From 354956f6382236000f2272da2e4a513d74dabcef Mon Sep 17 00:00:00 2001 From: parkourkarthik Date: Wed, 10 Oct 2018 08:38:30 +0530 Subject: [PATCH 001/290] include uri to open file cmd on clean tree --- extensions/git/src/commands.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 9c838715840..4dbc3784806 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -608,6 +608,9 @@ export class CommandCenter { uris = resources.map(r => r.resourceUri); } + else { + uris = [(window.activeTextEditor && window.activeTextEditor.document.uri)] as Uri[]; + } } if (!uris) { From 4228c786c45ccc4f403fac9e08574d47e67794a1 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Tue, 15 Jan 2019 19:58:07 -0600 Subject: [PATCH 002/290] git prompts to save only staged files --- extensions/git/src/commands.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index eb45f107f4b..26685a0afa3 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1200,19 +1200,21 @@ export class CommandCenter { const promptToSaveFilesBeforeCommit = config.get('promptToSaveFilesBeforeCommit') === true; if (promptToSaveFilesBeforeCommit) { - const unsavedTextDocuments = workspace.textDocuments - .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)); + const stagedUnsavedTextDocuments = workspace.textDocuments + .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)) + .filter(d => repository.indexGroup.resourceStates.some(s => + s.resourceUri.path === d.uri.fsPath)); - 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 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); + if (stagedUnsavedTextDocuments.length > 0) { + const message = stagedUnsavedTextDocuments.length === 1 + ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.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); if (pick === saveAndCommit) { - await Promise.all(unsavedTextDocuments.map(d => d.save())); + await Promise.all(stagedUnsavedTextDocuments.map(d => d.save())); await repository.status(); } else if (pick !== commit) { return false; // do not commit on cancel From e78b75e9452e026a6bc415911151aa365ce12c10 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Wed, 16 Jan 2019 00:18:15 -0600 Subject: [PATCH 003/290] update strings for prompt to save staged files --- 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 26685a0afa3..14a3e8b2cf8 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1207,8 +1207,8 @@ export class CommandCenter { if (stagedUnsavedTextDocuments.length > 0) { const message = stagedUnsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.length); + ? localize('unsaved files single', "The following staged file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved staged files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.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 dce56c504c08ab5e63fda05b793c581fac2a0851 Mon Sep 17 00:00:00 2001 From: Pawel Urbanski Date: Tue, 22 Jan 2019 19:43:58 +0100 Subject: [PATCH 004/290] Assigned an empty string to silence too verbose alerts, which try to handle function, much better handled by the screen readers, and therefore they should be removed. --- src/vs/editor/contrib/suggest/suggestController.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index 05e535ac302..9f9f2594ef0 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -292,7 +292,8 @@ export class SuggestController implements IEditorContribution { } private _alertCompletionItem({ completion: suggestion }: CompletionItem): void { - let msg = nls.localize('arai.alert.snippet', "Accepting '{0}' did insert the following text: {1}", suggestion.label, suggestion.insertText); + // @todo Remove alert support. Assigning an empty string temporarly to silence alers. + let msg = null; alert(msg); } From 700de5683e0072561cbc11d175c4f1533df934b3 Mon Sep 17 00:00:00 2001 From: Pawel Urbanski Date: Tue, 22 Jan 2019 21:11:40 +0100 Subject: [PATCH 005/290] Changed verbosity of code completion widget alerts to provide the current completion item without unnecesary snippet/regular hints, or if items have details. --- src/vs/editor/contrib/suggest/suggestWidget.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 347de4b6499..57c53a281bf 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -535,23 +535,25 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate { this.onDidSelectEmitter.fire({ item, index, model: completionModel }); - alert(nls.localize('suggestionAriaAccepted', "{0}, accepted", item.completion.label)); this.editor.focus(); }); } private _getSuggestionAriaAlertLabel(item: CompletionItem): string { + // It is not so important to know the type of completion: regular or snippet. + // Snippets can be identified by their names. + // They are usually created by users themselves. const isSnippet = item.completion.kind === CompletionItemKind.Snippet; if (!canExpandCompletionItem(item)) { - return isSnippet ? nls.localize('ariaCurrentSnippetSuggestion', "{0}, snippet suggestion", item.completion.label) - : nls.localize('ariaCurrentSuggestion', "{0}, suggestion", item.completion.label); + return isSnippet ? item.completion.label + : item.completion.label; } else if (this.expandDocsSettingFromStorage()) { - return isSnippet ? nls.localize('ariaCurrentSnippeSuggestionReadDetails', "{0}, snippet suggestion. Reading details. {1}", item.completion.label, this.details.getAriaLabel()) - : nls.localize('ariaCurrenttSuggestionReadDetails', "{0}, suggestion. Reading details. {1}", item.completion.label, this.details.getAriaLabel()); + return isSnippet ? nls.localize('ariaCurrentSnippeSuggestionReadDetails', "{0}: {1}", item.completion.label, this.details.getAriaLabel()) + : nls.localize('ariaCurrenttSuggestionReadDetails', "{0}: {1}", item.completion.label, this.details.getAriaLabel()); } else { - return isSnippet ? nls.localize('ariaCurrentSnippetSuggestionWithDetails', "{0}, snippet suggestion, has details", item.completion.label) - : nls.localize('ariaCurrentSuggestionWithDetails', "{0}, suggestion, has details", item.completion.label); + return isSnippet ? item.completion.label + : item.completion.label; } } From 12c69a6475e5ca4a7d4a8611b0cecbb387391679 Mon Sep 17 00:00:00 2001 From: Pawel Urbanski Date: Fri, 25 Jan 2019 17:11:00 +0100 Subject: [PATCH 006/290] Removed reporting the number of times alerted string appeared, which has no use for a blind user, and causes too much verbosity. --- src/vs/base/browser/ui/aria/aria.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/vs/base/browser/ui/aria/aria.ts b/src/vs/base/browser/ui/aria/aria.ts index 1922450144d..d7dad9cba5c 100644 --- a/src/vs/base/browser/ui/aria/aria.ts +++ b/src/vs/base/browser/ui/aria/aria.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./aria'; -import * as nls from 'vs/nls'; import { isMacintosh } from 'vs/base/common/platform'; import * as dom from 'vs/base/browser/dom'; @@ -48,29 +47,12 @@ 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++; - } - else { - prevText = msg; - repeatedTimes = 0; - } - - - 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); target.textContent = msg; From c3269a3966017a08077d3bbeee50905d416bffdd Mon Sep 17 00:00:00 2001 From: Pawel Urbanski Date: Fri, 25 Jan 2019 17:43:10 +0100 Subject: [PATCH 007/290] Changes to how documentation strings are presented. Includes previous fixes to alerts. --- src/vs/editor/contrib/suggest/suggestWidget.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 57c53a281bf..8de80617e8d 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -549,8 +549,8 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate Date: Mon, 28 Jan 2019 20:08:06 +0100 Subject: [PATCH 008/290] Fixes duplicating screen reader features with alert - needs further code refactoring. --- src/vs/editor/contrib/suggest/suggestController.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index 9f9f2594ef0..20f37c560e0 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { alert } from 'vs/base/browser/ui/aria/aria'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { onUnexpectedError } from 'vs/base/common/errors'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; @@ -292,9 +291,8 @@ export class SuggestController implements IEditorContribution { } private _alertCompletionItem({ completion: suggestion }: CompletionItem): void { - // @todo Remove alert support. Assigning an empty string temporarly to silence alers. - let msg = null; - alert(msg); + // A temporary fix for too verbose, unnecesary screen reader alerts. + // Todo: Remove calls to this empty method body. } triggerSuggest(onlyFrom?: CompletionItemProvider[]): void { From 552227eb5badb82c7a6d04f6c8eaae80743b96e4 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Tue, 29 Jan 2019 18:18:00 -0600 Subject: [PATCH 009/290] debugger console recognizes italic ansi code --- src/vs/workbench/parts/debug/browser/debugANSIHandling.ts | 4 +++- src/vs/workbench/parts/debug/browser/media/repl.css | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts b/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts index b373c452689..5fef576530f 100644 --- a/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts +++ b/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts @@ -56,7 +56,7 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML * Certain ranges that are matched here do not contain real graphics rendition sequences. For * the sake of having a simpler expression, they have been included anyway. */ - if (ansiSequence.match(/^(?:[349][0-7]|10[0-7]|[01]|4|[34]9)(?:;(?:[349][0-7]|10[0-7]|[01]|4|[34]9))*;?m$/)) { + if (ansiSequence.match(/^(?:[349][0-7]|10[0-7]|[013]|4|[34]9)(?:;(?:[349][0-7]|10[0-7]|[01]|4|[34]9))*;?m$/)) { const styleCodes: number[] = ansiSequence.slice(0, -1) // Remove final 'm' character. .split(';') // Separate style codes. @@ -68,6 +68,8 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML styleNames = []; } else if (code === 1) { styleNames.push('code-bold'); + } else if (code === 3) { + styleNames.push('code-italic'); } else if (code === 4) { styleNames.push('code-underline'); } else if ((code >= 30 && code <= 37) || (code >= 90 && code <= 97)) { diff --git a/src/vs/workbench/parts/debug/browser/media/repl.css b/src/vs/workbench/parts/debug/browser/media/repl.css index 9662f5852ee..b79c318a213 100644 --- a/src/vs/workbench/parts/debug/browser/media/repl.css +++ b/src/vs/workbench/parts/debug/browser/media/repl.css @@ -151,6 +151,7 @@ /* ANSI Codes */ .monaco-workbench .repl .repl-tree .output.expression .code-bold { font-weight: bold; } +.monaco-workbench .repl .repl-tree .output.expression .code-italic { font-style: italic; } .monaco-workbench .repl .repl-tree .output.expression .code-underline { text-decoration: underline; } /* Regular and bright color codes are currently treated the same. */ From 351cffa181cd0553c238ac1b02d75a39b9da330a Mon Sep 17 00:00:00 2001 From: Phil <35127144+flurmbo@users.noreply.github.com> Date: Tue, 29 Jan 2019 18:26:57 -0600 Subject: [PATCH 010/290] add '3' to second half of regex --- src/vs/workbench/parts/debug/browser/debugANSIHandling.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts b/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts index 5fef576530f..a177fc39161 100644 --- a/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts +++ b/src/vs/workbench/parts/debug/browser/debugANSIHandling.ts @@ -56,7 +56,7 @@ export function handleANSIOutput(text: string, linkDetector: LinkDetector): HTML * Certain ranges that are matched here do not contain real graphics rendition sequences. For * the sake of having a simpler expression, they have been included anyway. */ - if (ansiSequence.match(/^(?:[349][0-7]|10[0-7]|[013]|4|[34]9)(?:;(?:[349][0-7]|10[0-7]|[01]|4|[34]9))*;?m$/)) { + if (ansiSequence.match(/^(?:[349][0-7]|10[0-7]|[013]|4|[34]9)(?:;(?:[349][0-7]|10[0-7]|[013]|4|[34]9))*;?m$/)) { const styleCodes: number[] = ansiSequence.slice(0, -1) // Remove final 'm' character. .split(';') // Separate style codes. From 9960d7babdb11c602f9a77ede2e18fa6d441cddd Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Wed, 6 Feb 2019 16:46:18 -0600 Subject: [PATCH 011/290] Revert "update strings for prompt to save staged files" This reverts commit e78b75e9452e026a6bc415911151aa365ce12c10. --- 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 14a3e8b2cf8..26685a0afa3 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1207,8 +1207,8 @@ export class CommandCenter { if (stagedUnsavedTextDocuments.length > 0) { const message = stagedUnsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following staged file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved staged files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.length); + ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) + : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.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 bec02409988e520eb13d9cfd648245eee32fbb31 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Wed, 6 Feb 2019 16:46:25 -0600 Subject: [PATCH 012/290] Revert "git prompts to save only staged files" This reverts commit 4228c786c45ccc4f403fac9e08574d47e67794a1. --- extensions/git/src/commands.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 26685a0afa3..eb45f107f4b 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1200,21 +1200,19 @@ export class CommandCenter { const promptToSaveFilesBeforeCommit = config.get('promptToSaveFilesBeforeCommit') === true; if (promptToSaveFilesBeforeCommit) { - const stagedUnsavedTextDocuments = workspace.textDocuments - .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)) - .filter(d => repository.indexGroup.resourceStates.some(s => - s.resourceUri.path === d.uri.fsPath)); + const unsavedTextDocuments = workspace.textDocuments + .filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath)); - if (stagedUnsavedTextDocuments.length > 0) { - const message = stagedUnsavedTextDocuments.length === 1 - ? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(stagedUnsavedTextDocuments[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", stagedUnsavedTextDocuments.length); + 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 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); if (pick === saveAndCommit) { - await Promise.all(stagedUnsavedTextDocuments.map(d => d.save())); + await Promise.all(unsavedTextDocuments.map(d => d.save())); await repository.status(); } else if (pick !== commit) { return false; // do not commit on cancel From 26d5172258e36a756935e7e20634572343b59d6f Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Mon, 11 Feb 2019 23:46:08 -0500 Subject: [PATCH 013/290] Invalidate _messageTitleDisposable when disposed. Fixes #68287 --- .../contrib/terminal/electron-browser/terminalInstance.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index 0a38e48b7fd..3741120f02a 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -182,7 +182,7 @@ export class TerminalInstance implements ITerminalInstance { private _titleReadyComplete: (title: string) => any; private _disposables: lifecycle.IDisposable[]; - private _messageTitleDisposable: lifecycle.IDisposable; + private _messageTitleDisposable: lifecycle.IDisposable | undefined; private _widgetManager: TerminalWidgetManager; private _linkHandler: TerminalLinkHandler; @@ -1255,6 +1255,7 @@ export class TerminalInstance implements ITerminalInstance { // automatically updates the terminal name if (this._messageTitleDisposable) { lifecycle.dispose(this._messageTitleDisposable); + this._messageTitleDisposable = undefined; } } const didTitleChange = title !== this._title; From 20e6388e17198a63b4d91665da8d26f4fb94b570 Mon Sep 17 00:00:00 2001 From: Gunay Mert Karadogan Date: Wed, 13 Feb 2019 20:07:55 +0000 Subject: [PATCH 014/290] Add workspace name variable for snippets #68261 --- .../editor/contrib/snippet/snippetSession.ts | 7 +++- .../contrib/snippet/snippetVariables.ts | 29 ++++++++++++++ .../snippet/test/snippetVariables.test.ts | 38 ++++++++++++++++++- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index bf6c4909ac7..53cb0ed3c15 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -15,9 +15,10 @@ 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 { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { optional } from 'vs/platform/instantiation/common/instantiation'; import { Choice, Placeholder, SnippetParser, Text, TextmateSnippet } from './snippetParser'; -import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver, CommentBasedVariableResolver } from './snippetVariables'; +import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver, CommentBasedVariableResolver, WorkspaceBasedVariableResolver } from './snippetVariables'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import * as colors from 'vs/platform/theme/common/colorRegistry'; @@ -354,6 +355,7 @@ export class SnippetSession { const modelBasedVariableResolver = new ModelBasedVariableResolver(model); const clipboardService = editor.invokeWithinContext(accessor => accessor.get(IClipboardService, optional)); + const workspaceService = editor.invokeWithinContext(accessor => accessor.get(IWorkspaceContextService, optional)); let delta = 0; @@ -409,7 +411,8 @@ export class SnippetSession { new ClipboardBasedVariableResolver(clipboardService, idx, indexedSelections.length), new SelectionBasedVariableResolver(model, selection), new CommentBasedVariableResolver(model), - new TimeBasedVariableResolver + new TimeBasedVariableResolver, + new WorkspaceBasedVariableResolver(workspaceService), ])); const offset = model.getOffsetAt(start) + delta; diff --git a/src/vs/editor/contrib/snippet/snippetVariables.ts b/src/vs/editor/contrib/snippet/snippetVariables.ts index dd7591c79ab..d7307c5a043 100644 --- a/src/vs/editor/contrib/snippet/snippetVariables.ts +++ b/src/vs/editor/contrib/snippet/snippetVariables.ts @@ -11,6 +11,8 @@ import { VariableResolver, Variable, Text } from 'vs/editor/contrib/snippet/snip import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { getLeadingWhitespace, commonPrefixLength, isFalsyOrWhitespace, pad } from 'vs/base/common/strings'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { isSingleFolderWorkspaceIdentifier, toWorkspaceIdentifier, WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; export const KnownSnippetVariableNames = Object.freeze({ 'CURRENT_YEAR': true, @@ -38,6 +40,7 @@ export const KnownSnippetVariableNames = Object.freeze({ 'BLOCK_COMMENT_START': true, 'BLOCK_COMMENT_END': true, 'LINE_COMMENT': true, + 'WORKSPACE_NAME': true, }); export class CompositeSnippetVariableResolver implements VariableResolver { @@ -244,3 +247,29 @@ export class TimeBasedVariableResolver implements VariableResolver { return undefined; } } + +export class WorkspaceBasedVariableResolver implements VariableResolver { + constructor( + private readonly _workspaceService: IWorkspaceContextService, + ) { + // + } + + resolve(variable: Variable): string | undefined { + if (variable.name !== 'WORKSPACE_NAME' || !this._workspaceService) { + return undefined; + } + + const workspaceIdentifier = toWorkspaceIdentifier(this._workspaceService.getWorkspace()); + if (!workspaceIdentifier) { + return undefined; + } + + if (isSingleFolderWorkspaceIdentifier(workspaceIdentifier)) { + return basename(workspaceIdentifier.path); + } + + const filename = basename(workspaceIdentifier.configPath.path); + return filename.substr(0, filename.length - WORKSPACE_EXTENSION.length - 1); + } +} \ No newline at end of file diff --git a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts index 4931b38dac7..57853e2b59f 100644 --- a/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetVariables.test.ts @@ -6,10 +6,11 @@ import * as assert from 'assert'; import { isWindows } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { Selection } from 'vs/editor/common/core/selection'; -import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver } from 'vs/editor/contrib/snippet/snippetVariables'; +import { SelectionBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, ClipboardBasedVariableResolver, TimeBasedVariableResolver, WorkspaceBasedVariableResolver } from 'vs/editor/contrib/snippet/snippetVariables'; import { SnippetParser, Variable, VariableResolver } from 'vs/editor/contrib/snippet/snippetParser'; import { TextModel } from 'vs/editor/common/model/textModel'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { Workspace, toWorkspaceFolders, IWorkspace, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; suite('Snippet Variables Resolver', function () { @@ -301,4 +302,37 @@ suite('Snippet Variables Resolver', function () { snippet.resolveVariables({ resolve() { return '11'; } }); assert.equal(snippet.toString(), 'It is not line 10'); }); -}); + + test('Add workspace name variable for snippets #68261', function () { + + let workspace: IWorkspace; + let resolver: VariableResolver; + const workspaceService = new class implements IWorkspaceContextService { + _serviceBrand: any; + _throw = () => { throw new Error(); }; + onDidChangeWorkbenchState = this._throw; + onDidChangeWorkspaceName = this._throw; + onDidChangeWorkspaceFolders = this._throw; + getCompleteWorkspace = this._throw; + getWorkspace(): IWorkspace { return workspace; } + getWorkbenchState = this._throw; + getWorkspaceFolder = this._throw; + isCurrentWorkspace = this._throw; + isInsideWorkspace = this._throw; + }; + + resolver = new WorkspaceBasedVariableResolver(workspaceService); + + // empty workspace + workspace = new Workspace(''); + assertVariableResolve(resolver, 'WORKSPACE_NAME', undefined); + + // single folder workspace without config + workspace = new Workspace('', toWorkspaceFolders([{ path: '/folderName' }])); + assertVariableResolve(resolver, 'WORKSPACE_NAME', 'folderName'); + + // workspace with config + workspace = new Workspace('', toWorkspaceFolders([{ path: 'folderName' }]), URI.file('testWorkspace.code-workspace')); + assertVariableResolve(resolver, 'WORKSPACE_NAME', 'testWorkspace'); + }); +}); \ No newline at end of file From 59b8b2eeb9dc9570cef66f2b8f51ecbce0b6d628 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 20 Feb 2019 06:13:03 -0800 Subject: [PATCH 015/290] Fix strict null checks in terminalPanel Part of #60565 --- src/tsconfig.strictNullChecks.json | 1 + .../editor/contrib/find/simpleFindWidget.ts | 3 +-- .../electron-browser/terminalPanel.ts | 20 +++++++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index c4d5bc85314..923edcb13bd 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -295,6 +295,7 @@ "./vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler.ts", + "./vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalCommandTracker.ts", diff --git a/src/vs/editor/contrib/find/simpleFindWidget.ts b/src/vs/editor/contrib/find/simpleFindWidget.ts index 9eb65759b17..3148a62b196 100644 --- a/src/vs/editor/contrib/find/simpleFindWidget.ts +++ b/src/vs/editor/contrib/find/simpleFindWidget.ts @@ -26,7 +26,7 @@ const NLS_CLOSE_BTN_LABEL = nls.localize('label.closeButton', "Close"); export abstract class SimpleFindWidget extends Widget { private _findInput: FindInput; - private _domNode?: HTMLElement; + private _domNode: HTMLElement; private _innerDomNode: HTMLElement; private _isVisible: boolean = false; private _focusTracker: dom.IFocusTracker; @@ -182,7 +182,6 @@ export abstract class SimpleFindWidget extends Widget { if (this._domNode && this._domNode.parentElement) { this._domNode.parentElement.removeChild(this._domNode); - this._domNode = undefined; } } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts index bfde146007b..b4e7019e896 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts @@ -165,7 +165,7 @@ export class TerminalPanel extends Panel { return this._contextMenuActions; } - public getActionItem(action: Action): IActionItem { + public getActionItem(action: Action): IActionItem | null { if (action.id === SwitchTerminalAction.ID) { return this._instantiationService.createInstance(SwitchTerminalActionItem, action); } @@ -182,7 +182,7 @@ export class TerminalPanel extends Panel { public focusFindWidget() { const activeInstance = this._terminalService.getActiveInstance(); - if (activeInstance && activeInstance.hasSelection() && (activeInstance.selection.indexOf('\n') === -1)) { + if (activeInstance && activeInstance.hasSelection() && activeInstance.selection!.indexOf('\n') === -1) { this._findWidget.reveal(activeInstance.selection); } else { this._findWidget.reveal(); @@ -195,7 +195,7 @@ export class TerminalPanel extends Panel { public showFindWidget() { const activeInstance = this._terminalService.getActiveInstance(); - if (activeInstance && activeInstance.hasSelection() && (activeInstance.selection.indexOf('\n') === -1)) { + if (activeInstance && activeInstance.hasSelection() && activeInstance.selection!.indexOf('\n') === -1) { this._findWidget.show(activeInstance.selection); } else { this._findWidget.show(); @@ -215,10 +215,16 @@ export class TerminalPanel extends Panel { if (event.which === 2 && platform.isLinux) { // Drop selection and focus terminal on Linux to enable middle button paste when click // occurs on the selection itself. - this._terminalService.getActiveInstance().focus(); + const terminal = this._terminalService.getActiveInstance(); + if (terminal) { + terminal.focus(); + } } else if (event.which === 3) { if (this._terminalService.configHelper.config.rightClickBehavior === 'copyPaste') { const terminal = this._terminalService.getActiveInstance(); + if (!terminal) { + return; + } if (terminal.hasSelection()) { terminal.copySelection(); terminal.clearSelection(); @@ -246,7 +252,7 @@ export class TerminalPanel extends Panel { if (event.which === 1) { const terminal = this._terminalService.getActiveInstance(); - if (terminal.hasSelection()) { + if (terminal && terminal.hasSelection()) { terminal.copySelection(); } } @@ -299,7 +305,9 @@ export class TerminalPanel extends Panel { } const terminal = this._terminalService.getActiveInstance(); - terminal.sendText(terminalEnvironment.preparePathForTerminal(path), false); + if (terminal) { + terminal.sendText(terminalEnvironment.preparePathForTerminal(path), false); + } } })); } From 6da6653f4f8345b23d9bddcdaebeb340b1d0a7f0 Mon Sep 17 00:00:00 2001 From: "mgquan@myseneca.ca" Date: Wed, 20 Feb 2019 15:46:28 -0500 Subject: [PATCH 016/290] fixed 62968 --- src/vs/editor/common/controller/cursorTypeOperations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/controller/cursorTypeOperations.ts b/src/vs/editor/common/controller/cursorTypeOperations.ts index 032d035e41e..c18d081379d 100644 --- a/src/vs/editor/common/controller/cursorTypeOperations.ts +++ b/src/vs/editor/common/controller/cursorTypeOperations.ts @@ -526,7 +526,7 @@ export class TypeOperations { const lineText = model.getLineContent(position.lineNumber); // Do not auto-close ' or " after a word character - if (chIsQuote && position.column > 1) { + if ((chIsQuote && position.column > 1) && autoCloseConfig !== 'always') { const wordSeparators = getMapForWordSeparators(config.wordSeparators); const characterBeforeCode = lineText.charCodeAt(position.column - 2); const characterBeforeType = wordSeparators.get(characterBeforeCode); From d0dbd6103a6074051f7f73c1d22088a0a6e8405c Mon Sep 17 00:00:00 2001 From: Trevor Florence Date: Fri, 22 Feb 2019 12:22:16 -0700 Subject: [PATCH 017/290] Make EditStack correctly report canUndo Currently, `canUndo()` will incorrectly return false in the case that `this.past.length` is `0` and `this.currentOpenStackElement` is populated. You can call `undo()` and it will do the right thing but there's no indication that you should be able to do it as `canUndo()` returns false. --- src/vs/editor/common/model/editStack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/model/editStack.ts b/src/vs/editor/common/model/editStack.ts index 39ecc249c01..b60b083c1b6 100644 --- a/src/vs/editor/common/model/editStack.ts +++ b/src/vs/editor/common/model/editStack.ts @@ -210,7 +210,7 @@ export class EditStack { } public canUndo(): boolean { - return (this.past.length > 0); + return (this.past.length > 0) || this.currentOpenStackElement !== null; } public redo(): IUndoRedoResult | null { From afabf659aecd231a64cf057bc74dd33e1893877c Mon Sep 17 00:00:00 2001 From: khaled4vokalz Date: Sat, 23 Feb 2019 09:11:50 +0600 Subject: [PATCH 018/290] Fixed TYPO --- src/vs/editor/contrib/dnd/dnd.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/dnd/dnd.ts b/src/vs/editor/contrib/dnd/dnd.ts index 3d028223cee..f1adcb78ecf 100644 --- a/src/vs/editor/contrib/dnd/dnd.ts +++ b/src/vs/editor/contrib/dnd/dnd.ts @@ -38,7 +38,7 @@ export class DragAndDropController implements editorCommon.IEditorContribution { private _dragSelection: Selection; private _dndDecorationIds: string[]; private _mouseDown: boolean; - private _modiferPressed: boolean; + private _modifierPressed: boolean; static TRIGGER_KEY_VALUE = isMacintosh ? KeyCode.Alt : KeyCode.Ctrl; static get(editor: ICodeEditor): DragAndDropController { @@ -56,7 +56,7 @@ export class DragAndDropController implements editorCommon.IEditorContribution { this._toUnhook.push(this._editor.onKeyUp((e: IKeyboardEvent) => this.onEditorKeyUp(e))); this._dndDecorationIds = []; this._mouseDown = false; - this._modiferPressed = false; + this._modifierPressed = false; this._dragSelection = null; } @@ -66,7 +66,7 @@ export class DragAndDropController implements editorCommon.IEditorContribution { } if (hasTriggerModifier(e)) { - this._modiferPressed = true; + this._modifierPressed = true; } if (this._mouseDown && hasTriggerModifier(e)) { @@ -82,7 +82,7 @@ export class DragAndDropController implements editorCommon.IEditorContribution { } if (hasTriggerModifier(e)) { - this._modiferPressed = false; + this._modifierPressed = false; } if (this._mouseDown && e.keyCode === DragAndDropController.TRIGGER_KEY_VALUE) { @@ -156,13 +156,13 @@ export class DragAndDropController implements editorCommon.IEditorContribution { ( ( hasTriggerModifier(mouseEvent.event) || - this._modiferPressed + this._modifierPressed ) && ( this._dragSelection.getEndPosition().equals(newCursorPosition) || this._dragSelection.getStartPosition().equals(newCursorPosition) ) // we allow users to paste content beside the selection )) { this._editor.pushUndoStop(); - this._editor.executeCommand(DragAndDropController.ID, new DragAndDropCommand(this._dragSelection, newCursorPosition, hasTriggerModifier(mouseEvent.event) || this._modiferPressed)); + this._editor.executeCommand(DragAndDropController.ID, new DragAndDropCommand(this._dragSelection, newCursorPosition, hasTriggerModifier(mouseEvent.event) || this._modifierPressed)); this._editor.pushUndoStop(); } } @@ -213,7 +213,7 @@ export class DragAndDropController implements editorCommon.IEditorContribution { this._removeDecoration(); this._dragSelection = null; this._mouseDown = false; - this._modiferPressed = false; + this._modifierPressed = false; this._toUnhook = dispose(this._toUnhook); } } From 55cb25ecbdac60695230eba27f0f5d48738dba70 Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Mon, 25 Feb 2019 23:01:52 -0600 Subject: [PATCH 019/290] added tests for debugger itliac ANSI code --- .../test/browser/debugANSIHandling.test.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts index e42257fb540..f439453c3b2 100644 --- a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts @@ -92,6 +92,11 @@ suite('Debug - ANSI Handling', () => { assert(dom.hasClass(child, 'code-bold')); }); + // Italic code + assertSingleSequenceElement('\x1b[3m', (child) => { + assert(dom.hasClass(child, 'code-italic')); + }); + // Underline code assertSingleSequenceElement('\x1b[4m', (child) => { assert(dom.hasClass(child, 'code-underline')); @@ -126,10 +131,11 @@ suite('Debug - ANSI Handling', () => { } // Codes do not interfere - assertSingleSequenceElement('\x1b[1;4;30;31;32;33;34;35;36;37m', (child) => { + assertSingleSequenceElement('\x1b[1;3;4;30;31;32;33;34;35;36;37m', (child) => { assert.equal(10, child.classList.length); assert(dom.hasClass(child, 'code-bold')); + assert(dom.hasClass(child, 'code-italic')); assert(dom.hasClass(child, 'code-underline')); for (let i = 30; i <= 37; i++) { assert(dom.hasClass(child, 'code-foreground-' + i)); @@ -178,14 +184,15 @@ suite('Debug - ANSI Handling', () => { test('Expected multiple sequence operation', () => { // Multiple codes affect the same text - assertSingleSequenceElement('\x1b[1m\x1b[4m\x1b[32m', (child) => { + assertSingleSequenceElement('\x1b[1m\x1b[3m\x1b[4m\x1b[32m', (child) => { assert(dom.hasClass(child, 'code-bold')); + assert(dom.hasClass(child, 'code-italic')); assert(dom.hasClass(child, 'code-underline')); assert(dom.hasClass(child, 'code-foreground-32')); }); // Consecutive codes do not affect previous ones - assertMultipleSequenceElements('\x1b[1mbold\x1b[32mgreen\x1b[4munderline\x1b[0mnothing', [ + assertMultipleSequenceElements('\x1b[1mbold\x1b[32mgreen\x1b[4munderline\x1b[3mitalic\x1b[0mnothing', [ (bold) => { assert.equal(1, bold.classList.length); assert(dom.hasClass(bold, 'code-bold')); @@ -201,6 +208,13 @@ suite('Debug - ANSI Handling', () => { assert(dom.hasClass(underline, 'code-foreground-32')); assert(dom.hasClass(underline, 'code-underline')); }, + (italic) => { + assert.equal(4, italic.classList.length); + assert(dom.hasClass(italic, 'code-bold')); + assert(dom.hasClass(italic, 'code-foreground-32')); + assert(dom.hasClass(italic, 'code-underline')); + assert(dom.hasClass(italic, 'code-italic')); + }, (nothing) => { assert.equal(0, nothing.classList.length); }, From 06095789080e0cd642f08483e9e05a9d46306cfe Mon Sep 17 00:00:00 2001 From: Phil Marshall Date: Mon, 25 Feb 2019 23:41:41 -0600 Subject: [PATCH 020/290] fixed assertion for debugger italic ANSI code test --- .../contrib/debug/test/browser/debugANSIHandling.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts index f439453c3b2..4902d43a463 100644 --- a/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/debugANSIHandling.test.ts @@ -132,7 +132,7 @@ suite('Debug - ANSI Handling', () => { // Codes do not interfere assertSingleSequenceElement('\x1b[1;3;4;30;31;32;33;34;35;36;37m', (child) => { - assert.equal(10, child.classList.length); + assert.equal(11, child.classList.length); assert(dom.hasClass(child, 'code-bold')); assert(dom.hasClass(child, 'code-italic')); From 3ab8447baeb336e18e973ec9d285545192f57f9c Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 27 Feb 2019 15:03:45 +0100 Subject: [PATCH 021/290] explorer: raw file events should refersh the whole tree fixes #68627 --- .../contrib/files/common/explorerService.ts | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 4db163ecab6..7c751844e89 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -266,72 +266,73 @@ export class ExplorerService implements IExplorerService { // be fired first over the other or not at all. setTimeout(() => { // Filter to the ones we care - e = this.filterToViewRelevantEvents(e); - const changedItems: ExplorerItem[] = []; + const shouldRefresh = () => { + e = this.filterToViewRelevantEvents(e); + // Handle added files/folders + const added = e.getAdded(); + if (added.length) { - // Handle added files/folders - const added = e.getAdded(); - if (added.length) { + // Check added: Refresh if added file/folder is not part of resolved root and parent is part of it + const ignoredPaths: { [resource: string]: boolean } = <{ [resource: string]: boolean }>{}; + for (let i = 0; i < added.length; i++) { + const change = added[i]; - // Check added: Refresh if added file/folder is not part of resolved root and parent is part of it - const ignoredPaths: { [resource: string]: boolean } = <{ [resource: string]: boolean }>{}; - for (let i = 0; i < added.length; i++) { - const change = added[i]; + // Find parent + const parent = dirname(change.resource); - // Find parent - const parent = dirname(change.resource); + // Continue if parent was already determined as to be ignored + if (ignoredPaths[parent.toString()]) { + continue; + } - // Continue if parent was already determined as to be ignored - if (ignoredPaths[parent.toString()]) { - continue; - } + // Compute if parent is visible and added file not yet part of it + const parentStat = this.model.findClosest(parent); + if (parentStat && parentStat.isDirectoryResolved && !this.model.findClosest(change.resource)) { + return true; + } - // Compute if parent is visible and added file not yet part of it - const parentStat = this.model.findClosest(parent); - if (parentStat && parentStat.isDirectoryResolved && !this.model.findClosest(change.resource)) { - changedItems.push(parentStat); - } - - // Keep track of path that can be ignored for faster lookup - if (!parentStat || !parentStat.isDirectoryResolved) { - ignoredPaths[parent.toString()] = true; + // Keep track of path that can be ignored for faster lookup + if (!parentStat || !parentStat.isDirectoryResolved) { + ignoredPaths[parent.toString()] = true; + } } } - } - // Handle deleted files/folders - const deleted = e.getDeleted(); - if (deleted.length) { + // Handle deleted files/folders + const deleted = e.getDeleted(); + if (deleted.length) { - // Check deleted: Refresh if deleted file/folder part of resolved root - for (let j = 0; j < deleted.length; j++) { - const del = deleted[j]; - const item = this.model.findClosest(del.resource); - if (item && item.parent) { - changedItems.push(item.parent); + // Check deleted: Refresh if deleted file/folder part of resolved root + for (let j = 0; j < deleted.length; j++) { + const del = deleted[j]; + const item = this.model.findClosest(del.resource); + if (item && item.parent) { + return true; + } } } - } - // Handle updated files/folders if we sort by modified - if (this._sortOrder === SortOrderConfiguration.MODIFIED) { - const updated = e.getUpdated(); + // Handle updated files/folders if we sort by modified + if (this._sortOrder === SortOrderConfiguration.MODIFIED) { + const updated = e.getUpdated(); - // Check updated: Refresh if updated file/folder part of resolved root - for (let j = 0; j < updated.length; j++) { - const upd = updated[j]; - const item = this.model.findClosest(upd.resource); + // Check updated: Refresh if updated file/folder part of resolved root + for (let j = 0; j < updated.length; j++) { + const upd = updated[j]; + const item = this.model.findClosest(upd.resource); - if (item && item.parent) { - changedItems.push(item.parent); + if (item && item.parent) { + return true; + } } } - } - changedItems.forEach(item => { - item.forgetChildren(); - this._onDidChangeItem.fire(item); - }); + return false; + }; + + if (shouldRefresh()) { + this._onDidChangeItem.fire(undefined); + } }, ExplorerService.EXPLORER_FILE_CHANGES_REACT_DELAY); } From 9554d21148b5123db50627c9aa7532ffa75ddcfd Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 27 Feb 2019 15:06:50 +0100 Subject: [PATCH 022/290] fixes #69224 --- src/vs/base/browser/ui/list/list.ts | 4 ++-- src/vs/base/browser/ui/list/listPaging.ts | 6 +++--- src/vs/base/browser/ui/list/listView.ts | 10 ++++++++-- src/vs/base/browser/ui/list/listWidget.ts | 8 ++++---- src/vs/base/browser/ui/tree/abstractTree.ts | 21 ++++++++++++-------- src/vs/base/browser/ui/tree/asyncDataTree.ts | 8 ++++---- 6 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts index b4a4aa4821f..80dea11ee4a 100644 --- a/src/vs/base/browser/ui/list/list.ts +++ b/src/vs/base/browser/ui/list/list.ts @@ -16,8 +16,8 @@ export interface IListVirtualDelegate { export interface IListRenderer { templateId: string; renderTemplate(container: HTMLElement): TTemplateData; - renderElement(element: T, index: number, templateData: TTemplateData): void; - disposeElement?(element: T, index: number, templateData: TTemplateData): void; + renderElement(element: T, index: number, templateData: TTemplateData, dynamicHeightProbing?: boolean): void; + disposeElement?(element: T, index: number, templateData: TTemplateData, dynamicHeightProbing?: boolean): void; disposeTemplate(templateData: TTemplateData): void; } diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index c35537fa7ea..3d1fe415426 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -35,7 +35,7 @@ class PagedRenderer implements IListRenderer { } } }; } - renderElement(index: number, _: number, data: ITemplateData): void { + renderElement(index: number, _: number, data: ITemplateData, dynamicHeightProbing?: boolean): void { if (data.disposable) { data.disposable.dispose(); } @@ -47,7 +47,7 @@ class PagedRenderer implements IListRenderer implements IListRenderer cts.cancel() }; this.renderer.renderPlaceholder(index, data.data); - promise.then(entry => this.renderer.renderElement(entry, index, data.data!)); + promise.then(entry => this.renderer.renderElement(entry, index, data.data!, dynamicHeightProbing)); } disposeTemplate(data: ITemplateData): void { diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index f5ab01d4155..3bf44fc334b 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -1079,14 +1079,20 @@ export class ListView implements ISpliceable, IDisposable { } const size = item.size; - const renderer = this.renderers.get(item.templateId); const row = this.cache.alloc(item.templateId); row.domNode!.style.height = ''; this.rowsContainer.appendChild(row.domNode!); + + const renderer = this.renderers.get(item.templateId); if (renderer) { - renderer.renderElement(item.element, index, row.templateData); + renderer.renderElement(item.element, index, row.templateData, true); + + if (renderer.disposeElement) { + renderer.disposeElement(item.element, index, row.templateData, true); + } } + item.size = row.domNode!.offsetHeight; item.lastDynamicHeightWidth = this.renderWidth; this.rowsContainer.removeChild(row.domNode!); diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 8aa79431056..cd7312809c6 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -976,20 +976,20 @@ class PipelineRenderer implements IListRenderer { return this.renderers.map(r => r.renderTemplate(container)); } - renderElement(element: T, index: number, templateData: any[]): void { + renderElement(element: T, index: number, templateData: any[], dynamicHeightProbing?: boolean): void { let i = 0; for (const renderer of this.renderers) { - renderer.renderElement(element, index, templateData[i++]); + renderer.renderElement(element, index, templateData[i++], dynamicHeightProbing); } } - disposeElement(element: T, index: number, templateData: any[]): void { + disposeElement(element: T, index: number, templateData: any[], dynamicHeightProbing?: boolean): void { let i = 0; for (const renderer of this.renderers) { if (renderer.disposeElement) { - renderer.disposeElement(element, index, templateData[i]); + renderer.disposeElement(element, index, templateData[i], dynamicHeightProbing); } i += 1; diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 9edbb3174bb..22839784b16 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -233,23 +233,28 @@ class TreeRenderer implements IListRenderer, index: number, templateData: ITreeListTemplateData): void { - this.renderedNodes.set(node, templateData); - this.renderedElements.set(node.element, node); + renderElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData, dynamicHeightProbing?: boolean): void { + if (!dynamicHeightProbing) { + this.renderedNodes.set(node, templateData); + this.renderedElements.set(node.element, node); + } const indent = TreeRenderer.DefaultIndent + (node.depth - 1) * this.indent; templateData.twistie.style.marginLeft = `${indent}px`; this.update(node, templateData); - this.renderer.renderElement(node, index, templateData.templateData); + this.renderer.renderElement(node, index, templateData.templateData, dynamicHeightProbing); } - disposeElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData): void { + disposeElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData, dynamicHeightProbing?: boolean): void { if (this.renderer.disposeElement) { - this.renderer.disposeElement(node, index, templateData.templateData); + this.renderer.disposeElement(node, index, templateData.templateData, dynamicHeightProbing); + } + + if (!dynamicHeightProbing) { + this.renderedNodes.delete(node); + this.renderedElements.delete(node.element); } - this.renderedNodes.delete(node); - this.renderedElements.delete(node.element); } disposeTemplate(templateData: ITreeListTemplateData): void { diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index d8b97395fbf..fe397e7240f 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -87,8 +87,8 @@ class DataTreeRenderer implements ITreeRe return { templateData }; } - renderElement(node: ITreeNode, TFilterData>, index: number, templateData: IDataTreeListTemplateData): void { - this.renderer.renderElement(new AsyncDataTreeNodeWrapper(node), index, templateData.templateData); + renderElement(node: ITreeNode, TFilterData>, index: number, templateData: IDataTreeListTemplateData, dynamicHeightProbing?: boolean): void { + this.renderer.renderElement(new AsyncDataTreeNodeWrapper(node), index, templateData.templateData, dynamicHeightProbing); } renderTwistie(element: IAsyncDataTreeNode, twistieElement: HTMLElement): boolean { @@ -96,9 +96,9 @@ class DataTreeRenderer implements ITreeRe return false; } - disposeElement(node: ITreeNode, TFilterData>, index: number, templateData: IDataTreeListTemplateData): void { + disposeElement(node: ITreeNode, TFilterData>, index: number, templateData: IDataTreeListTemplateData, dynamicHeightProbing?: boolean): void { if (this.renderer.disposeElement) { - this.renderer.disposeElement(new AsyncDataTreeNodeWrapper(node), index, templateData.templateData); + this.renderer.disposeElement(new AsyncDataTreeNodeWrapper(node), index, templateData.templateData, dynamicHeightProbing); } } From 3bf1e49c76da3ea190eb8a1c9a3b90741e461990 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 27 Feb 2019 15:12:25 +0100 Subject: [PATCH 023/290] explorer: real refesh on file changes --- src/vs/workbench/contrib/files/common/explorerService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 7c751844e89..980c9b14035 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -331,6 +331,7 @@ export class ExplorerService implements IExplorerService { }; if (shouldRefresh()) { + this.roots.forEach(r => r.forgetChildren()); this._onDidChangeItem.fire(undefined); } }, ExplorerService.EXPLORER_FILE_CHANGES_REACT_DELAY); From 2c6d4ad1da3f80f52971ea712cd54e0444bf1d3b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 27 Feb 2019 15:17:10 +0100 Subject: [PATCH 024/290] Fixes #10339: Fix invocations of formatter to pass indentSize --- src/vs/editor/common/model.ts | 8 +++- src/vs/editor/common/model/textModel.ts | 9 +++- src/vs/editor/contrib/format/formatActions.ts | 46 ++++++++----------- .../mainThreadSaveParticipant.ts | 3 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index fa9125ff8f8..aa4796c306c 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -12,7 +12,7 @@ import { IRange, Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { IModelContentChange, IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent, ModelRawContentChangedEvent } from 'vs/editor/common/model/textModelEvents'; import { SearchData } from 'vs/editor/common/model/textModelSearch'; -import { LanguageId, LanguageIdentifier } from 'vs/editor/common/modes'; +import { LanguageId, LanguageIdentifier, FormattingOptions } from 'vs/editor/common/modes'; import { ITextSnapshot } from 'vs/platform/files/common/files'; import { ThemeColor } from 'vs/platform/theme/common/themeService'; @@ -500,6 +500,12 @@ export interface ITextModel { */ getOptions(): TextModelResolvedOptions; + /** + * Get the formatting options for this model. + * @internal + */ + getFormattingOptions(): FormattingOptions; + /** * Get the current version id of the model. * Anytime a change happens to the model (even undo/redo), diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 7f9d8351b14..1b67ebef2c8 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -25,7 +25,7 @@ import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguag import { SearchData, SearchParams, TextModelSearch } from 'vs/editor/common/model/textModelSearch'; import { ModelLinesTokens, ModelTokensChangedEventBuilder } from 'vs/editor/common/model/textModelTokens'; import { getWordAtText } from 'vs/editor/common/model/wordHelper'; -import { IState, LanguageId, LanguageIdentifier, TokenizationRegistry } from 'vs/editor/common/modes'; +import { IState, LanguageId, LanguageIdentifier, TokenizationRegistry, FormattingOptions } from 'vs/editor/common/modes'; import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry'; import { NULL_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/nullMode'; import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports'; @@ -590,6 +590,13 @@ export class TextModel extends Disposable implements model.ITextModel { return this._options; } + public getFormattingOptions(): FormattingOptions { + return { + tabSize: this._options.indentSize, + insertSpaces: this._options.insertSpaces + }; + } + public updateOptions(_newOpts: model.ITextModelUpdateOptions): void { this._assertNotDisposed(); let tabSize = (typeof _newOpts.tabSize !== 'undefined') ? _newOpts.tabSize : this._options.tabSize; diff --git a/src/vs/editor/contrib/format/formatActions.ts b/src/vs/editor/contrib/format/formatActions.ts index ffc30fdd8a9..06fd88eab28 100644 --- a/src/vs/editor/contrib/format/formatActions.ts +++ b/src/vs/editor/contrib/format/formatActions.ts @@ -213,34 +213,30 @@ class FormatOnType implements editorCommon.IEditorContribution { }); - let modelOpts = model.getOptions(); - getOnTypeFormattingEdits( this._telemetryService, this._workerService, model, position, ch, - { - tabSize: modelOpts.tabSize, - insertSpaces: modelOpts.insertSpaces - }).then(edits => { + model.getFormattingOptions() + ).then(edits => { - unbind.dispose(); + unbind.dispose(); - if (canceled) { - return; - } + if (canceled) { + return; + } - if (isNonEmptyArray(edits)) { - FormattingEdit.execute(this._editor, edits); - alertFormattingEdits(edits); - } + if (isNonEmptyArray(edits)) { + FormattingEdit.execute(this._editor, edits); + alertFormattingEdits(edits); + } - }, (err) => { - unbind.dispose(); - throw err; - }); + }, (err) => { + unbind.dispose(); + throw err; + }); } public getId(): string { @@ -311,8 +307,7 @@ class FormatOnPaste implements editorCommon.IEditorContribution { } const model = this.editor.getModel(); - const { tabSize, insertSpaces } = model.getOptions(); - formatDocumentRange(this.telemetryService, this.workerService, this.editor, range, { tabSize, insertSpaces }, CancellationToken.None); + formatDocumentRange(this.telemetryService, this.workerService, this.editor, range, model.getFormattingOptions(), CancellationToken.None); } public getId(): string { @@ -354,8 +349,7 @@ export class FormatDocumentAction extends EditorAction { } const workerService = accessor.get(IEditorWorkerService); const telemetryService = accessor.get(ITelemetryService); - const { tabSize, insertSpaces } = editor.getModel().getOptions(); - return formatDocument(telemetryService, workerService, editor, { tabSize, insertSpaces }, CancellationToken.None); + return formatDocument(telemetryService, workerService, editor, editor.getModel().getFormattingOptions(), CancellationToken.None); } } @@ -386,8 +380,7 @@ export class FormatSelectionAction extends EditorAction { } const workerService = accessor.get(IEditorWorkerService); const telemetryService = accessor.get(ITelemetryService); - const { tabSize, insertSpaces } = editor.getModel().getOptions(); - return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, { tabSize, insertSpaces }, CancellationToken.None); + return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, editor.getModel().getFormattingOptions(), CancellationToken.None); } } @@ -403,13 +396,12 @@ CommandsRegistry.registerCommand('editor.action.format', accessor => { if (!editor || !editor.hasModel()) { return undefined; } - const { tabSize, insertSpaces } = editor.getModel().getOptions(); const workerService = accessor.get(IEditorWorkerService); const telemetryService = accessor.get(ITelemetryService); if (editor.getSelection().isEmpty()) { - return formatDocument(telemetryService, workerService, editor, { tabSize, insertSpaces }, CancellationToken.None); + return formatDocument(telemetryService, workerService, editor, editor.getModel().getFormattingOptions(), CancellationToken.None); } else { - return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, { tabSize, insertSpaces }, CancellationToken.None); + return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, editor.getModel().getFormattingOptions(), CancellationToken.None); } }); diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index eb965620574..2c4068005f8 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -231,13 +231,12 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { } const versionNow = model.getVersionId(); - const { tabSize, insertSpaces } = model.getOptions(); const timeout = this._configurationService.getValue('editor.formatOnSaveTimeout', { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() }); return new Promise((resolve, reject) => { let source = new CancellationTokenSource(); - let request = getDocumentFormattingEdits(this._telemetryService, this._editorWorkerService, model, { tabSize, insertSpaces }, FormatMode.Auto, source.token); + let request = getDocumentFormattingEdits(this._telemetryService, this._editorWorkerService, model, model.getFormattingOptions(), FormatMode.Auto, source.token); setTimeout(() => { reject(localize('timeout.formatOnSave', "Aborted format on save after {0}ms", timeout)); From 60ebcd164b9049d2639fca235edfe9198374a1b5 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 27 Feb 2019 16:54:53 +0100 Subject: [PATCH 025/290] duplicate workspace forgets window authority --- src/vs/code/electron-main/windows.ts | 2 +- .../platform/workspaces/common/workspaces.ts | 3 ++- .../electron-main/workspacesMainService.ts | 20 +++++++++---------- .../platform/workspaces/node/workspacesIpc.ts | 9 +++++---- .../workspacesMainService.test.ts | 4 +++- .../browser/actions/workspaceActions.ts | 3 ++- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index 59bfccd1142..8f012a9315c 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -1075,7 +1075,7 @@ export class WindowsManager implements IWindowsMainService { if (!options.forceOpenWorkspaceAsFile) { const workspace = this.workspacesMainService.resolveLocalWorkspaceSync(URI.file(candidate)); if (workspace) { - return { workspace: { id: workspace.id, configPath: workspace.configPath }, remoteAuthority }; + return { workspace: { id: workspace.id, configPath: workspace.configPath }, remoteAuthority: workspace.remoteAuthority }; } } diff --git a/src/vs/platform/workspaces/common/workspaces.ts b/src/vs/platform/workspaces/common/workspaces.ts index dab9dd39404..890e9f55f13 100644 --- a/src/vs/platform/workspaces/common/workspaces.ts +++ b/src/vs/platform/workspaces/common/workspaces.ts @@ -70,6 +70,7 @@ export type IStoredWorkspaceFolder = IRawFileWorkspaceFolder | IRawUriWorkspaceF export interface IResolvedWorkspace extends IWorkspaceIdentifier { folders: IWorkspaceFolder[]; + remoteAuthority?: string; } export interface IStoredWorkspace { @@ -114,7 +115,7 @@ export interface IWorkspacesMainService extends IWorkspacesService { export interface IWorkspacesService { _serviceBrand: any; - createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[]): Promise; + createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise; } export function isSingleFolderWorkspaceIdentifier(obj: any): obj is ISingleFolderWorkspaceIdentifier { diff --git a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts index d61031e0e9d..70bb98c8626 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesMainService.ts @@ -20,10 +20,10 @@ import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { Disposable } from 'vs/base/common/lifecycle'; import { originalFSPath, dirname as resourcesDirname, isEqualOrParent, joinPath } from 'vs/base/common/resources'; -import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; export interface IStoredWorkspace { folders: IStoredWorkspaceFolder[]; + remoteAuthority?: string; } export class WorkspacesMainService extends Disposable implements IWorkspacesMainService { @@ -73,7 +73,8 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain return { id: workspaceIdentifier.id, configPath: workspaceIdentifier.configPath, - folders: toWorkspaceFolders(workspace.folders, resourcesDirname(path)) + folders: toWorkspaceFolders(workspace.folders, resourcesDirname(path)), + remoteAuthority: workspace.remoteAuthority }; } catch (error) { this.logService.warn(error.toString()); @@ -104,8 +105,8 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain return isEqualOrParent(path, this.environmentService.untitledWorkspacesHome); } - createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[]): Promise { - const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders); + createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise { + const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders, remoteAuthority); const configPath = workspace.configPath.fsPath; return mkdirp(dirname(configPath)).then(() => { @@ -113,8 +114,8 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain }); } - createUntitledWorkspaceSync(folders?: IWorkspaceFolderCreationData[]): IWorkspaceIdentifier { - const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders); + createUntitledWorkspaceSync(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): IWorkspaceIdentifier { + const { workspace, storedWorkspace } = this.newUntitledWorkspace(folders, remoteAuthority); const configPath = workspace.configPath.fsPath; const configPathDir = dirname(configPath); @@ -131,7 +132,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain return workspace; } - private newUntitledWorkspace(folders: IWorkspaceFolderCreationData[] = []): { workspace: IWorkspaceIdentifier, storedWorkspace: IStoredWorkspace } { + private newUntitledWorkspace(folders: IWorkspaceFolderCreationData[] = [], remoteAuthority?: string): { workspace: IWorkspaceIdentifier, storedWorkspace: IStoredWorkspace } { const randomId = (Date.now() + Math.round(Math.random() * 1000)).toString(); const untitledWorkspaceConfigFolder = joinPath(this.untitledWorkspacesHome, randomId); const untitledWorkspaceConfigPath = joinPath(untitledWorkspaceConfigFolder, UNTITLED_WORKSPACE_NAME); @@ -144,7 +145,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain return { workspace: this.getWorkspaceIdentifier(untitledWorkspaceConfigPath), - storedWorkspace: { folders: storedWorkspaceFolder } + storedWorkspace: { folders: storedWorkspaceFolder, remoteAuthority } }; } @@ -230,8 +231,7 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain if (!resolvedWorkspace) { this.doDeleteUntitledWorkspaceSync(workspace); } else { - const remoteAuthority = resolvedWorkspace.folders.length ? getRemoteAuthority(resolvedWorkspace.folders[0].uri) : undefined; - untitledWorkspaces.push({ workspace, remoteAuthority }); + untitledWorkspaces.push({ workspace, remoteAuthority: resolvedWorkspace.remoteAuthority }); } } } catch (error) { diff --git a/src/vs/platform/workspaces/node/workspacesIpc.ts b/src/vs/platform/workspaces/node/workspacesIpc.ts index 11ae4da17ec..59caecf0560 100644 --- a/src/vs/platform/workspaces/node/workspacesIpc.ts +++ b/src/vs/platform/workspaces/node/workspacesIpc.ts @@ -19,7 +19,8 @@ export class WorkspacesChannel implements IServerChannel { call(_, command: string, arg?: any): Promise { switch (command) { case 'createUntitledWorkspace': { - const rawFolders: IWorkspaceFolderCreationData[] = arg; + const rawFolders: IWorkspaceFolderCreationData[] = arg[0]; + const remoteAuthority: string = arg[1]; let folders: IWorkspaceFolderCreationData[] | undefined = undefined; if (Array.isArray(rawFolders)) { folders = rawFolders.map(rawFolder => { @@ -30,7 +31,7 @@ export class WorkspacesChannel implements IServerChannel { }); } - return this.service.createUntitledWorkspace(folders); + return this.service.createUntitledWorkspace(folders, remoteAuthority); } } @@ -44,7 +45,7 @@ export class WorkspacesChannelClient implements IWorkspacesService { constructor(private channel: IChannel) { } - createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[]): Promise { - return this.channel.call('createUntitledWorkspace', folders).then(reviveWorkspaceIdentifier); + createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise { + return this.channel.call('createUntitledWorkspace', [folders, remoteAuthority]).then(reviveWorkspaceIdentifier); } } 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 95a46d91ff0..31c50d16b58 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspacesMainService.test.ts @@ -114,7 +114,7 @@ suite('WorkspacesMainService', () => { const folder1URI = URI.parse('myscheme://server/work/p/f1'); const folder2URI = URI.parse('myscheme://server/work/o/f3'); - return service.createUntitledWorkspace([{ uri: folder1URI }, { uri: folder2URI }]).then(workspace => { + return service.createUntitledWorkspace([{ uri: folder1URI }, { uri: folder2URI }], 'server').then(workspace => { assert.ok(workspace); assert.ok(fs.existsSync(workspace.configPath.fsPath)); assert.ok(service.isUntitledWorkspace(workspace)); @@ -126,6 +126,8 @@ suite('WorkspacesMainService', () => { assert.ok(!(ws.folders[0]).name); assert.ok(!(ws.folders[1]).name); + + assert.equal(ws.remoteAuthority, 'server'); }); }); diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 4520821cde9..fdff577ff72 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -252,8 +252,9 @@ export class DuplicateWorkspaceInNewWindowAction extends Action { run(): Promise { const folders = this.workspaceContextService.getWorkspace().folders; + const remoteAuthority = this.windowService.getConfiguration().remoteAuthority; - return this.workspacesService.createUntitledWorkspace(folders).then(newWorkspace => { + return this.workspacesService.createUntitledWorkspace(folders, remoteAuthority).then(newWorkspace => { return this.workspaceEditingService.copyWorkspaceSettings(newWorkspace).then(() => { return this.windowService.openWindow([{ uri: newWorkspace.configPath, typeHint: 'file' }], { forceNewWindow: true }); }); From e2049cdca315d4e0a5ffa4d7ec41200e42297640 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 27 Feb 2019 17:24:18 +0100 Subject: [PATCH 026/290] Remove public facing usages of indentSize (#10339) --- .../common/config/commonEditorConfig.ts | 28 +++++++++---------- src/vs/editor/common/model.ts | 2 +- src/vs/vscode.d.ts | 11 +------- .../workbench/api/node/extHostTextEditor.ts | 24 ++++++++-------- 4 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 0146d8c3148..fa004fba308 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -289,20 +289,20 @@ const editorConfiguration: IConfigurationNode = { 'minimum': 1, '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.") }, - 'editor.indentSize': { - 'anyOf': [ - { - 'type': 'string', - 'enum': ['tabSize'] - }, - { - 'type': 'number', - 'minimum': 1 - } - ], - 'default': 'tabSize', - 'markdownDescription': nls.localize('indentSize', "The number of spaces used for indentation or 'tabSize' to use the value from `#editor.tabSize#`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on.") - }, + // 'editor.indentSize': { + // 'anyOf': [ + // { + // 'type': 'string', + // 'enum': ['tabSize'] + // }, + // { + // 'type': 'number', + // 'minimum': 1 + // } + // ], + // 'default': 'tabSize', + // 'markdownDescription': nls.localize('indentSize', "The number of spaces used for indentation or 'tabSize' to use the value from `#editor.tabSize#`. This setting is overridden based on the file contents when `#editor.detectIndentation#` is on.") + // }, 'editor.insertSpaces': { 'type': 'boolean', 'default': EDITOR_MODEL_DEFAULTS.insertSpaces, diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index aa4796c306c..a15dd004bef 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -362,7 +362,7 @@ export class TextModelResolvedOptions { trimAutoWhitespace: boolean; }) { this.tabSize = src.tabSize | 0; - this.indentSize = src.indentSize | 0; + this.indentSize = src.tabSize | 0; this.insertSpaces = Boolean(src.insertSpaces); this.defaultEOL = src.defaultEOL | 0; this.trimAutoWhitespace = Boolean(src.trimAutoWhitespace); diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index a00d67ec56b..b2ac03e4fcd 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -641,22 +641,13 @@ declare module 'vscode' { /** * The size in spaces a tab takes. This is used for two purposes: * - the rendering width of a tab character; - * - the number of spaces to insert when [insertSpaces](#TextEditorOptions.insertSpaces) is true - * and `indentSize` is set to `"tab"`. + * - the number of spaces to insert when [insertSpaces](#TextEditorOptions.insertSpaces) is true. * * When getting a text editor's options, this property will always be a number (resolved). * When setting a text editor's options, this property is optional and it can be a number or `"auto"`. */ tabSize?: number | string; - /** - * The number of spaces to insert when [insertSpaces](#TextEditorOptions.insertSpaces) is true. - * - * When getting a text editor's options, this property will always be a number (resolved). - * When setting a text editor's options, this property is optional and it can be a number or `"tabSize"`. - */ - indentSize?: number | string; - /** * When pressing Tab insert [n](#TextEditorOptions.tabSize) spaces. * When getting a text editor's options, this property will always be a boolean (resolved). diff --git a/src/vs/workbench/api/node/extHostTextEditor.ts b/src/vs/workbench/api/node/extHostTextEditor.ts index 67ddc6361cd..3cb2231f1b8 100644 --- a/src/vs/workbench/api/node/extHostTextEditor.ts +++ b/src/vs/workbench/api/node/extHostTextEditor.ts @@ -316,18 +316,18 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { } } - if (typeof newOptions.indentSize !== 'undefined') { - let indentSize = this._validateIndentSize(newOptions.indentSize); - if (indentSize === 'tabSize') { - hasUpdate = true; - bulkConfigurationUpdate.indentSize = indentSize; - } else if (typeof indentSize === 'number' && this._indentSize !== indentSize) { - // reflect the new indentSize value immediately - this._indentSize = indentSize; - hasUpdate = true; - bulkConfigurationUpdate.indentSize = indentSize; - } - } + // if (typeof newOptions.indentSize !== 'undefined') { + // let indentSize = this._validateIndentSize(newOptions.indentSize); + // if (indentSize === 'tabSize') { + // hasUpdate = true; + // bulkConfigurationUpdate.indentSize = indentSize; + // } else if (typeof indentSize === 'number' && this._indentSize !== indentSize) { + // // reflect the new indentSize value immediately + // this._indentSize = indentSize; + // hasUpdate = true; + // bulkConfigurationUpdate.indentSize = indentSize; + // } + // } if (typeof newOptions.insertSpaces !== 'undefined') { let insertSpaces = this._validateInsertSpaces(newOptions.insertSpaces); From 0acb390180df4cdc47ed63428b244a9575127832 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 27 Feb 2019 09:52:01 -0800 Subject: [PATCH 027/290] Fix #69114 --- .../electron-browser/preferencesSearch.ts | 23 +++++++++++-------- .../preferences/common/preferences.ts | 2 -- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts index 42948953bfa..4edd06ce8e7 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts @@ -260,20 +260,25 @@ class RemoteSearchProvider implements ISearchProvider { } const requestType = details.body ? 'post' : 'get'; + const headers = { + 'User-Agent': 'request', + 'Content-Type': 'application/json; charset=utf-8', + }; + + if (this.options.endpoint.key) { + headers['api-key'] = this.options.endpoint.key; + } + const start = Date.now(); return this.requestService.request({ type: requestType, url: details.url, data: details.body, - headers: { - 'User-Agent': 'request', - 'Content-Type': 'application/json; charset=utf-8', - 'api-key': this.options.endpoint.key - }, + headers, timeout: 5000 }, CancellationToken.None).then(context => { if (context.res.statusCode >= 300) { - throw new Error(`${details} returned status code: ${context.res.statusCode}`); + throw new Error(`${JSON.stringify(details)} returned status code: ${context.res.statusCode}`); } return asJson(context); @@ -319,8 +324,7 @@ class RemoteSearchProvider implements ISearchProvider { duration, timestamp, scoredResults, - context: result['@odata.context'], - extensions: details.extensions + context: result['@odata.context'] }; }); } @@ -374,8 +378,7 @@ class RemoteSearchProvider implements ISearchProvider { return { url, body, - hasMoreFilters, - extensions + hasMoreFilters }; } diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index c69cfc9d412..4bf2e5500f5 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -12,7 +12,6 @@ import { localize } from 'vs/nls'; import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; -import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { EditorOptions, IEditor } from 'vs/workbench/common/editor'; @@ -123,7 +122,6 @@ export interface IFilterMetadata { timestamp: number; duration: number; scoredResults: IScoredResults; - extensions?: ILocalExtension[]; /** The number of requests made, since requests are split by number of filters */ requestCount?: number; From 460645a1f5d084a9cd3f42a98cc43beb63f18cc0 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 27 Feb 2019 11:16:39 -0800 Subject: [PATCH 028/290] fix russian mnemonics fixes #69515 fixes #62449 --- src/vs/base/browser/ui/menu/menu.ts | 18 +++++++++--------- src/vs/base/browser/ui/menu/menubar.ts | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index c2b6a7ea36d..47da5e42776 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -8,7 +8,7 @@ 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, KeyCodeUtils } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, KeyCode } from 'vs/base/common/keyCodes'; import { addClass, EventType, EventHelper, EventLike, removeTabIndexAndUpdateFocus, isAncestor, hasClass, addDisposableListener, removeClass, append, $, addClasses, removeClasses } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -20,8 +20,8 @@ import { Event, Emitter } from 'vs/base/common/event'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { isLinux } from 'vs/base/common/platform'; -export const MENU_MNEMONIC_REGEX: RegExp = /\(&(\w)\)|(?>; + private mnemonics: Map>; private menuDisposables: IDisposable[]; private scrollableElement: DomScrollableElement; private menuElement: HTMLElement; @@ -93,7 +93,7 @@ export class Menu extends ActionBar { if (options.enableMnemonics) { this.menuDisposables.push(addDisposableListener(menuElement, EventType.KEY_DOWN, (e) => { - const key = KeyCodeUtils.fromString(e.key); + const key = e.key.toLocaleLowerCase(); if (this.mnemonics.has(key)) { EventHelper.stop(e, true); const actions = this.mnemonics.get(key)!; @@ -175,7 +175,7 @@ export class Menu extends ActionBar { parent: this }; - this.mnemonics = new Map>(); + this.mnemonics = new Map>(); this.push(actions, { icon: true, label: true, isMenu: true }); @@ -349,7 +349,7 @@ class MenuActionItem extends BaseActionItem { private label: HTMLElement; private check: HTMLElement; - private mnemonic: KeyCode; + private mnemonic: string; private cssClass: string; protected menuStyle: IMenuStyles; @@ -368,7 +368,7 @@ class MenuActionItem extends BaseActionItem { if (label) { let matches = MENU_MNEMONIC_REGEX.exec(label); if (matches) { - this.mnemonic = KeyCodeUtils.fromString((!!matches[1] ? matches[1] : matches[2]).toLocaleLowerCase()); + this.mnemonic = (!!matches[1] ? matches[1] : matches[2]).toLocaleLowerCase(); } } } @@ -522,7 +522,7 @@ class MenuActionItem extends BaseActionItem { } } - getMnemonic(): KeyCode { + getMnemonic(): string { return this.mnemonic; } diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 02e64243b56..4506ec9f488 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -14,7 +14,7 @@ import { cleanMnemonic, IMenuOptions, Menu, MENU_ESCAPED_MNEMONIC_REGEX, MENU_MN import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Event, Emitter } from 'vs/base/common/event'; -import { KeyCode, KeyCodeUtils, ResolvedKeybinding } from 'vs/base/common/keyCodes'; +import { KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes'; import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; const $ = DOM.$; @@ -70,7 +70,7 @@ export class MenuBar extends Disposable { private openedViaKeyboard: boolean; private awaitingAltRelease: boolean; private ignoreNextMouseUp: boolean; - private mnemonics: Map; + private mnemonics: Map; private updatePending: boolean; private _focusState: MenubarState; @@ -89,7 +89,7 @@ export class MenuBar extends Disposable { this.container.attributes['role'] = 'menubar'; this.menuCache = []; - this.mnemonics = new Map(); + this.mnemonics = new Map(); this._focusState = MenubarState.VISIBLE; @@ -110,7 +110,7 @@ export class MenuBar 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; + const key = !!e.key ? e.key.toLocaleLowerCase() : ''; if (event.equals(KeyCode.LeftArrow)) { this.focusPrevious(); @@ -162,7 +162,7 @@ export class MenuBar extends Disposable { return; } - const key = KeyCodeUtils.fromString(e.key); + const key = e.key.toLocaleLowerCase(); if (!this.mnemonics.has(key)) { return; } @@ -505,7 +505,7 @@ export class MenuBar extends Disposable { } private registerMnemonic(menuIndex: number, mnemonic: string): void { - this.mnemonics.set(KeyCodeUtils.fromString(mnemonic), menuIndex); + this.mnemonics.set(mnemonic.toLocaleLowerCase(), menuIndex); } private hideMenubar(): void { From 8c6d7bcbd0cbda7e1d09860d268cca8ae3ad0bc7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Feb 2019 11:21:56 -0800 Subject: [PATCH 029/290] Bundle TS 3.3.3 instead of TS 3.3.3333 People were being confused by the version number... --- extensions/package.json | 2 +- extensions/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/package.json b/extensions/package.json index 94c17380115..88394d29642 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.3.3333" + "typescript": "3.3.3" }, "scripts": { "postinstall": "node ./postinstall" diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 568fe29f5bf..abf61b0ecfa 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -2,7 +2,7 @@ # yarn lockfile v1 -typescript@3.3.3333: - version "3.3.3333" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.3333.tgz#171b2c5af66c59e9431199117a3bcadc66fdcfd6" - integrity sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw== +typescript@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.3.3.tgz#f1657fc7daa27e1a8930758ace9ae8da31403221" + integrity sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A== From 69249882e8717cf111e04330390107282e337559 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 27 Feb 2019 11:45:57 -0800 Subject: [PATCH 030/290] fixes #69323 --- src/vs/workbench/browser/layout.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 09e3e1b2b10..819bb315340 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -423,7 +423,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr } this.statusbarHeight = isStatusbarHidden ? 0 : this.partLayoutInfo.statusbar.height; - this.titlebarHeight = isTitlebarHidden ? 0 : this.partLayoutInfo.titlebar.height / (!menubarVisibility || menubarVisibility === 'hidden' ? getZoomFactor() : 1); // adjust for zoom prevention + this.titlebarHeight = isTitlebarHidden ? 0 : this.partLayoutInfo.titlebar.height / (isMacintosh || !menubarVisibility || menubarVisibility === 'hidden' ? getZoomFactor() : 1); // adjust for zoom prevention this.sidebarHeight = this.workbenchSize.height - this.statusbarHeight - this.titlebarHeight; let sidebarSize = new Dimension(this.sidebarWidth, this.sidebarHeight); From d51a1ce48270a1e51cf2c8943c62d71197bf0bb0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Feb 2019 13:52:04 -0800 Subject: [PATCH 031/290] Remove star from ligthbulb widget --- src/vs/editor/contrib/codeAction/codeActionWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/codeActionWidget.ts b/src/vs/editor/contrib/codeAction/codeActionWidget.ts index 3522fc39320..c1968825103 100644 --- a/src/vs/editor/contrib/codeAction/codeActionWidget.ts +++ b/src/vs/editor/contrib/codeAction/codeActionWidget.ts @@ -51,7 +51,7 @@ export class CodeActionContextMenu { private codeActionToAction(action: CodeAction): Action { const id = action.command ? action.command.id : action.title; - const title = action.isPreferred ? `${action.title} ★` : action.title; + const title = action.title; return new Action(id, title, undefined, true, () => this._onApplyCodeAction(action) .finally(() => this._onDidExecuteCodeAction.fire(undefined))); From bbcea2f3f9ae6b92a924d8934579c3973b57d8b0 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 27 Feb 2019 15:13:34 -0800 Subject: [PATCH 032/290] adding some basic menubar tests --- .../base/test/browser/ui/menu/menubar.test.ts | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/vs/base/test/browser/ui/menu/menubar.test.ts diff --git a/src/vs/base/test/browser/ui/menu/menubar.test.ts b/src/vs/base/test/browser/ui/menu/menubar.test.ts new file mode 100644 index 00000000000..7e41a8a46a6 --- /dev/null +++ b/src/vs/base/test/browser/ui/menu/menubar.test.ts @@ -0,0 +1,81 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { $ } from 'vs/base/browser/dom'; +import { MenuBar } from 'vs/base/browser/ui/menu/menubar'; + +function getButtonElementByAriaLabel(menubarElement: HTMLElement, ariaLabel: string): HTMLElement | null { + let i; + for (i = 0; i < menubarElement.childElementCount; i++) { + + if (menubarElement.children[i].getAttribute('aria-label') === ariaLabel) { + return menubarElement.children[i] as HTMLElement; + } + } + + return null; +} + +function getTitleDivFromButtonDiv(menuButtonElement: HTMLElement): HTMLElement | null { + let i; + for (i = 0; i < menuButtonElement.childElementCount; i++) { + if (menuButtonElement.children[i].classList.contains('menubar-menu-title')) { + return menuButtonElement.children[i] as HTMLElement; + } + } + + return null; +} + +function getMnemonicFromTitleDiv(menuTitleDiv: HTMLElement): string | null { + let i; + for (i = 0; i < menuTitleDiv.childElementCount; i++) { + if (menuTitleDiv.children[i].tagName.toLocaleLowerCase() === 'mnemonic') { + return menuTitleDiv.children[i].textContent; + } + } + + return null; +} + +function validateMenuBarItem(menubar: MenuBar, menubarContainer: HTMLElement, label: string, readableLabel: string, mnemonic: string) { + menubar.push([ + { + actions: [], + label: label + } + ]); + + const buttonElement = getButtonElementByAriaLabel(menubarContainer, readableLabel); + assert(buttonElement !== null, `Button element not found for ${readableLabel} button.`); + + const titleDiv = getTitleDivFromButtonDiv(buttonElement); + assert(titleDiv !== null, `Title div not found for ${readableLabel} button.`); + + const mnem = getMnemonicFromTitleDiv(titleDiv); + assert.equal(mnem, mnemonic, 'Mnemonic not correct'); +} + +suite('Menubar', () => { + const container = $('.container'); + + const menubar = new MenuBar(container, { + enableMnemonics: true, + visibility: 'visible' + }); + + test('English File menu renders mnemonics', function () { + validateMenuBarItem(menubar, container, '&File', 'File', 'F'); + }); + + test('Russian File menu renders mnemonics', function () { + validateMenuBarItem(menubar, container, '&Файл', 'Файл', 'Ф'); + }); + + test('Chinese File menu renders mnemonics', function () { + validateMenuBarItem(menubar, container, '文件(&F)', '文件', 'F'); + }); +}); \ No newline at end of file From 17d8121dd6098f01d5fd2acef297d8d3ed72bc73 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 27 Feb 2019 16:23:11 -0800 Subject: [PATCH 033/290] node2@1.32.1 - #69118 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 37d63713475..e0794621304 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -16,7 +16,7 @@ }, { "name": "ms-vscode.node-debug2", - "version": "1.32.0", + "version": "1.32.1", "repo": "https://github.com/Microsoft/vscode-node-debug2", "metadata": { "id": "36d19e17-7569-4841-a001-947eb18602b2", From 0a4a3b98282175a82a819b70d2bbe46475e1ebd0 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 27 Feb 2019 17:17:17 -0800 Subject: [PATCH 034/290] strict null checks --- src/vs/base/test/browser/ui/menu/menubar.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/test/browser/ui/menu/menubar.test.ts b/src/vs/base/test/browser/ui/menu/menubar.test.ts index 7e41a8a46a6..8bbeddcfc58 100644 --- a/src/vs/base/test/browser/ui/menu/menubar.test.ts +++ b/src/vs/base/test/browser/ui/menu/menubar.test.ts @@ -52,10 +52,10 @@ function validateMenuBarItem(menubar: MenuBar, menubarContainer: HTMLElement, la const buttonElement = getButtonElementByAriaLabel(menubarContainer, readableLabel); assert(buttonElement !== null, `Button element not found for ${readableLabel} button.`); - const titleDiv = getTitleDivFromButtonDiv(buttonElement); + const titleDiv = getTitleDivFromButtonDiv(buttonElement!); assert(titleDiv !== null, `Title div not found for ${readableLabel} button.`); - const mnem = getMnemonicFromTitleDiv(titleDiv); + const mnem = getMnemonicFromTitleDiv(titleDiv!); assert.equal(mnem, mnemonic, 'Mnemonic not correct'); } From 09d4f006b20f4d74b3a76a53ccddec46bd9baef9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 28 Feb 2019 13:04:18 -0800 Subject: [PATCH 035/290] Revert "Cleaning up reviver handling for webviews" This reverts commit 714192fdc30bfdb02259f41a3459e335c2b38e5a. Fixes #69612 --- .../api/electron-browser/mainThreadWebview.ts | 109 +++++++++--------- .../electron-browser/webviewEditorService.ts | 32 +++-- 2 files changed, 73 insertions(+), 68 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index e8b248cb19c..2e056e31d90 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -2,33 +2,35 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { onUnexpectedError } from 'vs/base/common/errors'; 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 { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { localize } from 'vs/nls'; -import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewInsetHandle, WebviewPanelHandle, WebviewPanelShowOptions } from 'vs/workbench/api/node/extHost.protocol'; +import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions, WebviewInsetHandle } from 'vs/workbench/api/node/extHost.protocol'; import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/shared/editor'; -import { CodeInsetController } from 'vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution'; import { WebviewEditor } from 'vs/workbench/contrib/webview/electron-browser/webviewEditor'; import { WebviewEditorInput } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorInput'; -import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorService'; -import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; -import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions, WebviewReviver } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import * as vscode from 'vscode'; import { extHostNamedCustomer } from './extHostCustomers'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { onUnexpectedError } from 'vs/base/common/errors'; +import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { CodeInsetController } from 'vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution'; +import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; @extHostNamedCustomer(MainContext.MainThreadWebviews) -export class MainThreadWebviews implements MainThreadWebviewsShape { +export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviver { + + private static readonly viewType = 'mainThreadWebview'; private static readonly standardSupportedLinkSchemes = ['http', 'https', 'mailto']; @@ -39,7 +41,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape { private readonly _proxy: ExtHostWebviewsShape; private readonly _webviews = new Map(); private readonly _webviewsElements = new Map(); - private readonly _revivers = new Map(); + private readonly _revivers = new Set(); private _activeWebview: WebviewPanelHandle | undefined = undefined; @@ -60,6 +62,8 @@ export class MainThreadWebviews implements MainThreadWebviewsShape { _editorService.onDidActiveEditorChange(this.onActiveEditorChanged, this, this._toDispose); _editorService.onDidVisibleEditorsChange(this.onVisibleEditorsChanged, this, this._toDispose); + this._toDispose.push(_webviewService.registerReviver(MainThreadWebviews.viewType, this)); + lifecycleService.onBeforeShutdown(e => { e.veto(this._onBeforeShutdown()); }, this, this._toDispose); @@ -84,7 +88,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape { mainThreadShowOptions.group = viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn); } - const webview = this._webviewService.createWebview(this.getInternalWebviewId(viewType), title, mainThreadShowOptions, reviveWebviewOptions(options), URI.revive(extensionLocation), this.createWebviewEventDelegate(handle)); + const webview = this._webviewService.createWebview(MainThreadWebviews.viewType, title, mainThreadShowOptions, reviveWebviewOptions(options), URI.revive(extensionLocation), this.createWebviewEventDelegate(handle)); webview.state = { viewType: viewType, state: undefined @@ -205,57 +209,50 @@ export class MainThreadWebviews implements MainThreadWebviewsShape { } public $registerSerializer(viewType: string): void { - if (this._revivers.has(viewType)) { - throw new Error(`Reviver for ${viewType} already registered`); - } - this._revivers.set(viewType, this._webviewService.registerReviver(this.getInternalWebviewId(viewType), { - canRevive: (webview) => { - return !webview.isDisposed() && webview.state; - }, - reviveWebview: (webview): Promise => { - const viewType = webview.state.viewType; - return Promise.resolve(this._extensionService.activateByEvent(`onWebviewPanel:${viewType}`).then(() => { - const handle = 'revival-' + MainThreadWebviews.revivalPool++; - this._webviews.set(handle, webview); - webview._events = this.createWebviewEventDelegate(handle); - let state = undefined; - if (webview.state.state) { - try { - state = JSON.parse(webview.state.state); - } catch { - // noop - } - } - - return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webview.group), webview.options) - .then(undefined, error => { - onUnexpectedError(error); - - webview.html = MainThreadWebviews.getDeserializationFailedContents(viewType); - }); - })); - } - })); + this._revivers.add(viewType); } public $unregisterSerializer(viewType: string): void { - const reviver = this._revivers.get(viewType); - if (!reviver) { - throw new Error(`No reviver for ${viewType} registered`); - } - - reviver.dispose(); this._revivers.delete(viewType); } - private getInternalWebviewId(viewType: string): string { - return `mainThreadWebview-${viewType}`; + public reviveWebview(webview: WebviewEditorInput): Promise { + const viewType = webview.state.viewType; + return Promise.resolve(this._extensionService.activateByEvent(`onWebviewPanel:${viewType}`).then(() => { + const handle = 'revival-' + MainThreadWebviews.revivalPool++; + this._webviews.set(handle, webview); + webview._events = this.createWebviewEventDelegate(handle); + + let state = undefined; + if (webview.state.state) { + try { + state = JSON.parse(webview.state.state); + } catch { + // noop + } + } + + return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webview.group), webview.options) + .then(undefined, error => { + onUnexpectedError(error); + + webview.html = MainThreadWebviews.getDeserializationFailedContents(viewType); + }); + })); + } + + public canRevive(webview: WebviewEditorInput): boolean { + if (webview.isDisposed() || !webview.state) { + return false; + } + + return this._revivers.has(webview.state.viewType) || !!webview.reviver; } private _onBeforeShutdown(): boolean { - this._webviews.forEach((webview) => { - if (!webview.isDisposed() && webview.state && this._revivers.has(webview.state.viewType)) { - webview.state.state = webview.webviewState; + this._webviews.forEach((view) => { + if (this.canRevive(view)) { + view.state.state = view.webviewState; } }); return false; // Don't veto shutdown diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts index abbda87a79e..c1d9d940bed 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts @@ -90,7 +90,7 @@ export function areWebviewInputOptionsEqual(a: WebviewInputOptions, b: WebviewIn export class WebviewEditorService implements IWebviewEditorService { _serviceBrand: any; - private readonly _revivers = new Map(); + private readonly _revivers = new Map(); private _awaitingRevival: { input: WebviewEditorInput, resolve: (x: any) => void }[] = []; constructor( @@ -159,14 +159,17 @@ export class WebviewEditorService implements IWebviewEditorService { viewType: string, reviver: WebviewReviver ): IDisposable { - if (this._revivers.has(viewType)) { - throw new Error(`Reviver for ${viewType} already registered`); + const currentRevivers = this._revivers.get(viewType); + if (currentRevivers) { + currentRevivers.push(reviver); + } else { + this._revivers.set(viewType, [reviver]); } - this._revivers.set(viewType, reviver); + // Resolve any pending views - const toRevive = this._awaitingRevival.filter(x => reviver.canRevive(x.input)); - this._awaitingRevival = this._awaitingRevival.filter(x => !reviver.canRevive(x.input)); + const toRevive = this._awaitingRevival.filter(x => x.input.viewType === viewType); + this._awaitingRevival = this._awaitingRevival.filter(x => x.input.viewType !== viewType); for (const input of toRevive) { reviver.reviveWebview(input.input).then(() => input.resolve(undefined)); @@ -181,19 +184,24 @@ export class WebviewEditorService implements IWebviewEditorService { webview: WebviewEditorInput ): boolean { const viewType = webview.viewType; - const reviver = this._revivers.get(viewType); - return !!reviver && reviver.canRevive(webview); + const revivers = this._revivers.get(viewType); + return !!revivers && revivers.some(reviver => reviver.canRevive(webview)); } private async tryRevive( webview: WebviewEditorInput ): Promise { - const reviver = this._revivers.get(webview.viewType); - if (!reviver || !reviver.canRevive(webview)) { + const revivers = this._revivers.get(webview.viewType); + if (!revivers) { return false; } - await reviver.reviveWebview(webview); - return true; + for (const reviver of revivers) { + if (reviver.canRevive(webview)) { + await reviver.reviveWebview(webview); + return true; + } + } + return false; } } From 52306b406d9231a0667c758e536bd177e5570180 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Thu, 28 Feb 2019 18:16:29 -0800 Subject: [PATCH 036/290] Fix memory leak in commentThreadWidget --- .../electron-browser/commentThreadWidget.ts | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts index 5c3bad5a5b0..79fb58de164 100644 --- a/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts @@ -11,7 +11,7 @@ import { Action } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; import { Color } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; @@ -69,7 +69,7 @@ export class ReviewZoneWidget extends ZoneWidget { private _owner: string; private _pendingComment: string; private _draftMode: modes.DraftMode; - private _localToDispose: IDisposable[]; + private _submitActionsDisposables: IDisposable[]; private _globalToDispose: IDisposable[]; private _markdownRenderer: MarkdownRenderer; private _styleElement: HTMLStyleElement; @@ -117,7 +117,7 @@ export class ReviewZoneWidget extends ZoneWidget { this._draftMode = draftMode; this._isCollapsed = commentThread.collapsibleState !== modes.CommentThreadCollapsibleState.Expanded; this._globalToDispose = []; - this._localToDispose = []; + this._disposables = []; this._formActions = null; this.create(); @@ -296,12 +296,14 @@ export class ReviewZoneWidget extends ZoneWidget { } updateDraftMode(draftMode: modes.DraftMode) { - this._draftMode = draftMode; + if (this._draftMode !== draftMode) { + this._draftMode = draftMode; - if (this._formActions) { - let model = this._commentEditor.getModel(); - dom.clearNode(this._formActions); - this.createCommentWidgetActions(this._formActions, model); + if (this._formActions) { + let model = this._commentEditor.getModel(); + dom.clearNode(this._formActions); + this.createCommentWidgetActions(this._formActions, model); + } } } @@ -316,8 +318,8 @@ export class ReviewZoneWidget extends ZoneWidget { display(lineNumber: number) { this._commentGlyph = new CommentGlyphWidget(this.editor, lineNumber); - this._localToDispose.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); - this._localToDispose.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); + this._disposables.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); + this._disposables.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); let headHeight = Math.ceil(this.editor.getConfiguration().lineHeight * 1.2); this._headElement.style.height = `${headHeight}px`; this._headElement.style.lineHeight = this._headElement.style.height; @@ -343,12 +345,12 @@ export class ReviewZoneWidget extends ZoneWidget { }); const resource = URI.parse(`${COMMENT_SCHEME}:commentinput-${modeId}.md?${params}`); const model = this.modelService.createModel(this._pendingComment || '', this.modeService.createByFilepathOrFirstLine(resource.path), resource, false); - this._localToDispose.push(model); + this._disposables.push(model); this._commentEditor.setModel(model); - this._localToDispose.push(this._commentEditor); - this._localToDispose.push(this._commentEditor.getModel().onDidChangeContent(() => this.setCommentEditorDecorations())); + this._disposables.push(this._commentEditor); + this._disposables.push(this._commentEditor.getModel().onDidChangeContent(() => this.setCommentEditorDecorations())); if ((this._commentThread as modes.CommentThread2).commentThreadHandle !== undefined) { - this._localToDispose.push(this._commentEditor.onDidFocusEditorWidget(() => { + this._disposables.push(this._commentEditor.onDidFocusEditorWidget(() => { let commentThread = this._commentThread as modes.CommentThread2; commentThread.input = { uri: this._commentEditor.getModel().uri, @@ -357,7 +359,7 @@ export class ReviewZoneWidget extends ZoneWidget { this.commentService.setActiveCommentThread(this._commentThread); })); - this._localToDispose.push(this._commentEditor.getModel().onDidChangeContent(() => { + this._disposables.push(this._commentEditor.getModel().onDidChangeContent(() => { let modelContent = this._commentEditor.getValue(); let thread = (this._commentThread as modes.CommentThread2); if (thread.input.uri === this._commentEditor.getModel().uri && thread.input.value !== modelContent) { @@ -367,7 +369,7 @@ export class ReviewZoneWidget extends ZoneWidget { } })); - this._localToDispose.push((this._commentThread as modes.CommentThread2).onDidChangeInput(input => { + this._disposables.push((this._commentThread as modes.CommentThread2).onDidChangeInput(input => { let thread = (this._commentThread as modes.CommentThread2); if (thread.input.uri !== this._commentEditor.getModel().uri) { @@ -389,7 +391,7 @@ export class ReviewZoneWidget extends ZoneWidget { } })); - this._localToDispose.push((this._commentThread as modes.CommentThread2).onDidChangeComments(_ => { + this._disposables.push((this._commentThread as modes.CommentThread2).onDidChangeComments(_ => { this.update(this._commentThread); })); } @@ -406,7 +408,7 @@ export class ReviewZoneWidget extends ZoneWidget { } } - this._localToDispose.push(this._commentEditor.onKeyDown((ev: IKeyboardEvent) => { + this._disposables.push(this._commentEditor.onKeyDown((ev: IKeyboardEvent) => { const hasExistingComments = this._commentThread.comments.length > 0; if (this._commentEditor.getModel().getValueLength() === 0 && ev.keyCode === KeyCode.Escape) { @@ -432,7 +434,7 @@ export class ReviewZoneWidget extends ZoneWidget { if ((this._commentThread as modes.CommentThread2).commentThreadHandle !== undefined) { this.createCommentWidgetActions2(this._formActions, model); - this._localToDispose.push((this._commentThread as modes.CommentThread2).onDidChangeAcceptInputCommands(_ => { + this._disposables.push((this._commentThread as modes.CommentThread2).onDidChangeAcceptInputCommands(_ => { dom.clearNode(this._formActions); this.createCommentWidgetActions2(this._formActions, model); })); @@ -471,12 +473,14 @@ export class ReviewZoneWidget extends ZoneWidget { } private createCommentWidgetActions(container: HTMLElement, model: ITextModel) { + dispose(this._submitActionsDisposables); + const button = new Button(container); - this._localToDispose.push(attachButtonStyler(button, this.themeService)); + this._submitActionsDisposables.push(attachButtonStyler(button, this.themeService)); button.label = 'Add comment'; button.enabled = model.getValueLength() > 0; - this._localToDispose.push(this._commentEditor.onDidChangeModelContent(_ => { + this._submitActionsDisposables.push(this._commentEditor.onDidChangeModelContent(_ => { if (this._commentEditor.getValue()) { button.enabled = true; } else { @@ -498,7 +502,7 @@ export class ReviewZoneWidget extends ZoneWidget { const deleteDraftLabel = this.commentService.getDeleteDraftLabel(this._owner); if (deleteDraftLabel) { const deletedraftButton = new Button(container); - this._disposables.push(attachButtonStyler(deletedraftButton, this.themeService)); + this._submitActionsDisposables.push(attachButtonStyler(deletedraftButton, this.themeService)); deletedraftButton.label = deleteDraftLabel; deletedraftButton.enabled = true; @@ -514,7 +518,7 @@ export class ReviewZoneWidget extends ZoneWidget { const submitDraftLabel = this.commentService.getFinishDraftLabel(this._owner); if (submitDraftLabel) { const submitdraftButton = new Button(container); - this._disposables.push(attachButtonStyler(submitdraftButton, this.themeService)); + this._submitActionsDisposables.push(attachButtonStyler(submitdraftButton, this.themeService)); submitdraftButton.label = this.commentService.getFinishDraftLabel(this._owner); submitdraftButton.enabled = true; @@ -540,7 +544,7 @@ export class ReviewZoneWidget extends ZoneWidget { draftButton.label = this.commentService.getStartDraftLabel(this._owner); draftButton.enabled = model.getValueLength() > 0; - this._localToDispose.push(this._commentEditor.onDidChangeModelContent(_ => { + this._submitActionsDisposables.push(this._commentEditor.onDidChangeModelContent(_ => { if (this._commentEditor.getValue()) { draftButton.enabled = true; } else { @@ -571,12 +575,12 @@ export class ReviewZoneWidget extends ZoneWidget { commentThread.acceptInputCommands.reverse().forEach(command => { const button = new Button(container); - this._localToDispose.push(attachButtonStyler(button, this.themeService)); + this._disposables.push(attachButtonStyler(button, this.themeService)); button.label = command.title; let commandId = command.id; let args = command.arguments || []; - this._localToDispose.push(button.onDidClick(async () => { + this._disposables.push(button.onDidClick(async () => { commentThread.input = { uri: this._commentEditor.getModel().uri, value: this._commentEditor.getValue() @@ -707,8 +711,8 @@ export class ReviewZoneWidget extends ZoneWidget { } this._reviewThreadReplyButton.textContent = nls.localize('reply', "Reply..."); // bind click/escape actions for reviewThreadReplyButton and textArea - this._localToDispose.push(dom.addDisposableListener(this._reviewThreadReplyButton, 'click', _ => this.expandReplyArea())); - this._localToDispose.push(dom.addDisposableListener(this._reviewThreadReplyButton, 'focus', _ => this.expandReplyArea())); + this._disposables.push(dom.addDisposableListener(this._reviewThreadReplyButton, 'click', _ => this.expandReplyArea())); + this._disposables.push(dom.addDisposableListener(this._reviewThreadReplyButton, 'focus', _ => this.expandReplyArea())); this._commentEditor.onDidBlurEditorWidget(() => { if (this._commentEditor.getModel().getValueLength() === 0 && dom.hasClass(this._commentForm, 'expand')) { @@ -920,7 +924,7 @@ export class ReviewZoneWidget extends ZoneWidget { } this._globalToDispose.forEach(global => global.dispose()); - this._localToDispose.forEach(local => local.dispose()); + this._submitActionsDisposables.forEach(local => local.dispose()); this._onDidClose.fire(undefined); } } \ No newline at end of file From 240eace66d4af5652c2a2c13f315c9705ed2108f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 1 Mar 2019 13:45:43 +0100 Subject: [PATCH 037/290] fix #69557 --- .../workbench/browser/parts/editor/breadcrumbsPicker.ts | 2 +- src/vs/workbench/contrib/outline/browser/outlinePanel.ts | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index decc4f57d70..6f1c4e469c8 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -150,7 +150,7 @@ export abstract class BreadcrumbsPicker { this._arrow.style.marginLeft = `${this._layoutInfo.arrowOffset}px`; this._treeContainer.style.height = `${treeHeight}px`; this._treeContainer.style.width = `${this._layoutInfo.width}px`; - this._tree.layout(); + this._tree.layout(treeHeight, this._layoutInfo.width); } diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index 99d9907e974..0df0b100107 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -239,7 +239,6 @@ export class OutlinePanel extends ViewletPanel { private _editorDisposables = new Array(); private _outlineViewState = new OutlineViewState(); private _requestOracle?: RequestOracle; - private _cachedHeight: number; private _domNode: HTMLElement; private _message: HTMLDivElement; private _inputContainer: HTMLDivElement; @@ -379,10 +378,8 @@ export class OutlinePanel extends ViewletPanel { })); } - protected layoutBody(height: number): void { - if (height !== this._cachedHeight) { - this._tree.layout(height); - } + protected layoutBody(height: number, width: number): void { + this._tree.layout(height, width); } getActions(): IAction[] { @@ -525,7 +522,7 @@ export class OutlinePanel extends ViewletPanel { await this._tree.setInput(newModel, state); } - this.layoutBody(this._cachedHeight); + this._tree.layout(); // transfer focus from domNode to the tree if (this._domNode === document.activeElement) { From 78484cc6cee62012f7a19d700ecb90d10126e4f8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 1 Mar 2019 13:51:45 +0100 Subject: [PATCH 038/290] fix #69578 --- src/vs/editor/contrib/documentSymbols/outlineTree.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index a15286a4a94..a6fe4786c24 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -16,7 +16,7 @@ import { SymbolKind, symbolKindToCssClass } from 'vs/editor/common/modes'; import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { localize } from 'vs/nls'; import { IKeybindingService, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; -import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; +import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { OutlineConfigKeys } from 'vs/editor/contrib/documentSymbols/outline'; import { MarkerSeverity } from 'vs/platform/markers/common/markers'; @@ -120,8 +120,9 @@ export class OutlineElementRenderer implements ITreeRenderer, index: number, template: OutlineElementTemplate): void { const { element } = node; - const options = { + const options: IIconLabelValueOptions = { matches: createMatches(node.filterData), + labelEscapeNewLines: true, extraClasses: [], title: localize('title.template', "{0} ({1})", element.symbol.name, OutlineElementRenderer._symbolKindNames[element.symbol.kind]) }; From 28d66834bdc0c75628ca0eb2c97a65c434808ad8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 1 Mar 2019 13:53:16 +0100 Subject: [PATCH 039/290] strict null mess --- src/vs/editor/contrib/documentSymbols/outlineTree.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index a6fe4786c24..926d6a3da2f 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -16,7 +16,7 @@ import { SymbolKind, symbolKindToCssClass } from 'vs/editor/common/modes'; import { OutlineElement, OutlineGroup, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { localize } from 'vs/nls'; import { IKeybindingService, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; -import { IconLabel, IIconLabelValueOptions } from 'vs/base/browser/ui/iconLabel/iconLabel'; +import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { OutlineConfigKeys } from 'vs/editor/contrib/documentSymbols/outline'; import { MarkerSeverity } from 'vs/platform/markers/common/markers'; @@ -120,7 +120,7 @@ export class OutlineElementRenderer implements ITreeRenderer, index: number, template: OutlineElementTemplate): void { const { element } = node; - const options: IIconLabelValueOptions = { + const options = { matches: createMatches(node.filterData), labelEscapeNewLines: true, extraClasses: [], From c3913b81adacb36ae9c636b29fb2391a3f436789 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 1 Mar 2019 14:03:59 +0100 Subject: [PATCH 040/290] Revert "make sure outline requests are cancelled when changing providers, #69147" This reverts commit bfe5b4c92c18b0be8e492b836bbbb45ca0571d4e. This fixes #69657 --- .../contrib/documentSymbols/outlineModel.ts | 12 +++------ .../documentSymbols/test/outlineModel.test.ts | 26 +------------------ 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineModel.ts b/src/vs/editor/contrib/documentSymbols/outlineModel.ts index 0c231026ede..179b23f3a11 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineModel.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineModel.ts @@ -264,11 +264,7 @@ export class OutlineModel extends TreeElement { }); } - private static _create(textModel: ITextModel, token: CancellationToken): Promise { - - let chainedToken = new CancellationTokenSource(); - let listener = DocumentSymbolProviderRegistry.onDidChange(() => chainedToken.cancel()); - token.onCancellationRequested(() => chainedToken.cancel()); + static _create(textModel: ITextModel, token: CancellationToken): Promise { let result = new OutlineModel(textModel); let promises = DocumentSymbolProviderRegistry.ordered(textModel).map((provider, index) => { @@ -276,7 +272,7 @@ export class OutlineModel extends TreeElement { let id = TreeElement.findId(`provider_${index}`, result); let group = new OutlineGroup(id, result, provider, index); - return Promise.resolve(provider.provideDocumentSymbols(result.textModel, chainedToken.token)).then(result => { + return Promise.resolve(provider.provideDocumentSymbols(result.textModel, token)).then(result => { for (const info of result || []) { OutlineModel._makeOutlineElement(info, group); } @@ -293,9 +289,7 @@ export class OutlineModel extends TreeElement { }); }); - return Promise.all(promises) - .then(() => result._compact()) - .finally(() => listener.dispose()); + return Promise.all(promises).then(() => result._compact()); } private static _makeOutlineElement(info: DocumentSymbol, container: OutlineGroup | OutlineElement): void { diff --git a/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts b/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts index 229c065da87..b15a1451072 100644 --- a/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts +++ b/src/vs/editor/contrib/documentSymbols/test/outlineModel.test.ts @@ -46,7 +46,7 @@ suite('OutlineModel', function () { let isCancelled = false; let reg = DocumentSymbolProviderRegistry.register({ pattern: '**/path.foo' }, { - provideDocumentSymbols(_d, token) { + provideDocumentSymbols(d, token) { return new Promise(resolve => { token.onCancellationRequested(_ => { isCancelled = true; @@ -183,28 +183,4 @@ suite('OutlineModel', function () { assert.equal(model.children['g2']!.children['c2'].children['c2.2'].marker!.count, 1); }); - test('"Cannot read property \'adapter\' of undefined" #69147', async function () { - - let model = TextModel.createFromString('foo', undefined, undefined, URI.file('/fome/path.foo')); - let reg1 = DocumentSymbolProviderRegistry.register({ pattern: '**/path.foo' }, { - provideDocumentSymbols(_model, token) { - assert.equal(token.isCancellationRequested, true); - return []; - } - }); - let reg2 = DocumentSymbolProviderRegistry.register({ pattern: '**/path.foo' }, { - provideDocumentSymbols(_model, token) { - assert.equal(token.isCancellationRequested, false); - reg1.dispose(); - assert.equal(token.isCancellationRequested, true); - return []; - } - }); - - await OutlineModel.create(model, CancellationToken.None); - - reg1.dispose(); - reg2.dispose(); - }); - }); From 804373ac4d5c84e96c8086cee5b9be132df88837 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 1 Mar 2019 18:00:01 +0100 Subject: [PATCH 041/290] fixes #69613 --- .../contrib/referenceSearch/referencesWidget.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts index 78037a31b7e..c637c11f7e0 100644 --- a/src/vs/editor/contrib/referenceSearch/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/referencesWidget.ts @@ -412,16 +412,16 @@ export class ReferenceWidget extends PeekViewWidget { onEvent(e.elements[0], 'show'); } }); - this._tree.onMouseDblClick(e => { - const aside = e.browserEvent.ctrlKey || e.browserEvent.metaKey || e.browserEvent.altKey; - const goto = e.browserEvent.detail === 2; + this._tree.onDidOpen(e => { + const aside = (e.browserEvent instanceof MouseEvent) && (e.browserEvent.ctrlKey || e.browserEvent.metaKey || e.browserEvent.altKey); + const goto = !e.browserEvent || ((e.browserEvent instanceof MouseEvent) && e.browserEvent.detail === 2); if (aside) { - onEvent(e.element, 'side'); + onEvent(e.elements[0], 'side'); } else if (goto) { - onEvent(e.element, 'goto'); + onEvent(e.elements[0], 'goto'); } else { - onEvent(e.element, 'show'); + onEvent(e.elements[0], 'show'); } }); From d6c200ea57fc3104af1c237dfd16ff0d83c3ad2a Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Fri, 1 Mar 2019 10:47:58 -0800 Subject: [PATCH 042/290] Initialize disposables array in commentThreadWidget --- .../contrib/comments/electron-browser/commentThreadWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts index 79fb58de164..973dd5a3292 100644 --- a/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts @@ -117,7 +117,7 @@ export class ReviewZoneWidget extends ZoneWidget { this._draftMode = draftMode; this._isCollapsed = commentThread.collapsibleState !== modes.CommentThreadCollapsibleState.Expanded; this._globalToDispose = []; - this._disposables = []; + this._submitActionsDisposables = []; this._formActions = null; this.create(); From 485b2c924a9c66faa20c6bd10c799e5e9409f8a5 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 1 Mar 2019 12:47:37 -0800 Subject: [PATCH 043/290] Notice for Node v10.x requirement for smoketest --- test/smoke/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/smoke/README.md b/test/smoke/README.md index c61944fee9e..4154212a0f5 100644 --- a/test/smoke/README.md +++ b/test/smoke/README.md @@ -1,5 +1,7 @@ # VS Code Smoke Test +Make sure you are on **Node v10.x**. + ### Run ```bash From 55d720646c20baf94b4ff2b20b7b79bbfb3ef8a6 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Fri, 1 Mar 2019 22:28:42 +0100 Subject: [PATCH 044/290] support integrated terminal in serverReady feature --- .../debug-server-ready/src/extension.ts | 186 ++++++++++++------ .../debug-server-ready/src/typings/ref.d.ts | 1 + 2 files changed, 127 insertions(+), 60 deletions(-) diff --git a/extensions/debug-server-ready/src/extension.ts b/extensions/debug-server-ready/src/extension.ts index 1aecc7ec852..413c4c3529f 100644 --- a/extensions/debug-server-ready/src/extension.ts +++ b/extensions/debug-server-ready/src/extension.ts @@ -7,7 +7,6 @@ import * as vscode from 'vscode'; //import * as nls from 'vscode-nls'; import * as util from 'util'; -const trackers = new Set(); const PATTERN = 'listening on.* (https?://\\S+|[0-9]+)'; // matches "listening on port 3000" or "Now listening on: https://localhost:5001" const URI_FORMAT = 'http://localhost:%s'; @@ -20,13 +19,123 @@ interface ServerReadyAction { webRoot?: string; } +class ServerReadyDetector extends vscode.Disposable { + static detectors = new Map(); + + private hasFired = false; + private regexp: RegExp; + private disposables: vscode.Disposable[] = []; + + static start(session: vscode.DebugSession): ServerReadyDetector | undefined { + if (session.configuration.serverReadyAction) { + let detector = ServerReadyDetector.detectors.get(session); + if (!detector) { + detector = new ServerReadyDetector(session); + ServerReadyDetector.detectors.set(session, detector); + } + return detector; + } + return undefined; + } + + static stop(session: vscode.DebugSession): void { + let detector = ServerReadyDetector.detectors.get(session); + if (detector) { + ServerReadyDetector.detectors.delete(session); + detector.dispose(); + } + } + + private constructor(private session: vscode.DebugSession) { + super(() => this.internalDispose()); + + this.regexp = new RegExp(session.configuration.serverReadyAction.pattern || PATTERN); + } + + private internalDispose() { + this.disposables.forEach(d => d.dispose()); + this.disposables = []; + } + + trackTerminals() { + // TODO: listen only on the Terminal associated with the debug session + vscode.window.terminals.forEach(terminal => { + this.disposables.push(terminal.onDidWriteData(s => { + this.detectPattern(s); + })); + }); + } + + detectPattern(s: string): void { + + if (!this.hasFired) { + const result = this.regexp.exec(s); + if (result && result.length === 2) { + this.openExternalWithString(this.session, result[1]); + this.hasFired = true; + this.internalDispose(); + } + } + } + + private openExternalWithString(session: vscode.DebugSession, portOrUriString: string) { + + if (portOrUriString) { + if (/^[0-9]+$/.test(portOrUriString)) { + const args: ServerReadyAction = session.configuration.serverReadyAction; + portOrUriString = util.format(args.uriFormat || URI_FORMAT, portOrUriString); + } + this.openExternalWithUri(session, portOrUriString); + } + } + + private openExternalWithUri(session: vscode.DebugSession, uri: string) { + + const args: ServerReadyAction = session.configuration.serverReadyAction; + switch (args.action || 'openExternally') { + case 'openExternally': + vscode.env.openExternal(vscode.Uri.parse(uri)); + break; + case 'debugWithChrome': + vscode.debug.startDebugging(session.workspaceFolder, { + type: 'chrome', + name: 'Chrome Debug', + request: 'launch', + url: uri, + webRoot: args.webRoot || WEB_ROOT + }); + break; + default: + // not supported + break; + } + } +} + export function activate(context: vscode.ExtensionContext) { + context.subscriptions.push(vscode.debug.onDidChangeActiveDebugSession(session => { + if (session && session.configuration.serverReadyAction) { + const detector = ServerReadyDetector.start(session); + if (detector) { + detector.trackTerminals(); + } + } + })); + + context.subscriptions.push(vscode.debug.onDidTerminateDebugSession(session => { + ServerReadyDetector.stop(session); + })); + + const trackers = new Set(); + context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('*', { resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, debugConfiguration: vscode.DebugConfiguration) { - const args: ServerReadyAction = debugConfiguration.serverReadyAction; - if (debugConfiguration.type && args) { - startTrackerForType(context, debugConfiguration.type); + if (debugConfiguration.type && debugConfiguration.serverReadyAction) { + if (!trackers.has(debugConfiguration.type)) { + trackers.add(debugConfiguration.type); + startTrackerForType(context, debugConfiguration.type); + } } return debugConfiguration; } @@ -35,63 +144,20 @@ export function activate(context: vscode.ExtensionContext) { function startTrackerForType(context: vscode.ExtensionContext, type: string) { - if (!trackers.has(type)) { - trackers.add(type); - - // scan debug console output for a PORT message - context.subscriptions.push(vscode.debug.registerDebugAdapterTrackerFactory(type, { - createDebugAdapterTracker(session: vscode.DebugSession) { - const args: ServerReadyAction = session.configuration.serverReadyAction; - if (args) { - const regexp = new RegExp(args.pattern || PATTERN); - let hasFired = false; - return { - onDidSendMessage: m => { - if (!hasFired && m.type === 'event' && m.event === 'output' && m.body.output) { - const result = regexp.exec(m.body.output); - if (result && result.length === 2) { - openExternalWithString(session, result[1]); - hasFired = true; - } - } + // scan debug console output for a PORT message + context.subscriptions.push(vscode.debug.registerDebugAdapterTrackerFactory(type, { + createDebugAdapterTracker(session: vscode.DebugSession) { + const detector = ServerReadyDetector.start(session); + if (detector) { + return { + onDidSendMessage: m => { + if (m.type === 'event' && m.event === 'output' && m.body.output) { + detector.detectPattern(m.body.output); } - }; - } - return undefined; + } + }; } - })); - } -} - -function openExternalWithString(session: vscode.DebugSession, portOrUriString: string) { - - if (portOrUriString) { - if (/^[0-9]+$/.test(portOrUriString)) { - const args: ServerReadyAction = session.configuration.serverReadyAction; - portOrUriString = util.format(args.uriFormat || URI_FORMAT, portOrUriString); + return undefined; } - openExternalWithUri(session, portOrUriString); - } -} - -function openExternalWithUri(session: vscode.DebugSession, uri: string) { - - const args: ServerReadyAction = session.configuration.serverReadyAction; - switch (args.action || 'openExternally') { - case 'openExternally': - vscode.env.openExternal(vscode.Uri.parse(uri)); - break; - case 'debugWithChrome': - vscode.debug.startDebugging(session.workspaceFolder, { - type: 'chrome', - name: 'Chrome Debug', - request: 'launch', - url: uri, - webRoot: args.webRoot || WEB_ROOT - }); - break; - default: - // not supported - break; - } + })); } diff --git a/extensions/debug-server-ready/src/typings/ref.d.ts b/extensions/debug-server-ready/src/typings/ref.d.ts index bc057c55878..954bab971e3 100644 --- a/extensions/debug-server-ready/src/typings/ref.d.ts +++ b/extensions/debug-server-ready/src/typings/ref.d.ts @@ -4,4 +4,5 @@ *--------------------------------------------------------------------------------------------*/ /// +/// /// From c4b1ae364800aa95383b5a7c63b326d0870b369f Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 1 Mar 2019 15:55:09 -0800 Subject: [PATCH 045/290] 1.32 -> 1.33 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d392e69ab0c..606c1365c3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "code-oss-dev", - "version": "1.32.0", + "version": "1.33.0", "distro": "d7aadf23b016949c24a43083a0b3deecb8aa81fa", "author": { "name": "Microsoft Corporation" From 29acd11312415a5d9967f3e33015ddfc6d2ceb08 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 26 Feb 2019 16:13:26 -0800 Subject: [PATCH 046/290] Fix bad newline --- .../typescript-language-features/src/utils/typeConverters.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/utils/typeConverters.ts b/extensions/typescript-language-features/src/utils/typeConverters.ts index 36a20544fee..131287ea58f 100644 --- a/extensions/typescript-language-features/src/utils/typeConverters.ts +++ b/extensions/typescript-language-features/src/utils/typeConverters.ts @@ -63,8 +63,8 @@ export namespace WorkspaceEdit { edits: Iterable ): vscode.WorkspaceEdit { return withFileCodeEdits(new vscode.WorkspaceEdit(), client, edits); - } + export function withFileCodeEdits( workspaceEdit: vscode.WorkspaceEdit, client: ITypeScriptServiceClient, From 1cb65ce8e5f8d11987289b37ed8a544e370ecfce Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 26 Feb 2019 16:15:10 -0800 Subject: [PATCH 047/290] Extract and lift constant --- .../typescript-language-features/src/utils/typeConverters.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/utils/typeConverters.ts b/extensions/typescript-language-features/src/utils/typeConverters.ts index 131287ea58f..279853cff21 100644 --- a/extensions/typescript-language-features/src/utils/typeConverters.ts +++ b/extensions/typescript-language-features/src/utils/typeConverters.ts @@ -71,8 +71,9 @@ export namespace WorkspaceEdit { edits: Iterable ): vscode.WorkspaceEdit { for (const edit of edits) { + const resource = client.toResource(edit.fileName); for (const textChange of edit.textChanges) { - workspaceEdit.replace(client.toResource(edit.fileName), + workspaceEdit.replace(resource, Range.fromTextSpan(textChange), textChange.newText); } From 491dd0feb8cbb2c43b2ebea3f8ebbac2c4a047f6 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 26 Feb 2019 16:53:02 -0800 Subject: [PATCH 048/290] Add logging to see if TS buffers are in an invalid state An example would be trying to change a file that is not opened --- .../src/features/bufferSyncSupport.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index 32c0b020e6b..422fee00f03 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -13,11 +13,17 @@ import * as languageModeIds from '../utils/languageModeIds'; import { ResourceMap } from '../utils/resourceMap'; import * as typeConverters from '../utils/typeConverters'; -enum BufferKind { +const enum BufferKind { TypeScript = 1, JavaScript = 2, } +const enum BufferState { + Initial = 1, + Open = 2, + Closed = 2, +} + function mode2ScriptKind(mode: string): 'TS' | 'TSX' | 'JS' | 'JSX' | undefined { switch (mode) { case languageModeIds.typescript: return 'TS'; @@ -30,6 +36,8 @@ function mode2ScriptKind(mode: string): 'TS' | 'TSX' | 'JS' | 'JSX' | undefined class SyncedBuffer { + private state = BufferState.Initial; + constructor( private readonly document: vscode.TextDocument, public readonly filepath: string, @@ -63,6 +71,7 @@ class SyncedBuffer { } this.client.executeWithoutWaitingForResponse('open', args); + this.state = BufferState.Open; } public get resource(): vscode.Uri { @@ -91,9 +100,14 @@ class SyncedBuffer { file: this.filepath }; this.client.executeWithoutWaitingForResponse('close', args); + this.state = BufferState.Closed; } public onContentChanged(events: vscode.TextDocumentContentChangeEvent[]): void { + if (this.state !== BufferState.Open) { + console.error(`Unexpected buffer state: ${this.state}`); + } + for (const { range, text } of events) { const args: Proto.ChangeRequestArgs = { insertString: text, From 9061cad570f03d4fa0b698fb9f8bac1241f25d05 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 26 Feb 2019 17:14:14 -0800 Subject: [PATCH 049/290] Removing preview.html command Fixes #62630 --- .../src/singlefolder-tests/commands.test.ts | 17 -- src/vs/workbench/api/node/apiCommands.ts | 13 - src/vs/workbench/api/node/extHost.api.impl.ts | 19 +- .../workbench/api/node/extHostApiCommands.ts | 16 +- .../contrib/html/common/htmlInput.ts | 32 --- .../electron-browser/html.contribution.ts | 81 ------ .../html/electron-browser/htmlPreviewPart.ts | 256 ------------------ src/vs/workbench/workbench.main.ts | 3 - 8 files changed, 2 insertions(+), 435 deletions(-) delete mode 100644 src/vs/workbench/contrib/html/common/htmlInput.ts delete mode 100644 src/vs/workbench/contrib/html/electron-browser/html.contribution.ts delete mode 100644 src/vs/workbench/contrib/html/electron-browser/htmlPreviewPart.ts diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts index c007e2168f0..c26666ed671 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/commands.test.ts @@ -74,23 +74,6 @@ suite('commands namespace tests', () => { }); - test('api-command: vscode.previewHtml', async function () { - - let registration = workspace.registerTextDocumentContentProvider('speciale', { - provideTextDocumentContent(uri) { - return `content of URI ${uri.toString()}`; - } - }); - - let virtualDocumentUri = Uri.parse('speciale://authority/path'); - let title = 'A title'; - - const success = await commands.executeCommand('vscode.previewHtml', virtualDocumentUri, ViewColumn.Three, title); - assert.ok(success); - registration.dispose(); - - }); - test('api-command: vscode.diff', function () { let registration = workspace.registerTextDocumentContentProvider('sc', { diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index 01d1c77337c..f2cc8adc5a6 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -36,19 +36,6 @@ function adjustHandler(handler: (executor: ICommandsExecutor, ...args: any[]) => }; } -export class PreviewHTMLAPICommand { - public static ID = 'vscode.previewHtml'; - public static execute(executor: ICommandsExecutor, uri: URI, position?: vscode.ViewColumn, label?: string, options?: any): Promise { - return executor.executeCommand('_workbench.previewHtml', - uri, - typeof position === 'number' && typeConverters.ViewColumn.from(position), - label, - options - ); - } -} -CommandsRegistry.registerCommand(PreviewHTMLAPICommand.ID, adjustHandler(PreviewHTMLAPICommand.execute)); - export class OpenFolderAPICommand { public static ID = 'vscode.openFolder'; public static execute(executor: ICommandsExecutor, uri?: URI, forceNewWindow?: boolean): Promise { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 565c8835155..d14dab1dd99 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -175,23 +175,6 @@ export function createApiFactory( }; })(); - // Warn when trying to use the vscode.previewHtml command as it does not work properly in all scenarios and - // has security concerns. - const checkCommand = (() => { - let done = false; - const informOnce = () => { - if (!done) { - done = true; - window.showWarningMessage(localize('previewHtml.deprecated', "Extension '{0}' uses the 'vscode.previewHtml' command which is deprecated and will be removed soon. Please file an issue against this extension to update to use VS Code's webview API.", extension.identifier.value)); - } - }; - return (commandId: string) => { - if (commandId === 'vscode.previewHtml') { - informOnce(); - } - return commandId; - }; - })(); // namespace: commands const commands: typeof vscode.commands = { @@ -232,7 +215,7 @@ export function createApiFactory( }); }), executeCommand(id: string, ...args: any[]): Thenable { - return extHostCommands.executeCommand(checkCommand(id), ...args); + return extHostCommands.executeCommand(id, ...args); }, getCommands(filterInternal: boolean = false): Thenable { return extHostCommands.getCommands(filterInternal); diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index 3e6559eb625..8a54f2e10d4 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -15,7 +15,7 @@ import * as search from 'vs/workbench/contrib/search/common/search'; import { ICommandHandlerDescription } from 'vs/platform/commands/common/commands'; import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands'; import { CustomCodeAction } from 'vs/workbench/api/node/extHostLanguageFeatures'; -import { ICommandsExecutor, PreviewHTMLAPICommand, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand, SetEditorLayoutAPICommand } from './apiCommands'; +import { ICommandsExecutor, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand, SetEditorLayoutAPICommand } from './apiCommands'; import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; @@ -219,20 +219,6 @@ export class ExtHostApiCommands { }; }; - this._register(PreviewHTMLAPICommand.ID, adjustHandler(PreviewHTMLAPICommand.execute), { - description: ` - Render the HTML of the resource in an editor view. - - See [working with the HTML preview](https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands#working-with-the-html-preview) for more information about the HTML preview's integration with the editor and for best practices for extension authors. - `, - args: [ - { name: 'uri', description: 'Uri of the resource to preview.', constraint: (value: any) => value instanceof URI || typeof value === 'string' }, - { name: 'column', description: '(optional) Column in which to preview.', constraint: (value: any) => typeof value === 'undefined' || (typeof value === 'number' && typeof types.ViewColumn[value] === 'string') }, - { name: 'label', description: '(optional) An human readable string that is used as title for the preview.', constraint: (v: any) => typeof v === 'string' || typeof v === 'undefined' }, - { name: 'options', description: '(optional) Options for controlling webview environment.', constraint: (v: any) => typeof v === 'object' || typeof v === 'undefined' } - ] - }); - this._register(OpenFolderAPICommand.ID, adjustHandler(OpenFolderAPICommand.execute), { description: 'Open a folder or workspace in the current window or new window depending on the newWindow argument. Note that opening in the same window will shutdown the current extension host process and start a new one on the given folder/workspace unless the newWindow parameter is set to true.', args: [ diff --git a/src/vs/workbench/contrib/html/common/htmlInput.ts b/src/vs/workbench/contrib/html/common/htmlInput.ts deleted file mode 100644 index e70b08d999a..00000000000 --- a/src/vs/workbench/contrib/html/common/htmlInput.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { URI } from 'vs/base/common/uri'; -import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; -import { ITextModelService } from 'vs/editor/common/services/resolverService'; -import { IHashService } from 'vs/workbench/services/hash/common/hashService'; - -export interface HtmlInputOptions { - readonly allowScripts?: boolean; - readonly allowSvgs?: boolean; - readonly svgWhiteList?: string[]; -} - -export function areHtmlInputOptionsEqual(left: HtmlInputOptions, right: HtmlInputOptions) { - return left.allowScripts === right.allowScripts && left.allowSvgs === right.allowSvgs; -} - -export class HtmlInput extends ResourceEditorInput { - constructor( - name: string, - description: string, - resource: URI, - public readonly options: HtmlInputOptions, - @ITextModelService textModelResolverService: ITextModelService, - @IHashService hashService: IHashService - ) { - super(name, description, resource, textModelResolverService, hashService); - } -} diff --git a/src/vs/workbench/contrib/html/electron-browser/html.contribution.ts b/src/vs/workbench/contrib/html/electron-browser/html.contribution.ts deleted file mode 100644 index 693109a0624..00000000000 --- a/src/vs/workbench/contrib/html/electron-browser/html.contribution.ts +++ /dev/null @@ -1,81 +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 { URI } from 'vs/base/common/uri'; -import { localize } from 'vs/nls'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/shared/editor'; -import { HtmlInput, HtmlInputOptions } from '../common/htmlInput'; -import { HtmlPreviewPart } from './htmlPreviewPart'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; -import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; -import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; -import { registerWebViewCommands } from 'vs/workbench/contrib/webview/electron-browser/webview.contribution'; - -// --- Register Editor - -(Registry.as(EditorExtensions.Editors)).registerEditor(new EditorDescriptor( - HtmlPreviewPart, - HtmlPreviewPart.ID, - localize('html.editor.label', "Html Preview")), - [new SyncDescriptor(HtmlInput)]); - -// --- Register Commands - -CommandsRegistry.registerCommand('_workbench.previewHtml', function ( - accessor: ServicesAccessor, - resource: URI | string, - position?: EditorViewColumn, - label?: string -) { - const uri = resource instanceof URI ? resource : URI.parse(resource); - label = label || uri.fsPath; - - let input: HtmlInput | undefined; - - const editorGroupService = accessor.get(IEditorGroupsService); - - let targetGroup: IEditorGroup = editorGroupService.getGroup(viewColumnToEditorGroup(editorGroupService, position)); - if (!targetGroup) { - targetGroup = editorGroupService.activeGroup; - } - - // Find already opened HTML input if any - if (targetGroup) { - const editors = targetGroup.editors; - for (const editor of editors) { - const editorResource = editor.getResource(); - if (editor instanceof HtmlInput && editorResource && editorResource.toString() === resource.toString()) { - input = editor; - break; - } - } - } - - const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService); - - const inputOptions: HtmlInputOptions = { - allowScripts: true, - allowSvgs: true, - svgWhiteList: extensionsWorkbenchService.allowedBadgeProviders - }; - - // Otherwise, create new input and open it - if (!input) { - input = accessor.get(IInstantiationService).createInstance(HtmlInput, label, '', uri, inputOptions); - } else { - input.setName(label); // make sure to use passed in label - } - - return accessor.get(IEditorService) - .openEditor(input, { pinned: true }, viewColumnToEditorGroup(editorGroupService, position)) - .then(editor => true); -}); - -registerWebViewCommands(HtmlPreviewPart.ID); \ No newline at end of file diff --git a/src/vs/workbench/contrib/html/electron-browser/htmlPreviewPart.ts b/src/vs/workbench/contrib/html/electron-browser/htmlPreviewPart.ts deleted file mode 100644 index 8f86431edbb..00000000000 --- a/src/vs/workbench/contrib/html/electron-browser/htmlPreviewPart.ts +++ /dev/null @@ -1,256 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from 'vs/nls'; -import { Disposable, IDisposable, dispose, IReference } from 'vs/base/common/lifecycle'; -import { EditorOptions, EditorInput, IEditorMemento } from 'vs/workbench/common/editor'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; -import { HtmlInput, HtmlInputOptions, areHtmlInputOptionsEqual } from 'vs/workbench/contrib/html/common/htmlInput'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; -import { Parts, IPartService } from 'vs/workbench/services/part/common/partService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { Dimension } from 'vs/base/browser/dom'; -import { BaseWebviewEditor } from 'vs/workbench/contrib/webview/electron-browser/baseWebviewEditor'; -import { WebviewElement, WebviewContentOptions } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { Event, Emitter } from 'vs/base/common/event'; - -export interface HtmlPreviewEditorViewState { - scrollYPercentage: number; -} - -/** - * An implementation of editor for showing HTML content in an IFrame by leveraging the HTML input. - */ -export class HtmlPreviewPart extends BaseWebviewEditor { - - static readonly ID: string = 'workbench.editor.htmlPreviewPart'; - static class: string = 'htmlPreviewPart'; - - private _webviewDisposables: IDisposable[]; - - private _modelRef?: IReference; - public get model() { return this._modelRef ? this._modelRef.object.textEditorModel : undefined; } - private _modelChangeSubscription = Disposable.None; - private _themeChangeSubscription = Disposable.None; - - private _content: HTMLElement; - private _scrollYPercentage: number = 0; - - private editorMemento: IEditorMemento; - - private readonly _onDidFocusWebview = this._register(new Emitter()); - public get onDidFocus(): Event { return this._onDidFocusWebview.event; } - - constructor( - @ITelemetryService telemetryService: ITelemetryService, - @IThemeService themeService: IThemeService, - @IContextKeyService contextKeyService: IContextKeyService, - @IOpenerService private readonly _openerService: IOpenerService, - @IPartService private readonly _partService: IPartService, - @IStorageService readonly _storageService: IStorageService, - @ITextModelService private readonly _textModelResolverService: ITextModelService, - @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IEditorGroupsService readonly editorGroupService: IEditorGroupsService - ) { - super(HtmlPreviewPart.ID, telemetryService, themeService, contextKeyService, _storageService); - - this.editorMemento = this.getEditorMemento(editorGroupService, this.viewStateStorageKey); - } - - dispose(): void { - // remove from dom - this._webviewDisposables = dispose(this._webviewDisposables); - - // unhook listeners - this._themeChangeSubscription.dispose(); - this._modelChangeSubscription.dispose(); - - // dispose model ref - dispose(this._modelRef); - super.dispose(); - } - - protected createEditor(parent: HTMLElement): void { - this._content = document.createElement('div'); - this._content.style.position = 'absolute'; - this._content.classList.add(HtmlPreviewPart.class); - parent.appendChild(this._content); - } - - private get webview(): WebviewElement { - if (!this._webview) { - let webviewOptions: WebviewContentOptions = {}; - if (this.input && this.input instanceof HtmlInput) { - webviewOptions = this.input.options; - } - - this._webview = this._instantiationService.createInstance(WebviewElement, - this._partService.getContainer(Parts.EDITOR_PART), - { - useSameOriginForRoot: true - }, - webviewOptions); - this._webview.mountTo(this._content); - - if (this.input && this.input instanceof HtmlInput) { - const state = this.loadHTMLPreviewViewState(this.input); - this._scrollYPercentage = state ? state.scrollYPercentage : 0; - this.webview.initialScrollProgress = this._scrollYPercentage; - - const resourceUri = this.input.getResource(); - this.webview.baseUrl = resourceUri.toString(true); - } - this._webviewDisposables = [ - this._webview, - this._webview.onDidClickLink(uri => this._openerService.open(uri)), - this._webview.onDidScroll(data => { - this._scrollYPercentage = data.scrollYPercentage; - }), - ]; - - this._register(this._webview.onDidFocus(() => this._onDidFocusWebview.fire())); - } - return this._webview; - } - - protected setEditorVisible(visible: boolean, group: IEditorGroup): void { - this._doSetVisible(visible); - super.setEditorVisible(visible, group); - } - - private _doSetVisible(visible: boolean): void { - if (!visible) { - this._themeChangeSubscription.dispose(); - this._modelChangeSubscription.dispose(); - this._webviewDisposables = dispose(this._webviewDisposables); - this._webview = undefined; - } else { - this._themeChangeSubscription = this.themeService.onThemeChange(this.onThemeChange.bind(this)); - - if (this._hasValidModel()) { - this._modelChangeSubscription = this.model!.onDidChangeContent(() => this.webview.contents = this.model!.getLinesContent().join('\n')); - this.webview.contents = this.model!.getLinesContent().join('\n'); - } - } - } - - private _hasValidModel(): boolean { - return !!(this._modelRef && this.model && !this.model.isDisposed()); - } - - public layout(dimension: Dimension): void { - const { width, height } = dimension; - this._content.style.width = `${width}px`; - this._content.style.height = `${height}px`; - - super.layout(dimension); - } - - public clearInput(): void { - if (this.input instanceof HtmlInput) { - this.saveHTMLPreviewViewState(this.input, { - scrollYPercentage: this._scrollYPercentage - }); - } - dispose(this._modelRef); - this._modelRef = undefined; - super.clearInput(); - } - - protected saveState(): void { - if (this.input instanceof HtmlInput) { - this.saveHTMLPreviewViewState(this.input, { - scrollYPercentage: this._scrollYPercentage - }); - } - - super.saveState(); - } - - public sendMessage(data: any): void { - this.webview.sendMessage(data); - } - - public setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise { - - if (this.input && this.input.matches(input) && this._hasValidModel() && this.input instanceof HtmlInput && input instanceof HtmlInput && areHtmlInputOptionsEqual(this.input.options, input.options)) { - return Promise.resolve(undefined); - } - - let oldOptions: HtmlInputOptions | undefined = undefined; - - if (this.input instanceof HtmlInput) { - oldOptions = this.input.options; - this.saveHTMLPreviewViewState(this.input, { - scrollYPercentage: this._scrollYPercentage - }); - } - - if (this._modelRef) { - this._modelRef.dispose(); - } - this._modelChangeSubscription.dispose(); - - if (!(input instanceof HtmlInput)) { - return Promise.reject(new Error('Invalid input')); - } - - return super.setInput(input, options, token).then(() => { - const resourceUri = input.getResource(); - return this._textModelResolverService.createModelReference(resourceUri).then(ref => { - if (token.isCancellationRequested) { - return undefined; - } - - const model = ref.object; - if (model instanceof BaseTextEditorModel) { - this._modelRef = ref; - } - - if (!this.model) { - return Promise.reject(new Error(localize('html.voidInput', "Invalid editor input."))); - } - - if (oldOptions && !areHtmlInputOptionsEqual(oldOptions, input.options)) { - this._doSetVisible(false); - } - - this._modelChangeSubscription = this.model.onDidChangeContent(() => { - if (this.model) { - this._scrollYPercentage = 0; - this.webview.contents = this.model.getLinesContent().join('\n'); - } - }); - const state = this.loadHTMLPreviewViewState(input); - this._scrollYPercentage = state ? state.scrollYPercentage : 0; - this.webview.baseUrl = resourceUri.toString(true); - this.webview.options = input.options; - this.webview.contents = this.model.getLinesContent().join('\n'); - this.webview.initialScrollProgress = this._scrollYPercentage; - return undefined; - }); - }); - } - - - private get viewStateStorageKey(): string { - return this.getId() + '.editorViewState'; - } - - private saveHTMLPreviewViewState(input: HtmlInput, editorViewState: HtmlPreviewEditorViewState): void { - this.editorMemento.saveEditorState(this.group!, input, editorViewState); - } - - private loadHTMLPreviewViewState(input: HtmlInput): HtmlPreviewEditorViewState | undefined { - return this.editorMemento.loadEditorState(this.group!, input); - } -} diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 368fffe6423..cf08e9d08ee 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -98,9 +98,6 @@ import 'vs/workbench/contrib/markers/browser/markers.contribution'; // Comments import 'vs/workbench/contrib/comments/electron-browser/comments.contribution'; -// HTML Preview -import 'vs/workbench/contrib/html/electron-browser/html.contribution'; - // URL Support import 'vs/workbench/contrib/url/common/url.contribution'; From 09905893e616072578f8cb542d9fd50cca0986e0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 26 Feb 2019 17:22:09 -0800 Subject: [PATCH 050/290] Removing the baseWebviewEditor class This base class is no longer needed now that the html preview has been removed --- .../electron-browser/baseWebviewEditor.ts | 98 --------------- .../electron-browser/webview.contribution.ts | 3 +- .../electron-browser/webviewCommands.ts | 10 +- .../webview/electron-browser/webviewEditor.ts | 119 +++++++++++++----- 4 files changed, 96 insertions(+), 134 deletions(-) delete mode 100644 src/vs/workbench/contrib/webview/electron-browser/baseWebviewEditor.ts diff --git a/src/vs/workbench/contrib/webview/electron-browser/baseWebviewEditor.ts b/src/vs/workbench/contrib/webview/electron-browser/baseWebviewEditor.ts deleted file mode 100644 index 0851ec06807..00000000000 --- a/src/vs/workbench/contrib/webview/electron-browser/baseWebviewEditor.ts +++ /dev/null @@ -1,98 +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 { Dimension } from 'vs/base/browser/dom'; -import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; -import { WebviewElement } from './webviewElement'; -import { IStorageService } from 'vs/platform/storage/common/storage'; - -/** A context key that is set when the find widget in a webview is visible. */ -export const KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE = new RawContextKey('webviewFindWidgetVisible', false); - - -/** - * This class is only intended to be subclassed and not instantiated. - */ -export abstract class BaseWebviewEditor extends BaseEditor { - - protected _webview: WebviewElement | undefined; - protected findWidgetVisible: IContextKey; - - constructor( - id: string, - telemetryService: ITelemetryService, - themeService: IThemeService, - contextKeyService: IContextKeyService, - storageService: IStorageService - ) { - super(id, telemetryService, themeService, storageService); - if (contextKeyService) { - this.findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(contextKeyService); - } - } - - public showFind() { - if (this._webview) { - this._webview.showFind(); - this.findWidgetVisible.set(true); - } - } - - public hideFind() { - this.findWidgetVisible.reset(); - if (this._webview) { - this._webview.hideFind(); - } - } - - public get isWebviewEditor() { - return true; - } - - public reload() { - this.withWebviewElement(webview => webview.reload()); - } - - public layout(dimension: Dimension): void { - this.withWebviewElement(webview => webview.layout()); - } - - public focus(): void { - this.withWebviewElement(webview => webview.focus()); - } - - public selectAll(): void { - this.withWebviewElement(webview => webview.selectAll()); - } - - public copy(): void { - this.withWebviewElement(webview => webview.copy()); - } - - public paste(): void { - this.withWebviewElement(webview => webview.paste()); - } - - public cut(): void { - this.withWebviewElement(webview => webview.cut()); - } - - public undo(): void { - this.withWebviewElement(webview => webview.undo()); - } - - public redo(): void { - this.withWebviewElement(webview => webview.redo()); - } - - private withWebviewElement(f: (element: WebviewElement) => void): void { - if (this._webview) { - f(this._webview); - } - } -} diff --git a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts index 8e2b9e03bc0..484ff86a0c3 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts @@ -15,9 +15,8 @@ import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } fro import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; import { WebviewEditorInputFactory } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorInputFactory'; -import { KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from './baseWebviewEditor'; import { HideWebViewEditorFindCommand, OpenWebviewDeveloperToolsAction, ReloadWebviewAction, ShowWebViewEditorFindWidgetCommand, SelectAllWebviewEditorCommand, CopyWebviewEditorCommand, PasteWebviewEditorCommand, CutWebviewEditorCommand, UndoWebviewEditorCommand, RedoWebviewEditorCommand } from './webviewCommands'; -import { WebviewEditor } from './webviewEditor'; +import { WebviewEditor, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from './webviewEditor'; import { WebviewEditorInput } from './webviewEditorInput'; import { IWebviewEditorService, WebviewEditorService } from './webviewEditorService'; import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts index b91a3fa1224..ff62950a517 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts @@ -8,7 +8,7 @@ import { Command } from 'vs/editor/browser/editorExtensions'; import * as nls from 'vs/nls'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { BaseWebviewEditor } from './baseWebviewEditor'; +import { WebviewEditor } from 'vs/workbench/contrib/webview/electron-browser/webviewEditor'; export class ShowWebViewEditorFindWidgetCommand extends Command { public static readonly ID = 'editor.action.webvieweditor.showFind'; @@ -143,13 +143,13 @@ export class ReloadWebviewAction extends Action { private getVisibleWebviews() { return this.editorService.visibleControls - .filter(control => control && (control as BaseWebviewEditor).isWebviewEditor) - .map(control => control as BaseWebviewEditor); + .filter(control => control && (control as WebviewEditor).isWebviewEditor) + .map(control => control as WebviewEditor); } } -function getActiveWebviewEditor(accessor: ServicesAccessor): BaseWebviewEditor | null { +function getActiveWebviewEditor(accessor: ServicesAccessor): WebviewEditor | null { const editorService = accessor.get(IEditorService); - const activeControl = editorService.activeControl as BaseWebviewEditor; + const activeControl = editorService.activeControl as WebviewEditor; return activeControl.isWebviewEditor ? activeControl : null; } \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditor.ts index b004ebbd6ea..344124376ef 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditor.ts @@ -6,24 +6,31 @@ import * as DOM from 'vs/base/browser/dom'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IWindowService } from 'vs/platform/windows/common/windows'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions } from 'vs/workbench/common/editor'; import { WebviewEditorInput } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorInput'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; -import { BaseWebviewEditor, KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE } from './baseWebviewEditor'; import { WebviewElement } from './webviewElement'; -import { IWindowService } from 'vs/platform/windows/common/windows'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -export class WebviewEditor extends BaseWebviewEditor { +/** A context key that is set when the find widget in a webview is visible. */ +export const KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE = new RawContextKey('webviewFindWidgetVisible', false); + + +export class WebviewEditor extends BaseEditor { + + protected _webview: WebviewElement | undefined; + protected findWidgetVisible: IContextKey; public static readonly ID = 'WebviewEditor'; @@ -50,7 +57,10 @@ export class WebviewEditor extends BaseWebviewEditor { @IWindowService private readonly _windowService: IWindowService, @IStorageService storageService: IStorageService ) { - super(WebviewEditor.ID, telemetryService, themeService, _contextKeyService, storageService); + super(WebviewEditor.ID, telemetryService, themeService, storageService); + if (_contextKeyService) { + this.findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(_contextKeyService); + } } protected createEditor(parent: HTMLElement): void { @@ -73,27 +83,6 @@ export class WebviewEditor extends BaseWebviewEditor { } } - public layout(dimension: DOM.Dimension): void { - if (this._webview) { - this.doUpdateContainer(); - } - super.layout(dimension); - } - - public focus() { - super.focus(); - if (this._onFocusWindowHandler) { - return; - } - - // Make sure we restore focus when switching back to a VS Code window - this._onFocusWindowHandler = this._windowService.onDidChangeFocus(focused => { - if (focused && this._editorService.activeControl === this) { - this.focus(); - } - }); - } - public dispose(): void { this.pendingMessages = []; @@ -122,6 +111,78 @@ export class WebviewEditor extends BaseWebviewEditor { this.pendingMessages.push(data); } } + public showFind() { + if (this._webview) { + this._webview.showFind(); + this.findWidgetVisible.set(true); + } + } + + public hideFind() { + this.findWidgetVisible.reset(); + if (this._webview) { + this._webview.hideFind(); + } + } + + public get isWebviewEditor() { + return true; + } + + public reload() { + this.withWebviewElement(webview => webview.reload()); + } + + public layout(_dimension: DOM.Dimension): void { + this.withWebviewElement(webview => { + this.doUpdateContainer(); + webview.layout(); + }); + } + + public focus(): void { + super.focus(); + if (!this._onFocusWindowHandler) { + + // Make sure we restore focus when switching back to a VS Code window + this._onFocusWindowHandler = this._windowService.onDidChangeFocus(focused => { + if (focused && this._editorService.activeControl === this) { + this.focus(); + } + }); + } + this.withWebviewElement(webview => webview.focus()); + } + + public selectAll(): void { + this.withWebviewElement(webview => webview.selectAll()); + } + + public copy(): void { + this.withWebviewElement(webview => webview.copy()); + } + + public paste(): void { + this.withWebviewElement(webview => webview.paste()); + } + + public cut(): void { + this.withWebviewElement(webview => webview.cut()); + } + + public undo(): void { + this.withWebviewElement(webview => webview.undo()); + } + + public redo(): void { + this.withWebviewElement(webview => webview.redo()); + } + + private withWebviewElement(f: (element: WebviewElement) => void): void { + if (this._webview) { + f(this._webview); + } + } protected setEditorVisible(visible: boolean, group: IEditorGroup): void { if (this.input && this.input instanceof WebviewEditorInput) { From c7bf51034b8791bd5ad47f10906aace5c08e8976 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Feb 2019 11:47:56 -0800 Subject: [PATCH 051/290] Take uri as argument instead of string version of uri --- .../node/extHostDocumentContentProviders.ts | 4 ++-- src/vs/workbench/api/node/extHostDocuments.ts | 18 +++++++----------- .../api/node/extHostDocumentsAndEditors.ts | 4 ++-- .../api/node/extHostTypeConverters.ts | 2 +- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/api/node/extHostDocumentContentProviders.ts b/src/vs/workbench/api/node/extHostDocumentContentProviders.ts index 89c7332e1b1..3ffd9a81fda 100644 --- a/src/vs/workbench/api/node/extHostDocumentContentProviders.ts +++ b/src/vs/workbench/api/node/extHostDocumentContentProviders.ts @@ -52,13 +52,13 @@ export class ExtHostDocumentContentProvider implements ExtHostDocumentContentPro this._logService.warn(`Provider for scheme '${scheme}' is firing event for schema '${uri.scheme}' which will be IGNORED`); return; } - if (this._documentsAndEditors.getDocument(uri.toString())) { + if (this._documentsAndEditors.getDocument(uri)) { this.$provideTextDocumentContent(handle, uri).then(value => { if (!value) { return; } - const document = this._documentsAndEditors.getDocument(uri.toString()); + const document = this._documentsAndEditors.getDocument(uri); if (!document) { // disposed in the meantime return; diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index dfc39581f84..a053696d1cf 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -60,7 +60,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { if (!resource) { return undefined; } - const data = this._documentsAndEditors.getDocument(resource.toString()); + const data = this._documentsAndEditors.getDocument(resource); if (data) { return data; } @@ -77,7 +77,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public ensureDocumentData(uri: URI): Promise { - let cached = this._documentsAndEditors.getDocument(uri.toString()); + let cached = this._documentsAndEditors.getDocument(uri); if (cached) { return Promise.resolve(cached); } @@ -86,7 +86,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { if (!promise) { promise = this._proxy.$tryOpenDocument(uri).then(() => { this._documentLoader.delete(uri.toString()); - return this._documentsAndEditors.getDocument(uri.toString()); + return this._documentsAndEditors.getDocument(uri); }, err => { this._documentLoader.delete(uri.toString()); return Promise.reject(err); @@ -103,8 +103,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public $acceptModelModeChanged(uriComponents: UriComponents, oldModeId: string, newModeId: string): void { const uri = URI.revive(uriComponents); - const strURL = uri.toString(); - let data = this._documentsAndEditors.getDocument(strURL); + let data = this._documentsAndEditors.getDocument(uri); // Treat a mode change as a remove + add @@ -115,16 +114,14 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public $acceptModelSaved(uriComponents: UriComponents): void { const uri = URI.revive(uriComponents); - const strURL = uri.toString(); - let data = this._documentsAndEditors.getDocument(strURL); + let data = this._documentsAndEditors.getDocument(uri); this.$acceptDirtyStateChanged(uriComponents, false); this._onDidSaveDocument.fire(data.document); } public $acceptDirtyStateChanged(uriComponents: UriComponents, isDirty: boolean): void { const uri = URI.revive(uriComponents); - const strURL = uri.toString(); - let data = this._documentsAndEditors.getDocument(strURL); + let data = this._documentsAndEditors.getDocument(uri); data._acceptIsDirty(isDirty); this._onDidChangeDocument.fire({ document: data.document, @@ -134,8 +131,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public $acceptModelChanged(uriComponents: UriComponents, events: IModelChangedEvent, isDirty: boolean): void { const uri = URI.revive(uriComponents); - const strURL = uri.toString(); - let data = this._documentsAndEditors.getDocument(strURL); + let data = this._documentsAndEditors.getDocument(uri); data._acceptIsDirty(isDirty); data.onEvents(events); this._onDidChangeDocument.fire({ diff --git a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts index 4048e3a936b..0455b24ecbf 100644 --- a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts @@ -131,8 +131,8 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha } } - getDocument(strUrl: string): ExtHostDocumentData { - return this._documents.get(strUrl); + getDocument(uri: URI): ExtHostDocumentData { + return this._documents.get(uri.toString()); } allDocuments(): ExtHostDocumentData[] { diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index a445750d59d..54006bf3829 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -457,7 +457,7 @@ export namespace WorkspaceEdit { const [uri, uriOrEdits] = entry; if (Array.isArray(uriOrEdits)) { // text edits - const doc = documents && uri ? documents.getDocument(uri.toString()) : undefined; + const doc = documents && uri ? documents.getDocument(uri) : undefined; result.edits.push({ resource: uri, modelVersionId: doc && doc.version, edits: uriOrEdits.map(TextEdit.from) }); } else { // resource edits From 4516dd8ce62e2f3f45546d9287ebc5c5518fbbfd Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Feb 2019 16:50:51 -0800 Subject: [PATCH 052/290] Make sure we properly set _visible This value was previously always false --- src/vs/editor/contrib/codeAction/codeActionWidget.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/editor/contrib/codeAction/codeActionWidget.ts b/src/vs/editor/contrib/codeAction/codeActionWidget.ts index c1968825103..9e543cb08ac 100644 --- a/src/vs/editor/contrib/codeAction/codeActionWidget.ts +++ b/src/vs/editor/contrib/codeAction/codeActionWidget.ts @@ -32,6 +32,7 @@ export class CodeActionContextMenu { // cancel when editor went off-dom return Promise.reject(canceled()); } + this._visible = true; const actions = codeActions.map(action => this.codeActionToAction(action)); this._contextMenuService.showContextMenu({ getAnchor: () => { From f62d1f25f3ef410dd2ba0ecc1f83d4c4c3b8c88a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 27 Feb 2019 18:28:24 -0800 Subject: [PATCH 053/290] Only show the markdown refresh preview command when preview is active or you are in a markdown file --- extensions/markdown-language-features/package.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 9dd958c29c9..10431185034 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -153,6 +153,14 @@ { "command": "markdown.preview.toggleLock", "when": "markdownPreviewFocus" + }, + { + "command": "markdown.preview.refresh", + "when": "editorLangId == markdown" + }, + { + "command": "markdown.preview.refresh", + "when": "markdownPreviewFocus" } ] }, @@ -315,4 +323,4 @@ "webpack": "^4.1.0", "webpack-cli": "^2.0.10" } -} +} \ No newline at end of file From e30008eb4a12761abb7b164ac285b16e8b802273 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 28 Feb 2019 15:54:37 -0800 Subject: [PATCH 054/290] Leave determining which webviews a reviver supports entirely up to that reviver Don't key off of `viewType` first, let the reviver decide --- .../api/electron-browser/mainThreadWebview.ts | 4 +-- .../electron-browser/webviewEditorService.ts | 36 +++++++------------ 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index 2e056e31d90..2f4502f7a3c 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -62,7 +62,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv _editorService.onDidActiveEditorChange(this.onActiveEditorChanged, this, this._toDispose); _editorService.onDidVisibleEditorsChange(this.onVisibleEditorsChanged, this, this._toDispose); - this._toDispose.push(_webviewService.registerReviver(MainThreadWebviews.viewType, this)); + this._toDispose.push(_webviewService.registerReviver(this)); lifecycleService.onBeforeShutdown(e => { e.veto(this._onBeforeShutdown()); @@ -242,7 +242,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv } public canRevive(webview: WebviewEditorInput): boolean { - if (webview.isDisposed() || !webview.state) { + if (webview.isDisposed() || !webview.state || webview.viewType !== MainThreadWebviews.viewType) { return false; } diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts index c1d9d940bed..8c71b32bf72 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts @@ -49,7 +49,6 @@ export interface IWebviewEditorService { ): void; registerReviver( - viewType: string, reviver: WebviewReviver ): IDisposable; @@ -90,7 +89,7 @@ export function areWebviewInputOptionsEqual(a: WebviewInputOptions, b: WebviewIn export class WebviewEditorService implements IWebviewEditorService { _serviceBrand: any; - private readonly _revivers = new Map(); + private readonly _revivers = new Set(); private _awaitingRevival: { input: WebviewEditorInput, resolve: (x: any) => void }[] = []; constructor( @@ -135,7 +134,7 @@ export class WebviewEditorService implements IWebviewEditorService { ): WebviewEditorInput { const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, { canRevive: (_webview) => { - return true; + return _webview === webviewInput; }, reviveWebview: (webview: WebviewEditorInput): Promise => { return this.tryRevive(webview).then(didRevive => { @@ -156,47 +155,38 @@ export class WebviewEditorService implements IWebviewEditorService { } registerReviver( - viewType: string, reviver: WebviewReviver ): IDisposable { - const currentRevivers = this._revivers.get(viewType); - if (currentRevivers) { - currentRevivers.push(reviver); - } else { - this._revivers.set(viewType, [reviver]); - } - + this._revivers.add(reviver); // Resolve any pending views - const toRevive = this._awaitingRevival.filter(x => x.input.viewType === viewType); - this._awaitingRevival = this._awaitingRevival.filter(x => x.input.viewType !== viewType); + const toRevive = this._awaitingRevival.filter(x => reviver.canRevive(x.input)); + this._awaitingRevival = this._awaitingRevival.filter(x => !reviver.canRevive(x.input)); for (const input of toRevive) { reviver.reviveWebview(input.input).then(() => input.resolve(undefined)); } return toDisposable(() => { - this._revivers.delete(viewType); + this._revivers.delete(reviver); }); } canRevive( webview: WebviewEditorInput ): boolean { - const viewType = webview.viewType; - const revivers = this._revivers.get(viewType); - return !!revivers && revivers.some(reviver => reviver.canRevive(webview)); + for (const reviver of this._revivers) { + if (reviver.canRevive(webview)) { + return true; + } + } + return false; } private async tryRevive( webview: WebviewEditorInput ): Promise { - const revivers = this._revivers.get(webview.viewType); - if (!revivers) { - return false; - } - - for (const reviver of revivers) { + for (const reviver of this._revivers) { if (reviver.canRevive(webview)) { await reviver.reviveWebview(webview); return true; From 98c084ff4a74a4162319f505c259f578114c2000 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 28 Feb 2019 16:01:27 -0800 Subject: [PATCH 055/290] Don't re-use reviver interface where it not needed --- .../electron-browser/webviewEditorInput.ts | 6 ++--- .../electron-browser/webviewEditorService.ts | 27 ++++++++----------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts index 5e9c6243e94..caa44a7d943 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts @@ -10,7 +10,7 @@ import { IEditorModel } from 'vs/platform/editor/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 { WebviewEvents, WebviewInputOptions } from './webviewEditorService'; import { WebviewElement } from './webviewElement'; export class WebviewEditorInput extends EditorInput { @@ -77,7 +77,7 @@ export class WebviewEditorInput extends EditorInput { state: any, events: WebviewEvents, extensionLocation: URI | undefined, - public readonly reviver: WebviewReviver | undefined, + public readonly reviver: (input: WebviewEditorInput) => Promise | undefined, @IPartService private readonly _partService: IPartService, ) { super(); @@ -215,7 +215,7 @@ export class WebviewEditorInput extends EditorInput { public resolve(): Promise { if (this.reviver && !this._revived) { this._revived = true; - return this.reviver.reviveWebview(this).then(() => new EditorModel()); + return this.reviver(this).then(() => new EditorModel()); } return Promise.resolve(new EditorModel()); } diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts index 8c71b32bf72..5e68af23090 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts @@ -132,23 +132,18 @@ export class WebviewEditorService implements IWebviewEditorService { options: WebviewInputOptions, extensionLocation: URI ): WebviewEditorInput { - const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, { - canRevive: (_webview) => { - return _webview === webviewInput; - }, - reviveWebview: (webview: WebviewEditorInput): Promise => { - return this.tryRevive(webview).then(didRevive => { - if (didRevive) { - return Promise.resolve(undefined); - } + const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, (webview: WebviewEditorInput): Promise => { + return this.tryRevive(webview).then(didRevive => { + if (didRevive) { + return Promise.resolve(undefined); + } - // A reviver may not be registered yet. Put into queue and resolve promise when we can revive - let resolve: (value: void) => void; - const promise = new Promise(r => { resolve = r; }); - this._awaitingRevival.push({ input: webview, resolve: resolve! }); - return promise; - }); - } + // A reviver may not be registered yet. Put into queue and resolve promise when we can revive + let resolve: (value: void) => void; + const promise = new Promise(r => { resolve = r; }); + this._awaitingRevival.push({ input: webview, resolve: resolve! }); + return promise; + }); }); webviewInput.iconPath = iconPath; return webviewInput; From 904e426052a5ac50390ad79cd8a98f442c6c7418 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 28 Feb 2019 17:19:33 -0800 Subject: [PATCH 056/290] Introduce RevivedWebviewEditorInput --- .../api/electron-browser/mainThreadWebview.ts | 4 +-- .../electron-browser/webviewEditorInput.ts | 34 +++++++++++++++---- .../webviewEditorInputFactory.ts | 4 +-- .../electron-browser/webviewEditorService.ts | 23 ++++++------- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts index 2f4502f7a3c..1ccd47f9ff3 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWebview.ts @@ -11,7 +11,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions, WebviewInsetHandle } from 'vs/workbench/api/node/extHost.protocol'; import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/shared/editor'; import { WebviewEditor } from 'vs/workbench/contrib/webview/electron-browser/webviewEditor'; -import { WebviewEditorInput } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorInput'; +import { WebviewEditorInput, RevivedWebviewEditorInput } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorInput'; import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions, WebviewReviver } from 'vs/workbench/contrib/webview/electron-browser/webviewEditorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -246,7 +246,7 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv return false; } - return this._revivers.has(webview.state.viewType) || !!webview.reviver; + return this._revivers.has(webview.state.viewType) || !!(webview as RevivedWebviewEditorInput).reviver; } private _onBeforeShutdown(): boolean { diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts index caa44a7d943..3173942bff3 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInput.ts @@ -64,8 +64,6 @@ export class WebviewEditorInput extends EditorInput { private _scrollYPercentage: number = 0; private _state: any; - private _revived: boolean = false; - public readonly extensionLocation: URI | undefined; private readonly _id: number; @@ -77,7 +75,6 @@ export class WebviewEditorInput extends EditorInput { state: any, events: WebviewEvents, extensionLocation: URI | undefined, - public readonly reviver: (input: WebviewEditorInput) => Promise | undefined, @IPartService private readonly _partService: IPartService, ) { super(); @@ -213,10 +210,6 @@ export class WebviewEditorInput extends EditorInput { } public resolve(): Promise { - if (this.reviver && !this._revived) { - this._revived = true; - return this.reviver(this).then(() => new EditorModel()); - } return Promise.resolve(new EditorModel()); } @@ -310,3 +303,30 @@ export class WebviewEditorInput extends EditorInput { this._group = group; } } + + +export class RevivedWebviewEditorInput extends WebviewEditorInput { + private _revived: boolean = false; + + constructor( + viewType: string, + id: number | undefined, + name: string, + options: WebviewInputOptions, + state: any, + events: WebviewEvents, + extensionLocation: URI | undefined, + public readonly reviver: (input: WebviewEditorInput) => Promise, + @IPartService partService: IPartService, + ) { + super(viewType, id, name, options, state, events, extensionLocation, partService); + } + + public async resolve(): Promise { + if (!this._revived) { + this._revived = true; + await this.reviver(this); + } + return super.resolve(); + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInputFactory.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInputFactory.ts index e46bac47814..26247da337e 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInputFactory.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorInputFactory.ts @@ -5,7 +5,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IEditorInputFactory } from 'vs/workbench/common/editor'; -import { WebviewEditorInput } from './webviewEditorInput'; +import { WebviewEditorInput, RevivedWebviewEditorInput } from './webviewEditorInput'; import { IWebviewEditorService, WebviewInputOptions } from './webviewEditorService'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -41,7 +41,7 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { } // Only attempt revival if we may have a reviver - if (!this._webviewService.canRevive(input) && !input.reviver) { + if (!this._webviewService.canRevive(input) && !(input instanceof RevivedWebviewEditorInput)) { return null; } diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts index 5e68af23090..234d1a1bcad 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts @@ -9,7 +9,7 @@ import { IInstantiationService, createDecorator } from 'vs/platform/instantiatio import { IEditorService, ACTIVE_GROUP_TYPE, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import * as vscode from 'vscode'; -import { WebviewEditorInput } from './webviewEditorInput'; +import { WebviewEditorInput, RevivedWebviewEditorInput } from './webviewEditorInput'; import { GroupIdentifier } from 'vs/workbench/common/editor'; import { equals } from 'vs/base/common/arrays'; @@ -132,18 +132,17 @@ export class WebviewEditorService implements IWebviewEditorService { options: WebviewInputOptions, extensionLocation: URI ): WebviewEditorInput { - const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, (webview: WebviewEditorInput): Promise => { - return this.tryRevive(webview).then(didRevive => { - if (didRevive) { - return Promise.resolve(undefined); - } + const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, async (webview: WebviewEditorInput): Promise => { + const didRevive = await this.tryRevive(webview); + if (didRevive) { + return Promise.resolve(undefined); + } - // A reviver may not be registered yet. Put into queue and resolve promise when we can revive - let resolve: (value: void) => void; - const promise = new Promise(r => { resolve = r; }); - this._awaitingRevival.push({ input: webview, resolve: resolve! }); - return promise; - }); + // A reviver may not be registered yet. Put into queue and resolve promise when we can revive + let resolve: () => void; + const promise = new Promise(r => { resolve = r; }); + this._awaitingRevival.push({ input: webview, resolve: resolve! }); + return promise; }); webviewInput.iconPath = iconPath; return webviewInput; From 82c3b30e39b05e433224c4c408da62432f007b43 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 28 Feb 2019 17:33:29 -0800 Subject: [PATCH 057/290] Don't hold on to themeService member --- .../contrib/webview/electron-browser/webviewElement.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 5a287448892..70b14883b23 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -235,7 +235,7 @@ export class WebviewElement extends Disposable { private readonly _options: WebviewOptions, private _contentOptions: WebviewContentOptions, @IInstantiationService instantiationService: IInstantiationService, - @IThemeService private readonly _themeService: IThemeService, + @IThemeService themeService: IThemeService, @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService ) { @@ -347,8 +347,8 @@ export class WebviewElement extends Disposable { this._webviewFindWidget = this._register(instantiationService.createInstance(WebviewFindWidget, this)); } - this.style(this._themeService.getTheme()); - this._register(this._themeService.onThemeChange(this.style, this)); + this.style(themeService.getTheme()); + themeService.onThemeChange(this.style, this, this._toDispose); } public mountTo(parent: HTMLElement) { From 5dfc7f62cf17f30f887d68a5d9a240bb3549881a Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Thu, 28 Feb 2019 11:27:48 +0100 Subject: [PATCH 058/290] Add support for async worker creation --- src/vs/base/worker/defaultWorkerFactory.ts | 37 +++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/vs/base/worker/defaultWorkerFactory.ts b/src/vs/base/worker/defaultWorkerFactory.ts index 30ad9bf632f..b252db4be2e 100644 --- a/src/vs/base/worker/defaultWorkerFactory.ts +++ b/src/vs/base/worker/defaultWorkerFactory.ts @@ -6,7 +6,7 @@ import { globals } from 'vs/base/common/platform'; import { IWorker, IWorkerCallback, IWorkerFactory, logOnceWebWorkerWarning } from 'vs/base/common/worker/simpleWorker'; -function getWorker(workerId: string, label: string): Worker { +function getWorker(workerId: string, label: string): Worker | Promise { // Option for hosts to overwrite the worker script (used in the standalone editor) if (globals.MonacoEnvironment) { if (typeof globals.MonacoEnvironment.getWorker === 'function') { @@ -24,6 +24,13 @@ function getWorker(workerId: string, label: string): Worker { throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`); } +function isPromiseLike(obj: any): obj is PromiseLike { + if (typeof obj.then === 'function') { + return true; + } + return false; +} + /** * A worker that uses HTML5 web workers so that is has * its own global scope and its own thread. @@ -31,18 +38,26 @@ function getWorker(workerId: string, label: string): Worker { class WebWorker implements IWorker { private id: number; - private worker: Worker | null; + private worker: Promise | null; constructor(moduleId: string, id: number, label: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void) { this.id = id; - this.worker = getWorker('workerMain.js', label); - this.postMessage(moduleId); - this.worker.onmessage = function (ev: any) { - onMessageCallback(ev.data); - }; - if (typeof this.worker.addEventListener === 'function') { - this.worker.addEventListener('error', onErrorCallback); + const workerOrPromise = getWorker('workerMain.js', label); + if (isPromiseLike(workerOrPromise)) { + this.worker = workerOrPromise; + } else { + this.worker = Promise.resolve(workerOrPromise); } + this.postMessage(moduleId); + this.worker.then((w) => { + w.onmessage = function (ev: any) { + onMessageCallback(ev.data); + }; + (w).onmessageerror = onErrorCallback; + if (typeof w.addEventListener === 'function') { + w.addEventListener('error', onErrorCallback); + } + }); } public getId(): number { @@ -51,13 +66,13 @@ class WebWorker implements IWorker { public postMessage(msg: string): void { if (this.worker) { - this.worker.postMessage(msg); + this.worker.then(w => w.postMessage(msg)); } } public dispose(): void { if (this.worker) { - this.worker.terminate(); + this.worker.then(w => w.terminate()); } this.worker = null; } From c1ec8af28fa465151e24e28866569fb7a5351c02 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 1 Mar 2019 13:32:28 +0100 Subject: [PATCH 059/290] Add workaround for regular expression leading to Syntax Error (#69655) --- src/vs/base/browser/ui/menu/menu.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index 47da5e42776..26d89db30a2 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -20,8 +20,22 @@ import { Event, Emitter } from 'vs/base/common/event'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { isLinux } from 'vs/base/common/platform'; -export const MENU_MNEMONIC_REGEX: RegExp = /\(&([^\s&])\)|(? Date: Fri, 1 Mar 2019 13:33:32 +0100 Subject: [PATCH 060/290] Add built-in support for cross-origin web worker loading --- src/vs/base/worker/defaultWorkerFactory.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vs/base/worker/defaultWorkerFactory.ts b/src/vs/base/worker/defaultWorkerFactory.ts index b252db4be2e..eccaa81f139 100644 --- a/src/vs/base/worker/defaultWorkerFactory.ts +++ b/src/vs/base/worker/defaultWorkerFactory.ts @@ -18,7 +18,22 @@ function getWorker(workerId: string, label: string): Worker | Promise { } // ESM-comment-begin if (typeof require === 'function') { - return new Worker(require.toUrl('./' + workerId) + '#' + label); + // check if the JS lives on a different origin + + const workerMain = require.toUrl('./' + workerId); + if (/^(http:)|(https:)|(file:)/.test(workerMain)) { + const currentUrl = String(window.location); + const currentOrigin = currentUrl.substr(0, currentUrl.length - window.location.hash.length - window.location.search.length - window.location.pathname.length); + if (workerMain.substring(0, currentOrigin.length) !== currentOrigin) { + // this is the cross-origin case + // i.e. the webpage is running at a different origin than where the scripts are loaded from + const workerBaseUrl = workerMain.substr(0, workerMain.length - 'vs/base/worker/workerMain.js'.length); + const js = `/*${label}*/self.MonacoEnvironment={baseUrl: '${workerBaseUrl}'};importScripts('${workerMain}');/*${label}*/`; + const url = `data:text/javascript;charset=utf-8,${encodeURIComponent(js)}`; + return new Worker(url); + } + } + return new Worker(workerMain + '#' + label); } // ESM-comment-end throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`); From 07a671b2d0aee8ac761538f5c74a0fb05433babf Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 1 Mar 2019 13:34:14 +0100 Subject: [PATCH 061/290] Avoid console log error messages in the standalone editor --- src/vs/editor/contrib/folding/folding.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index d85f6bfbc75..e8393a98ce2 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -279,6 +279,9 @@ export class FoldingController implements IEditorContribution { } return foldingModel; }); + }).then(undefined, (err) => { + onUnexpectedError(err); + return null; }); } } From f18704818733145b21a139dc47d005718b1ee83c Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 1 Mar 2019 20:05:24 +0100 Subject: [PATCH 062/290] Fixes Microsoft/monaco-editor#1319: Listen to selectionchange listener only when focused --- .../browser/controller/textAreaInput.ts | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/browser/controller/textAreaInput.ts b/src/vs/editor/browser/controller/textAreaInput.ts index 7ccf0e99d29..bc986faeb6f 100644 --- a/src/vs/editor/browser/controller/textAreaInput.ts +++ b/src/vs/editor/browser/controller/textAreaInput.ts @@ -10,7 +10,7 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { RunOnceScheduler } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; import { ITextAreaWrapper, ITypeData, TextAreaState } from 'vs/editor/browser/controller/textAreaState'; @@ -105,6 +105,7 @@ export class TextAreaInput extends Disposable { private readonly _asyncTriggerCut: RunOnceScheduler; private _textAreaState: TextAreaState; + private _selectionChangeListener: IDisposable | null; private _hasFocus: boolean; private _isDoingComposition: boolean; @@ -330,8 +331,9 @@ export class TextAreaInput extends Disposable { this._lastTextAreaEvent = TextAreaInputEventType.blur; this._setHasFocus(false); })); + } - + private _installSelectionChangeListener(): IDisposable { // See https://github.com/Microsoft/vscode/issues/27216 // When using a Braille display, it is possible for users to reposition the // system caret. This is reflected in Chrome as a `selectionchange` event. @@ -351,7 +353,7 @@ export class TextAreaInput extends Disposable { // `selectionchange` events often come multiple times for a single logical change // so throttle multiple `selectionchange` events that burst in a short period of time. let previousSelectionChangeEventTime = 0; - this._register(dom.addDisposableListener(document, 'selectionchange', (e) => { + return dom.addDisposableListener(document, 'selectionchange', (e) => { if (!this._hasFocus) { return; } @@ -411,11 +413,15 @@ export class TextAreaInput extends Disposable { ); this._onSelectionChangeRequest.fire(newSelection); - })); + }); } public dispose(): void { super.dispose(); + if (this._selectionChangeListener) { + this._selectionChangeListener.dispose(); + this._selectionChangeListener = null; + } } public focusTextArea(): void { @@ -435,6 +441,14 @@ export class TextAreaInput extends Disposable { } this._hasFocus = newHasFocus; + if (this._selectionChangeListener) { + this._selectionChangeListener.dispose(); + this._selectionChangeListener = null; + } + if (this._hasFocus) { + this._selectionChangeListener = this._installSelectionChangeListener(); + } + if (this._hasFocus) { if (browser.isEdge) { // Edge has a bug where setting the selection range while the focus event From 5698d79117a1d2db448503bd265c1aa679f59eb5 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 1 Mar 2019 20:46:33 +0100 Subject: [PATCH 063/290] Fixes Microsoft/monaco-editor#1335 --- src/vs/editor/common/modes/supports/tokenization.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/common/modes/supports/tokenization.ts b/src/vs/editor/common/modes/supports/tokenization.ts index e58c791f60b..d245a41fb89 100644 --- a/src/vs/editor/common/modes/supports/tokenization.ts +++ b/src/vs/editor/common/modes/supports/tokenization.ts @@ -240,7 +240,7 @@ export class TokenTheme { } } -const STANDARD_TOKEN_TYPE_REGEXP = /\b(comment|string|regex)\b/; +const STANDARD_TOKEN_TYPE_REGEXP = /\b(comment|string|regex|regexp)\b/; export function toStandardTokenType(tokenType: string): StandardTokenType { let m = tokenType.match(STANDARD_TOKEN_TYPE_REGEXP); if (!m) { @@ -253,6 +253,8 @@ export function toStandardTokenType(tokenType: string): StandardTokenType { return StandardTokenType.String; case 'regex': return StandardTokenType.RegEx; + case 'regexp': + return StandardTokenType.RegEx; } throw new Error('Unexpected match for standard token type!'); } From f2536728d3ef013c7e4512d8901d9487930e1038 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 1 Mar 2019 23:15:02 +0100 Subject: [PATCH 064/290] Add monaco.editor.remeasureFonts (Microsoft/monaco-editor#392) --- src/vs/editor/browser/config/configuration.ts | 9 +++++++++ src/vs/editor/standalone/browser/standaloneEditor.ts | 9 +++++++++ src/vs/monaco.d.ts | 5 +++++ 3 files changed, 23 insertions(+) diff --git a/src/vs/editor/browser/config/configuration.ts b/src/vs/editor/browser/config/configuration.ts index f4a579bc8ce..32e87b2a794 100644 --- a/src/vs/editor/browser/config/configuration.ts +++ b/src/vs/editor/browser/config/configuration.ts @@ -54,6 +54,10 @@ class CSSBasedConfigurationCache { } } +export function clearAllFontInfos(): void { + CSSBasedConfiguration.INSTANCE.clearCache(); +} + export function readFontInfo(bareFontInfo: BareFontInfo): FontInfo { return CSSBasedConfiguration.INSTANCE.readConfiguration(bareFontInfo); } @@ -122,6 +126,11 @@ class CSSBasedConfiguration extends Disposable { super.dispose(); } + public clearCache(): void { + this._cache = new CSSBasedConfigurationCache(); + this._onDidChange.fire(); + } + private _writeToCache(item: BareFontInfo, value: FontInfo): void { this._cache.put(item, value); diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index bd5660f51e4..09d4b4bce46 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -37,6 +37,7 @@ import { IMarker, IMarkerData } from 'vs/platform/markers/common/markers'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { clearAllFontInfos } from 'vs/editor/browser/config/configuration'; type Omit = Pick>; @@ -311,6 +312,13 @@ export function setTheme(themeName: string): void { StaticServices.standaloneThemeService.get().setTheme(themeName); } +/** + * Clears all cached font measurements and triggers re-measurement. + */ +export function remeasureFonts(): void { + clearAllFontInfos(); +} + /** * @internal */ @@ -340,6 +348,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { tokenize: tokenize, defineTheme: defineTheme, setTheme: setTheme, + remeasureFonts: remeasureFonts, // enums ScrollbarVisibility: standaloneEnums.ScrollbarVisibility, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 8084ebff346..cf24813d108 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -923,6 +923,11 @@ declare namespace monaco.editor { */ export function setTheme(themeName: string): void; + /** + * Clears all cached font measurements and triggers re-measurement. + */ + export function remeasureFonts(): void; + export type BuiltinTheme = 'vs' | 'vs-dark' | 'hc-black'; export interface IStandaloneThemeData { From e4300018d215cdc8dd0ba7b29f4c1be8f377889b Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 00:42:49 +0100 Subject: [PATCH 065/290] Allow to register a tokenizer promise and honor tokenizer promises when dealing with embedded modes in colorizing API --- src/vs/editor/standalone/browser/colorizer.ts | 23 +++++++++-- .../standalone/browser/standaloneLanguages.ts | 38 ++++++++++++------ .../standalone/common/monarch/monarchLexer.ts | 39 ++++++++++++++++++- src/vs/monaco.d.ts | 4 +- 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/src/vs/editor/standalone/browser/colorizer.ts b/src/vs/editor/standalone/browser/colorizer.ts index e085b2e80ed..7ae4fb0498c 100644 --- a/src/vs/editor/standalone/browser/colorizer.ts +++ b/src/vs/editor/standalone/browser/colorizer.ts @@ -13,6 +13,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { RenderLineInput, renderViewLine2 as renderViewLine } from 'vs/editor/common/viewLayout/viewLineRenderer'; import { ViewLineRenderingData } from 'vs/editor/common/viewModel/viewModel'; import { IStandaloneThemeService } from 'vs/editor/standalone/common/standaloneThemeService'; +import { MonarchTokenizer } from 'vs/editor/standalone/common/monarch/monarchLexer'; export interface IColorizerOptions { tabSize?: number; @@ -82,9 +83,10 @@ export class Colorizer { } const tokenizationSupport = TokenizationRegistry.get(language!); if (tokenizationSupport) { - return resolve(_colorize(lines, tabSize, tokenizationSupport)); + _colorize(lines, tabSize, tokenizationSupport).then(resolve, reject); + return; } - return resolve(_fakeColorize(lines, tabSize)); + resolve(_fakeColorize(lines, tabSize)); }; // wait 500ms for mode to load, then give up @@ -130,8 +132,21 @@ export class Colorizer { } } -function _colorize(lines: string[], tabSize: number, tokenizationSupport: ITokenizationSupport): string { - return _actualColorize(lines, tabSize, tokenizationSupport); +function _colorize(lines: string[], tabSize: number, tokenizationSupport: ITokenizationSupport): Promise { + return new Promise((c, e) => { + const execute = () => { + const result = _actualColorize(lines, tabSize, tokenizationSupport); + if (tokenizationSupport instanceof MonarchTokenizer) { + const status = tokenizationSupport.getLoadStatus(); + if (status.loaded === false) { + status.promise.then(execute, e); + return; + } + } + c(result); + }; + execute(); + }); } function _fakeColorize(lines: string[], tabSize: number): string { diff --git a/src/vs/editor/standalone/browser/standaloneLanguages.ts b/src/vs/editor/standalone/browser/standaloneLanguages.ts index 238ae5df16e..8a1f4a9c183 100644 --- a/src/vs/editor/standalone/browser/standaloneLanguages.ts +++ b/src/vs/editor/standalone/browser/standaloneLanguages.ts @@ -292,31 +292,47 @@ export interface EncodedTokensProvider { function isEncodedTokensProvider(provider: TokensProvider | EncodedTokensProvider): provider is EncodedTokensProvider { return provider['tokenizeEncoded']; } + +function isThenable(obj: any): obj is Thenable { + if (typeof obj.then === 'function') { + return true; + } + return false; +} + /** * Set the tokens provider for a language (manual implementation). */ -export function setTokensProvider(languageId: string, provider: TokensProvider | EncodedTokensProvider): IDisposable { +export function setTokensProvider(languageId: string, provider: TokensProvider | EncodedTokensProvider | Thenable): IDisposable { let languageIdentifier = StaticServices.modeService.get().getLanguageIdentifier(languageId); if (!languageIdentifier) { throw new Error(`Cannot set tokens provider for unknown language ${languageId}`); } - let adapter: modes.ITokenizationSupport; - if (isEncodedTokensProvider(provider)) { - adapter = new EncodedTokenizationSupport2Adapter(provider); - } else { - adapter = new TokenizationSupport2Adapter(StaticServices.standaloneThemeService.get(), languageIdentifier, provider); + const create = (provider: TokensProvider | EncodedTokensProvider) => { + if (isEncodedTokensProvider(provider)) { + return new EncodedTokenizationSupport2Adapter(provider); + } else { + return new TokenizationSupport2Adapter(StaticServices.standaloneThemeService.get(), languageIdentifier!, provider); + } + }; + if (isThenable(provider)) { + return modes.TokenizationRegistry.registerPromise(languageId, provider.then(provider => create(provider))); } - return modes.TokenizationRegistry.register(languageId, adapter); + return modes.TokenizationRegistry.register(languageId, create(provider)); } /** * Set the tokens provider for a language (monarch implementation). */ -export function setMonarchTokensProvider(languageId: string, languageDef: IMonarchLanguage): IDisposable { - let lexer = compile(languageId, languageDef); - let adapter = createTokenizationSupport(StaticServices.modeService.get(), StaticServices.standaloneThemeService.get(), languageId, lexer); - return modes.TokenizationRegistry.register(languageId, adapter); +export function setMonarchTokensProvider(languageId: string, languageDef: IMonarchLanguage | Thenable): IDisposable { + const create = (languageDef: IMonarchLanguage) => { + return createTokenizationSupport(StaticServices.modeService.get(), StaticServices.standaloneThemeService.get(), languageId, compile(languageId, languageDef)); + }; + if (isThenable(languageDef)) { + return modes.TokenizationRegistry.registerPromise(languageId, languageDef.then(languageDef => create(languageDef))); + } + return modes.TokenizationRegistry.register(languageId, create(languageDef)); } /** diff --git a/src/vs/editor/standalone/common/monarch/monarchLexer.ts b/src/vs/editor/standalone/common/monarch/monarchLexer.ts index 0deb0ed169a..6d8b55352ab 100644 --- a/src/vs/editor/standalone/common/monarch/monarchLexer.ts +++ b/src/vs/editor/standalone/common/monarch/monarchLexer.ts @@ -374,13 +374,16 @@ class MonarchModernTokensCollector implements IMonarchTokensCollector { } } -class MonarchTokenizer implements modes.ITokenizationSupport { +export type ILoadStatus = { loaded: true; } | { loaded: false; promise: Promise; }; + +export class MonarchTokenizer implements modes.ITokenizationSupport { private readonly _modeService: IModeService; private readonly _standaloneThemeService: IStandaloneThemeService; private readonly _modeId: string; private readonly _lexer: monarchCommon.ILexer; private _embeddedModes: { [modeId: string]: boolean; }; + public embeddedLoaded: Promise; private _tokenizationRegistryListener: IDisposable; constructor(modeService: IModeService, standaloneThemeService: IStandaloneThemeService, modeId: string, lexer: monarchCommon.ILexer) { @@ -389,6 +392,7 @@ class MonarchTokenizer implements modes.ITokenizationSupport { this._modeId = modeId; this._lexer = lexer; this._embeddedModes = Object.create(null); + this.embeddedLoaded = Promise.resolve(undefined); // Set up listening for embedded modes let emitting = false; @@ -416,6 +420,39 @@ class MonarchTokenizer implements modes.ITokenizationSupport { this._tokenizationRegistryListener.dispose(); } + public getLoadStatus(): ILoadStatus { + let promises: Thenable[] = []; + for (let nestedModeId in this._embeddedModes) { + const tokenizationSupport = modes.TokenizationRegistry.get(nestedModeId); + if (tokenizationSupport) { + // The nested mode is already loaded + if (tokenizationSupport instanceof MonarchTokenizer) { + const nestedModeStatus = tokenizationSupport.getLoadStatus(); + if (nestedModeStatus.loaded === false) { + promises.push(nestedModeStatus.promise); + } + } + continue; + } + + const tokenizationSupportPromise = modes.TokenizationRegistry.getPromise(nestedModeId); + if (tokenizationSupportPromise) { + // The nested mode is in the process of being loaded + promises.push(tokenizationSupportPromise); + } + } + + if (promises.length === 0) { + return { + loaded: true + }; + } + return { + loaded: false, + promise: Promise.all(promises).then(_ => undefined) + }; + } + public getInitialState(): modes.IState { let rootState = MonarchStackElementFactory.create(null, this._lexer.start!); return MonarchLineStateFactory.create(rootState, null); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index cf24813d108..3f279a4527c 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4284,12 +4284,12 @@ declare namespace monaco.languages { /** * Set the tokens provider for a language (manual implementation). */ - export function setTokensProvider(languageId: string, provider: TokensProvider | EncodedTokensProvider): IDisposable; + export function setTokensProvider(languageId: string, provider: TokensProvider | EncodedTokensProvider | Thenable): IDisposable; /** * Set the tokens provider for a language (monarch implementation). */ - export function setMonarchTokensProvider(languageId: string, languageDef: IMonarchLanguage): IDisposable; + export function setMonarchTokensProvider(languageId: string, languageDef: IMonarchLanguage | Thenable): IDisposable; /** * Register a reference provider (used by e.g. reference search). From 7ff5246e1bd5f33abb46a2055c75c10a8a73cdff Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 00:54:08 +0100 Subject: [PATCH 066/290] More honoring of tokenization support promises in colorize API --- src/vs/editor/standalone/browser/colorizer.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/standalone/browser/colorizer.ts b/src/vs/editor/standalone/browser/colorizer.ts index 7ae4fb0498c..db4ceaff579 100644 --- a/src/vs/editor/standalone/browser/colorizer.ts +++ b/src/vs/editor/standalone/browser/colorizer.ts @@ -65,7 +65,17 @@ export class Colorizer { let tokenizationSupport = TokenizationRegistry.get(language); if (tokenizationSupport) { - return Promise.resolve(_colorize(lines, tabSize, tokenizationSupport)); + return _colorize(lines, tabSize, tokenizationSupport); + } + + let tokenizationSupportPromise = TokenizationRegistry.getPromise(language); + if (tokenizationSupportPromise) { + // A tokenizer will be registered soon + return new Promise((resolve, reject) => { + tokenizationSupportPromise.then(tokenizationSupport => { + _colorize(lines, tabSize, tokenizationSupport).then(resolve, reject); + }, reject); + }); } return new Promise((resolve, reject) => { From 95e1e94fca81704ff6ebeab49132e1bcd621859c Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 01:45:15 +0100 Subject: [PATCH 067/290] Fix strict null check --- src/vs/editor/standalone/browser/colorizer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/standalone/browser/colorizer.ts b/src/vs/editor/standalone/browser/colorizer.ts index db4ceaff579..7c9a64ff411 100644 --- a/src/vs/editor/standalone/browser/colorizer.ts +++ b/src/vs/editor/standalone/browser/colorizer.ts @@ -72,7 +72,7 @@ export class Colorizer { if (tokenizationSupportPromise) { // A tokenizer will be registered soon return new Promise((resolve, reject) => { - tokenizationSupportPromise.then(tokenizationSupport => { + tokenizationSupportPromise!.then(tokenizationSupport => { _colorize(lines, tabSize, tokenizationSupport).then(resolve, reject); }, reject); }); From 6aa3a66966affc4f755ac4acf033b8c1caaad5d6 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 01:53:49 +0100 Subject: [PATCH 068/290] Make vs/base/common/path compatible with ESM --- src/vs/base/common/path.ts | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/vs/base/common/path.ts b/src/vs/base/common/path.ts index 53bd495fd8d..982934e20d1 100644 --- a/src/vs/base/common/path.ts +++ b/src/vs/base/common/path.ts @@ -205,12 +205,7 @@ interface IPath { posix: IPath | null; } -interface IExportedPath extends IPath { - win32: IPath; - posix: IPath; -} - -const win32: IPath = { +export const win32: IPath = { // path.resolve([from ...], to) resolve(...pathSegments: string[]): string { let resolvedDevice = ''; @@ -1199,7 +1194,7 @@ const win32: IPath = { posix: null }; -const posix: IPath = { +export const posix: IPath = { // path.resolve([from ...], to) resolve(...pathSegments: string[]): string { let resolvedPath = ''; @@ -1685,5 +1680,16 @@ const posix: IPath = { posix.win32 = win32.win32 = win32; posix.posix = win32.posix = posix; -const impl = (safeProcess.platform === 'win32' ? win32 : posix) as IExportedPath; -export = impl; +export const normalize = (safeProcess.platform === 'win32' ? win32.normalize : posix.normalize); +export const isAbsolute = (safeProcess.platform === 'win32' ? win32.isAbsolute : posix.isAbsolute); +export const join = (safeProcess.platform === 'win32' ? win32.join : posix.join); +export const resolve = (safeProcess.platform === 'win32' ? win32.resolve : posix.resolve); +export const relative = (safeProcess.platform === 'win32' ? win32.relative : posix.relative); +export const dirname = (safeProcess.platform === 'win32' ? win32.dirname : posix.dirname); +export const basename = (safeProcess.platform === 'win32' ? win32.basename : posix.basename); +export const extname = (safeProcess.platform === 'win32' ? win32.extname : posix.extname); +export const format = (safeProcess.platform === 'win32' ? win32.format : posix.format); +export const parse = (safeProcess.platform === 'win32' ? win32.parse : posix.parse); +export const toNamespacedPath = (safeProcess.platform === 'win32' ? win32.toNamespacedPath : posix.toNamespacedPath); +export const sep = (safeProcess.platform === 'win32' ? win32.sep : posix.sep); +export const delimiter = (safeProcess.platform === 'win32' ? win32.delimiter : posix.delimiter); From afded16b6fd860266463e8fba797a38a5d5a5d89 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 02:08:54 +0100 Subject: [PATCH 069/290] Fix Microsoft/monaco-editor#1297 --- build/monaco/monaco.usage.recipe | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/monaco/monaco.usage.recipe b/build/monaco/monaco.usage.recipe index fad1e8ee724..13290a7abb5 100644 --- a/build/monaco/monaco.usage.recipe +++ b/build/monaco/monaco.usage.recipe @@ -13,6 +13,7 @@ import { QuickOpenWidget } from './vs/base/parts/quickopen/browser/quickOpenWidg import { WorkbenchAsyncDataTree } from './vs/platform/list/browser/listService'; import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from './vs/platform/instantiation/common/descriptors'; import { DiffNavigator } from './vs/editor/browser/widget/diffNavigator'; +import { DocumentRangeFormattingEditProvider } from './vs/editor/common/modes'; import * as editorAPI from './vs/editor/editor.api'; (function () { @@ -32,6 +33,7 @@ import * as editorAPI from './vs/editor/editor.api'; a = (>b).getProxyObject; // IWorkerClient a = create1; a = create2; + a = (b).extensionId; // injection madness a = (>b).ctor; From 57f34ad851fd07c0bd4d83da8bb587d806d42ce7 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 02:25:49 +0100 Subject: [PATCH 070/290] monaco-editor-core@0.16.0 --- build/gulpfile.editor.js | 8 ++++++ build/monaco/ThirdPartyNotices.txt | 25 ++++++++++++++++++ build/monaco/package.json | 2 +- build/monaco/version.txt | 0 src/vs/base/common/path.ts | 42 ++++++++++++++++-------------- 5 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 build/monaco/version.txt diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 05c7d4fb8b5..7bbf246a8dc 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -234,6 +234,14 @@ const finalEditorResourcesTask = task.define('final-editor-resources', () => { })) .pipe(gulp.dest('out-monaco-editor-core')), + // version.txt + gulp.src('build/monaco/version.txt') + .pipe(es.through(function (data) { + data.contents = Buffer.from(`monaco-editor-core: https://github.com/Microsoft/vscode/tree/${sha1}`); + this.emit('data', data); + })) + .pipe(gulp.dest('out-monaco-editor-core')), + // README.md gulp.src('build/monaco/README-npm.md') .pipe(es.through(function (data) { diff --git a/build/monaco/ThirdPartyNotices.txt b/build/monaco/ThirdPartyNotices.txt index a459893cc97..1de70ddaab6 100644 --- a/build/monaco/ThirdPartyNotices.txt +++ b/build/monaco/ThirdPartyNotices.txt @@ -7,6 +7,31 @@ herein, whether by implication, estoppel or otherwise. +%% nodejs path library (https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158) +========================================= +Copyright Joyent, Inc. and other Node 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: + +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. +========================================= +END OF nodejs path library NOTICES AND INFORMATION + %% promise-polyfill version 8.1.0 (https://github.com/taylorhakes/promise-polyfill) ========================================= diff --git a/build/monaco/package.json b/build/monaco/package.json index efd919085b2..1962694ce6d 100644 --- a/build/monaco/package.json +++ b/build/monaco/package.json @@ -1,7 +1,7 @@ { "name": "monaco-editor-core", "private": true, - "version": "0.14.3", + "version": "0.16.0", "description": "A browser based code editor", "author": "Microsoft Corporation", "license": "MIT", diff --git a/build/monaco/version.txt b/build/monaco/version.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/vs/base/common/path.ts b/src/vs/base/common/path.ts index 982934e20d1..a93084c42b7 100644 --- a/src/vs/base/common/path.ts +++ b/src/vs/base/common/path.ts @@ -6,26 +6,28 @@ // NOTE: VSCode's copy of nodejs path library to be usable in common (non-node) namespace // Copied from: https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158 -// Copyright Joyent, Inc. and other Node 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: -// -// 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. +/** + * Copyright Joyent, Inc. and other Node 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: + * + * 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. + */ import { isWindows } from 'vs/base/common/platform'; From 87a826c6e8e8891020a9e02fa796b3590c10d751 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Sat, 2 Mar 2019 02:29:27 +0100 Subject: [PATCH 071/290] Fix path tests --- src/vs/base/test/common/path.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/base/test/common/path.test.ts b/src/vs/base/test/common/path.test.ts index f16f61a9bea..e135fd3a177 100644 --- a/src/vs/base/test/common/path.test.ts +++ b/src/vs/base/test/common/path.test.ts @@ -753,11 +753,11 @@ suite('Paths (Node Implementation)', () => { // posix assert.strictEqual(path.posix.delimiter, ':'); - if (isWindows) { - assert.strictEqual(path, path.win32); - } else { - assert.strictEqual(path, path.posix); - } + // if (isWindows) { + // assert.strictEqual(path, path.win32); + // } else { + // assert.strictEqual(path, path.posix); + // } }); // test('perf', () => { From 3f68d38c9bf1ff4f2c69befc5b107af3fb087a4f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 1 Mar 2019 19:52:09 -0800 Subject: [PATCH 072/290] Fix strict null error in webview --- src/vs/workbench/api/node/extHostWebview.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/node/extHostWebview.ts b/src/vs/workbench/api/node/extHostWebview.ts index df6b86f3e92..d5e5d2264db 100644 --- a/src/vs/workbench/api/node/extHostWebview.ts +++ b/src/vs/workbench/api/node/extHostWebview.ts @@ -85,7 +85,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { private readonly _options: vscode.WebviewPanelOptions; private readonly _webview: ExtHostWebview; private _isDisposed: boolean = false; - private _viewColumn: vscode.ViewColumn; + private _viewColumn: vscode.ViewColumn | undefined; private _visible: boolean = true; private _active: boolean = true; @@ -101,7 +101,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { proxy: MainThreadWebviewsShape, viewType: string, title: string, - viewColumn: vscode.ViewColumn, + viewColumn: vscode.ViewColumn | undefined, editorOptions: vscode.WebviewPanelOptions, webview: ExtHostWebview ) { @@ -173,7 +173,7 @@ export class ExtHostWebviewPanel implements vscode.WebviewPanel { get viewColumn(): vscode.ViewColumn | undefined { this.assertNotDisposed(); - if (this._viewColumn < 0) { + if (typeof this._viewColumn === 'number' && this._viewColumn < 0) { // We are using a symbolic view column // Return undefined instead to indicate that the real view column is currently unknown but will be resolved. return undefined; From a733b477504dbaf81b26296cdd2d3d40d72ffcca Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 1 Mar 2019 19:53:22 -0800 Subject: [PATCH 073/290] Strict null work in breadcrumbs --- .../browser/parts/editor/breadcrumbsControl.ts | 10 +++++----- .../browser/parts/editor/breadcrumbsPicker.ts | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 8eaf0a8810b..1b9aad2e2fb 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -221,7 +221,7 @@ export class BreadcrumbsControl { input = input.master; } - if (!input || !input.getResource() || (input.getResource().scheme !== Schemas.untitled && !this._fileService.canHandleResource(input.getResource()))) { + if (!input || !input.getResource() || (input.getResource()!.scheme !== Schemas.untitled && !this._fileService.canHandleResource(input.getResource()!))) { // cleanup and return when there is no input or when // we cannot handle this input this._ckBreadcrumbsPossible.set(false); @@ -238,7 +238,7 @@ export class BreadcrumbsControl { this._ckBreadcrumbsPossible.set(true); let editor = this._getActiveCodeEditor(); - let model = new EditorBreadcrumbsModel(input.getResource(), editor, this._workspaceService, this._configurationService); + let model = new EditorBreadcrumbsModel(input.getResource()!, editor, this._workspaceService, this._configurationService); dom.toggleClass(this.domNode, 'relative-path', model.isRelative()); let updateBreadcrumbs = () => { @@ -435,7 +435,7 @@ export class BreadcrumbsControl { this._ckBreadcrumbsActive.set(value); } - private _revealInEditor(event: IBreadcrumbsItemEvent, element: any, group: SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, pinned: boolean = false): void { + private _revealInEditor(event: IBreadcrumbsItemEvent, element: any, group: SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE | undefined, pinned: boolean = false): void { if (element instanceof FileElement) { if (element.kind === FileKind.FILE) { // open file in any editor @@ -450,14 +450,14 @@ export class BreadcrumbsControl { } else if (element instanceof OutlineElement) { // open symbol in code editor - let model = OutlineModel.get(element); + const model = OutlineModel.get(element); this._codeEditorService.openCodeEditor({ resource: model.textModel.uri, options: { selection: Range.collapseToStart(element.symbol.selectionRange), revealInCenterIfOutsideViewport: true } - }, this._getActiveCodeEditor(), group === SIDE_GROUP); + }, this._getActiveCodeEditor() || null, group === SIDE_GROUP); } } diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index 6f1c4e469c8..b0d991ac9eb 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -87,11 +87,11 @@ export abstract class BreadcrumbsPicker { this._arrow = document.createElement('div'); this._arrow.className = 'arrow'; - this._arrow.style.borderColor = `transparent transparent ${color.toString()}`; + this._arrow.style.borderColor = `transparent transparent ${color ? color.toString() : ''}`; this._domNode.appendChild(this._arrow); this._treeContainer = document.createElement('div'); - this._treeContainer.style.background = color.toString(); + this._treeContainer.style.background = color ? color.toString() : ''; this._treeContainer.style.paddingTop = '2px'; this._treeContainer.style.boxShadow = `0px 5px 8px ${this._themeService.getTheme().getColor(widgetShadow)}`; this._domNode.appendChild(this._treeContainer); @@ -219,10 +219,10 @@ class FileDataSource implements IAsyncDataSource { - for (let child of stat.children) { + for (const child of stat.children || []) { this._parents.set(stat, child); } - return stat.children; + return stat.children || []; }); } } From 326660dddd15333def33eacf11561368cb370a24 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 1 Mar 2019 20:00:18 -0800 Subject: [PATCH 074/290] Strict null work --- src/vs/workbench/browser/dnd.ts | 2 +- .../workbench/browser/parts/editor/editor.ts | 2 +- src/vs/workbench/common/editor.ts | 2 +- .../files/browser/editors/binaryFileEditor.ts | 2 +- .../browser/editors/fileEditorTracker.ts | 23 ++++++++++--------- .../files/browser/editors/textFileEditor.ts | 6 ++--- .../contrib/files/browser/saveErrorHandler.ts | 6 +++++ .../contrib/files/browser/views/emptyView.ts | 17 ++++++++++---- .../files/browser/views/explorerView.ts | 4 ++-- .../files/common/editors/fileEditorInput.ts | 2 +- .../electron-browser/remoteFileDialog.ts | 4 +++- .../services/editor/browser/editorService.ts | 2 +- 12 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 5897ab9e710..a494e038b78 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -162,7 +162,7 @@ export class ResourcesDropHandler { ) { } - handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup, afterDrop: (targetGroup: IEditorGroup) => void, targetIndex?: number): void { + handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup) => void, targetIndex?: number): void { const untitledOrFileResources = extractResources(event).filter(r => this.fileService.canHandleResource(r.resource) || r.resource.scheme === Schemas.untitled); if (!untitledOrFileResources.length) { return; diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 5da1159887f..0fac3e2d9e6 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -77,7 +77,7 @@ export interface IEditorOpeningEvent extends IEditorIdentifier { * to return a promise that resolves to NULL to prevent the opening * alltogether. */ - prevent(callback: () => Promise): void; + prevent(callback: () => undefined | Promise): void; } export interface IEditorGroupsAccessor { diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 027f4d17d21..bd9740edb23 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -678,7 +678,7 @@ export class EditorOptions implements IEditorOptions { /** * Helper to create EditorOptions inline. */ - static create(settings: IEditorOptions): EditorOptions | null { + static create(settings: IEditorOptions): EditorOptions { const options = new EditorOptions(); options.preserveFocus = settings.preserveFocus; diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index a928e36712a..56e4ac1979b 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -64,7 +64,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { }); } - getTitle(): string { + getTitle(): string | null { return this.input ? this.input.getName() : nls.localize('binaryFileEditor', "Binary File Viewer"); } } diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts index 5b62bd8c09b..c281e9d0bfb 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts @@ -13,7 +13,7 @@ import { FileOperationEvent, FileOperation, IFileService, FileChangeType, FileCh import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle'; -import { distinct } from 'vs/base/common/arrays'; +import { distinct, coalesce } from 'vs/base/common/arrays'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { isLinux } from 'vs/base/common/platform'; @@ -92,12 +92,12 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // are visible in any editor. since this is a fast operation in the case nothing has changed, // we tolerate the additional work. distinct( - this.editorService.visibleEditors + coalesce(this.editorService.visibleEditors .map(editorInput => { const resource = toResource(editorInput, { supportSideBySide: true }); return resource ? this.textFileService.models.get(resource) : undefined; - }) - .filter(model => model && !model.isDirty()), + })) + .filter(model => !model.isDirty()), m => m.getResource().toString() ).forEach(model => this.queueModelLoad(model)); } @@ -276,7 +276,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut if (editorResource && resource.toString() === editorResource.toString()) { const control = editor.getControl(); if (isCodeEditor(control)) { - return control.saveViewState(); + return control.saveViewState() || undefined; } } } @@ -320,18 +320,19 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut private handleUpdatesToVisibleBinaryEditors(e: FileChangesEvent): void { const editors = this.editorService.visibleControls; editors.forEach(editor => { - const resource = toResource(editor.input, { supportSideBySide: true }); + const resource = editor.input ? toResource(editor.input, { supportSideBySide: true }) : undefined; // Support side-by-side binary editors too let isBinaryEditor = false; if (editor instanceof SideBySideEditor) { - isBinaryEditor = editor.getMasterEditor().getId() === BINARY_FILE_EDITOR_ID; + const masterEditor = editor.getMasterEditor(); + isBinaryEditor = !!masterEditor && masterEditor.getId() === BINARY_FILE_EDITOR_ID; } else { isBinaryEditor = editor.getId() === BINARY_FILE_EDITOR_ID; } // Binary editor that should reload from event - if (resource && isBinaryEditor && (e.contains(resource, FileChangeType.UPDATED) || e.contains(resource, FileChangeType.ADDED))) { + if (resource && editor.input && isBinaryEditor && (e.contains(resource, FileChangeType.UPDATED) || e.contains(resource, FileChangeType.ADDED))) { this.editorService.openEditor(editor.input, { forceReload: true, preserveFocus: true }, editor.group); } }); @@ -339,10 +340,10 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut private handleOutOfWorkspaceWatchers(): void { const visibleOutOfWorkspacePaths = new ResourceMap(); - this.editorService.visibleEditors.map(editorInput => { + coalesce(this.editorService.visibleEditors.map(editorInput => { return toResource(editorInput, { supportSideBySide: true }); - }).filter(resource => { - return !!resource && this.fileService.canHandleResource(resource) && !this.contextService.isInsideWorkspace(resource); + })).filter(resource => { + return this.fileService.canHandleResource(resource) && !this.contextService.isInsideWorkspace(resource); }).forEach(resource => { visibleOutOfWorkspacePaths.set(resource, resource); }); diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts index 8d1c0fbc798..5e1a9623ea0 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts @@ -185,7 +185,7 @@ export class TextFileEditor extends BaseTextEditor { if ((error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND && isValidBasename(basename(input.getResource()))) { return Promise.reject(createErrorWithActions(toErrorMessage(error), { actions: [ - new Action('workbench.files.action.createMissingFile', nls.localize('createFile', "Create File"), null, true, () => { + new Action('workbench.files.action.createMissingFile', nls.localize('createFile', "Create File"), undefined, true, () => { return this.fileService.updateContent(input.getResource(), '').then(() => this.editorService.openEditor({ resource: input.getResource(), options: { @@ -202,14 +202,14 @@ export class TextFileEditor extends BaseTextEditor { return Promise.reject(createErrorWithActions(toErrorMessage(error), { actions: [ - new Action('workbench.window.action.relaunchWithIncreasedMemoryLimit', nls.localize('relaunchWithIncreasedMemoryLimit', "Restart with {0} MB", memoryLimit), null, true, () => { + new Action('workbench.window.action.relaunchWithIncreasedMemoryLimit', nls.localize('relaunchWithIncreasedMemoryLimit', "Restart with {0} MB", memoryLimit), undefined, true, () => { return this.windowsService.relaunch({ addArgs: [ `--max-memory=${memoryLimit}` ] }); }), - new Action('workbench.window.action.configureMemoryLimit', nls.localize('configureMemoryLimit', 'Configure Memory Limit'), null, true, () => { + new Action('workbench.window.action.configureMemoryLimit', nls.localize('configureMemoryLimit', 'Configure Memory Limit'), undefined, true, () => { return this.preferencesService.openGlobalSettings(undefined, { query: 'files.maxMemoryForLargeFilesMB' }); }) ] diff --git a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts index 76ea4afea5f..c3861633546 100644 --- a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts +++ b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts @@ -314,6 +314,9 @@ export const acceptLocalChangesCommand = (accessor: ServicesAccessor, resource: const modelService = accessor.get(IModelService); const control = editorService.activeControl; + if (!control) { + return; + } const editor = control.input; const group = control.group; @@ -350,6 +353,9 @@ export const revertLocalChangesCommand = (accessor: ServicesAccessor, resource: const resolverService = accessor.get(ITextModelService); const control = editorService.activeControl; + if (!control) { + return; + } const editor = control.input; const group = control.group; diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index 40315768e67..89e2def4556 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -70,6 +70,9 @@ export class EmptyView extends ViewletPanel { attachButtonStyler(this.button, this.themeService); this.disposables.push(this.button.onDidClick(() => { + if (!this.actionRunner) { + return; + } const actionClass = this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE ? AddRootFolderAction : env.isMacintosh ? OpenFileFolderAction : OpenFolderAction; const action = this.instantiationService.createInstance(actionClass, actionClass.ID, actionClass.LABEL); this.actionRunner.run(action).then(() => { @@ -82,21 +85,25 @@ export class EmptyView extends ViewletPanel { this.disposables.push(new DragAndDropObserver(container, { onDrop: e => { - container.style.backgroundColor = this.themeService.getTheme().getColor(SIDE_BAR_BACKGROUND).toString(); + const color = this.themeService.getTheme().getColor(SIDE_BAR_BACKGROUND); + container.style.backgroundColor = color ? color.toString() : ''; const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: true }); dropHandler.handleDrop(e, () => undefined, targetGroup => undefined); }, onDragEnter: (e) => { - container.style.backgroundColor = this.themeService.getTheme().getColor(listDropBackground).toString(); + const color = this.themeService.getTheme().getColor(listDropBackground); + container.style.backgroundColor = color ? color.toString() : ''; }, onDragEnd: () => { - container.style.backgroundColor = this.themeService.getTheme().getColor(SIDE_BAR_BACKGROUND).toString(); + const color = this.themeService.getTheme().getColor(SIDE_BAR_BACKGROUND); + container.style.backgroundColor = color ? color.toString() : ''; }, onDragLeave: () => { - container.style.backgroundColor = this.themeService.getTheme().getColor(SIDE_BAR_BACKGROUND).toString(); + const color = this.themeService.getTheme().getColor(SIDE_BAR_BACKGROUND); + container.style.backgroundColor = color ? color.toString() : ''; }, onDragOver: e => { - e.dataTransfer.dropEffect = 'copy'; + e.dataTransfer!.dropEffect = 'copy'; } })); diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 2f4cf5df114..eafa721b5bd 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -61,7 +61,7 @@ export class ExplorerView extends ViewletPanel { // Refresh is needed on the initial explorer open private shouldRefresh = true; - private setTreeInputPromise = Promise.resolve(undefined); + private setTreeInputPromise = Promise.resolve(); private dragHandler: DelayedDragHandler; private decorationProvider: ExplorerDecorationsProvider; private autoReveal = false; @@ -487,7 +487,7 @@ export class ExplorerView extends ViewletPanel { return promise; } - private getActiveFile(): URI { + private getActiveFile(): URI | undefined { const input = this.editorService.activeEditor; // ignore diff editor inputs (helps to get out of diffing when returning to explorer) diff --git a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts index 3b7916fe08f..ba125a48dba 100644 --- a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts @@ -28,7 +28,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { private preferredEncoding: string; private forceOpenAsBinary: boolean; private forceOpenAsText: boolean; - private textModelReference: Promise>; + private textModelReference: Promise> | null; private name: string; /** diff --git a/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts index c8264fa5a65..82aefb51aff 100644 --- a/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts @@ -150,7 +150,9 @@ export class RemoteFileDialog { } this.filePickBox.onDidTriggerButton(button => { if (button === this.fallbackPickerButton) { - options.availableFileSystems.shift(); + if (options.availableFileSystems) { + options.availableFileSystems.shift(); + } isResolved = true; if (this.requiresTrailing) { this.fileDialogService.showSaveDialog(options).then(result => { diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 228dfe7afb4..b9665358c3b 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -54,7 +54,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { private fileInputFactory: IFileInputFactory; private openEditorHandlers: IOpenEditorOverrideHandler[] = []; - private lastActiveEditor: IEditorInput; + private lastActiveEditor: IEditorInput | null; private lastActiveGroupId: GroupIdentifier; constructor( From 74e525d78fc9eb9fff3adcdcc07a85be7661e1e4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 1 Mar 2019 20:22:40 -0800 Subject: [PATCH 075/290] Strict null work on api tests --- .../api/extHostApiCommands.test.ts | 22 +++++++++---------- .../api/extHostTextEditor.test.ts | 2 +- .../api/extHostTreeViews.test.ts | 4 ++-- .../api/mainThreadConfiguration.test.ts | 16 +++++++------- .../api/mainThreadEditors.test.ts | 6 ++--- 5 files changed, 25 insertions(+), 25 deletions(-) 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 49c0a50275a..f7c066436d5 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -87,15 +87,15 @@ suite('ExtHostLanguageFeatureCommands', function () { instantiationService.stub(IModelService, { _serviceBrand: IModelService, getModel(): any { return model; }, - createModel(): any { throw new Error(); }, - updateModel(): any { throw new Error(); }, - setMode(): any { throw new Error(); }, - destroyModel(): any { throw new Error(); }, - getModels(): any { throw new Error(); }, - onModelAdded: undefined, - onModelModeChanged: undefined, - onModelRemoved: undefined, - getCreationOptions(): any { throw new Error(); } + createModel() { throw new Error(); }, + updateModel() { throw new Error(); }, + setMode() { throw new Error(); }, + destroyModel() { throw new Error(); }, + getModels() { throw new Error(); }, + onModelAdded: undefined!, + onModelModeChanged: undefined!, + onModelRemoved: undefined!, + getCreationOptions() { throw new Error(); } }); inst = instantiationService; } @@ -190,8 +190,8 @@ suite('ExtHostLanguageFeatureCommands', function () { test('executeWorkspaceSymbolProvider should accept empty string, #39522', async function () { disposables.push(extHost.registerWorkspaceSymbolProvider(nullExtensionDescription, { - provideWorkspaceSymbols(query) { - return [new types.SymbolInformation('hello', types.SymbolKind.Array, new types.Range(0, 0, 0, 0), URI.parse('foo:bar'))]; + provideWorkspaceSymbols(query): vscode.SymbolInformation[] { + return [new types.SymbolInformation('hello', types.SymbolKind.Array, new types.Range(0, 0, 0, 0), URI.parse('foo:bar')) as vscode.SymbolInformation]; } })); 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 b7cdcfcf6e9..a9bcfbeca01 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTextEditor.test.ts @@ -292,7 +292,7 @@ suite('ExtHostTextEditorOptions', () => { }); test('ignores invalid indentSize 1', () => { - opts.indentSize = null; + opts.indentSize = null!; assertState(opts, { tabSize: 4, indentSize: 4, diff --git a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts index f371dd2f5d9..7e626d3985b 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostTreeViews.test.ts @@ -625,7 +625,7 @@ suite('ExtHostTreeView', function () { getTreeItem: (element: { key: string }): TreeItem => { return getTreeItem(element.key); }, - getParent: ({ key }: { key: string }): { key: string } => { + getParent: ({ key }: { key: string }): { key: string } | undefined => { const parentKey = key.substring(0, key.length - 1); return parentKey ? new Key(parentKey) : undefined; }, @@ -672,7 +672,7 @@ suite('ExtHostTreeView', function () { return parent; } - function getChildren(key: string): string[] { + function getChildren(key: string | undefined): string[] { if (!key) { return Object.keys(tree); } diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadConfiguration.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadConfiguration.test.ts index 4be29bb9ecd..01d75b06fd5 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadConfiguration.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadConfiguration.test.ts @@ -63,7 +63,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.WORKSPACE }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', null); + testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -81,7 +81,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.FOLDER }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', null); + testObject.$updateConfigurationOption(null, 'extHostConfiguration.resource', 'value', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -90,7 +90,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.WORKSPACE }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', null); + testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -117,7 +117,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.FOLDER }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', null); + testObject.$updateConfigurationOption(null, 'extHostConfiguration.window', 'value', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -162,7 +162,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.WORKSPACE }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', null); + testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -180,7 +180,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.FOLDER }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', null); + testObject.$removeConfigurationOption(null, 'extHostConfiguration.resource', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -189,7 +189,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.WORKSPACE }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', null); + testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); @@ -216,7 +216,7 @@ suite('MainThreadConfiguration', function () { instantiationService.stub(IWorkspaceContextService, { getWorkbenchState: () => WorkbenchState.FOLDER }); const testObject: MainThreadConfiguration = instantiationService.createInstance(MainThreadConfiguration, SingleProxyRPCProtocol(proxy)); - testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', null); + testObject.$removeConfigurationOption(null, 'extHostConfiguration.window', undefined); assert.equal(ConfigurationTarget.WORKSPACE, target.args[0][3]); }); 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 049ba68c009..fb0d2c8e3aa 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -100,10 +100,10 @@ suite('MainThreadEditors', () => { textFileService, workbenchEditorService, codeEditorService, - null, + null!, fileService, - null, - null, + null!, + null!, editorGroupService, bulkEditService, new class extends mock() implements IPanelService { From c5e999376f6f30ebe94bfdc838dccd2a9e7424b4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 1 Mar 2019 20:24:34 -0800 Subject: [PATCH 076/290] Fix strict null error in performance --- .../contrib/performance/electron-browser/startupProfiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts index b6c1119841a..dfd9214684a 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts @@ -87,7 +87,7 @@ export class StartupProfiler implements IWorkbenchContribution { message: localize('prof.thanks', "Thanks for helping us."), detail: localize('prof.detail.restart', "A final restart is required to continue to use '{0}'. Again, thank you for your contribution.", this._environmentService.appNameLong), primaryButton: localize('prof.restart', "Restart"), - secondaryButton: null + secondaryButton: undefined }).then(() => { // now we are ready to restart this._windowsService.relaunch({ removeArgs }); From a0851ca719d423d82776bab621339e31fb5f08d7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 1 Mar 2019 21:08:16 -0800 Subject: [PATCH 077/290] Strict null check textEditorModel Enables strict null checking for `textEditorModel`. I also had to add a few null supressions to difficult errors. --- src/tsconfig.strictNullChecks.json | 10 ++++++ .../common/services/languagesRegistry.ts | 2 +- src/vs/editor/common/services/modeService.ts | 2 +- .../editor/common/services/modeServiceImpl.ts | 4 +-- .../editor/common/services/resolverService.ts | 8 +++-- .../standalone/browser/simpleServices.ts | 6 ++-- .../common/editor/textEditorModel.ts | 10 +++--- .../bulkEdit/browser/bulkEditService.ts | 6 ++-- .../configuration/node/jsonEditingService.ts | 10 +++--- .../textfile/common/textFileEditorModel.ts | 36 +++++++++---------- .../common/textFileEditorModelManager.ts | 10 +++--- .../services/textfile/common/textfiles.ts | 4 +-- 12 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 315d356b476..ddcdd59c311 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -132,6 +132,10 @@ "./vs/workbench/common/editor/dataUriEditorInput.ts", "./vs/workbench/common/editor/diffEditorModel.ts", "./vs/workbench/common/editor/editorGroup.ts", + "./vs/workbench/common/editor/resourceEditorInput.ts", + "./vs/workbench/common/editor/resourceEditorModel.ts", + "./vs/workbench/common/editor/textDiffEditorModel.ts", + "./vs/workbench/common/editor/textEditorModel.ts", "./vs/workbench/common/memento.ts", "./vs/workbench/common/notifications.ts", "./vs/workbench/common/panel.ts", @@ -205,8 +209,10 @@ "./vs/workbench/contrib/feedback/electron-browser/feedback.contribution.ts", "./vs/workbench/contrib/feedback/electron-browser/feedback.ts", "./vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts", + "./vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts", "./vs/workbench/contrib/files/browser/files.ts", "./vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts", + "./vs/workbench/contrib/files/common/editors/fileEditorInput.ts", "./vs/workbench/contrib/files/common/explorerModel.ts", "./vs/workbench/contrib/files/common/explorerService.ts", "./vs/workbench/contrib/files/common/files.ts", @@ -229,6 +235,8 @@ "./vs/workbench/contrib/output/common/outputLinkComputer.ts", "./vs/workbench/contrib/output/common/outputLinkProvider.ts", "./vs/workbench/contrib/output/node/outputAppender.ts", + "./vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts", + "./vs/workbench/contrib/performance/electron-browser/startupProfiler.ts", "./vs/workbench/contrib/performance/electron-browser/startupTimings.ts", "./vs/workbench/contrib/preferences/browser/settingsWidgets.ts", "./vs/workbench/contrib/preferences/common/smartSnippetInserter.ts", @@ -414,6 +422,8 @@ "./vs/workbench/services/textMate/common/textMateService.ts", "./vs/workbench/services/textMate/electron-browser/TMGrammars.ts", "./vs/workbench/services/textMate/electron-browser/textMateService.ts", + "./vs/workbench/services/textfile/common/textFileEditorModel.ts", + "./vs/workbench/services/textfile/common/textFileEditorModelManager.ts", "./vs/workbench/services/textfile/common/textfiles.ts", "./vs/workbench/services/textfile/node/textResourcePropertiesService.ts", "./vs/workbench/services/timer/electron-browser/timerService.ts", diff --git a/src/vs/editor/common/services/languagesRegistry.ts b/src/vs/editor/common/services/languagesRegistry.ts index e5f39e13df3..5534b442510 100644 --- a/src/vs/editor/common/services/languagesRegistry.ts +++ b/src/vs/editor/common/services/languagesRegistry.ts @@ -270,7 +270,7 @@ export class LanguagesRegistry extends Disposable { return (language.mimetypes[0] || null); } - public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds: string): string[] { + public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): string[] { if (!commaSeparatedMimetypesOrCommaSeparatedIds) { return []; } diff --git a/src/vs/editor/common/services/modeService.ts b/src/vs/editor/common/services/modeService.ts index bf6a6e51a06..de852f670f7 100644 --- a/src/vs/editor/common/services/modeService.ts +++ b/src/vs/editor/common/services/modeService.ts @@ -47,7 +47,7 @@ export interface IModeService { getConfigurationFiles(modeId: string): URI[]; // --- instantiation - create(commaSeparatedMimetypesOrCommaSeparatedIds: string): ILanguageSelection; + create(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): ILanguageSelection; createByLanguageName(languageName: string): ILanguageSelection; createByFilepathOrFirstLine(filepath: string | null, firstLine?: string): ILanguageSelection; diff --git a/src/vs/editor/common/services/modeServiceImpl.ts b/src/vs/editor/common/services/modeServiceImpl.ts index db3cd258a1f..9b4667220e8 100644 --- a/src/vs/editor/common/services/modeServiceImpl.ts +++ b/src/vs/editor/common/services/modeServiceImpl.ts @@ -104,7 +104,7 @@ export class ModeServiceImpl implements IModeService { return null; } - public getModeId(commaSeparatedMimetypesOrCommaSeparatedIds: string): string | null { + public getModeId(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): string | null { const modeIds = this._registry.extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds); if (modeIds.length > 0) { @@ -124,7 +124,7 @@ export class ModeServiceImpl implements IModeService { // --- instantiation - public create(commaSeparatedMimetypesOrCommaSeparatedIds: string): ILanguageSelection { + public create(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): ILanguageSelection { return new LanguageSelection(this.onLanguagesMaybeChanged, () => { const modeId = this.getModeId(commaSeparatedMimetypesOrCommaSeparatedIds); return this._createModeAndGetLanguageIdentifier(modeId); diff --git a/src/vs/editor/common/services/resolverService.ts b/src/vs/editor/common/services/resolverService.ts index e000629c298..2b04d4b1218 100644 --- a/src/vs/editor/common/services/resolverService.ts +++ b/src/vs/editor/common/services/resolverService.ts @@ -18,7 +18,7 @@ export interface ITextModelService { * Provided a resource URI, it will return a model reference * which should be disposed once not needed anymore. */ - createModelReference(resource: URI): Promise>; + createModelReference(resource: URI): Promise>; /** * Registers a specific `scheme` content provider. @@ -44,7 +44,11 @@ export interface ITextEditorModel extends IEditorModel { /** * Provides access to the underlying `ITextModel`. */ - readonly textEditorModel: ITextModel; + readonly textEditorModel: ITextModel | null; isReadonly(): boolean; } + +export interface IActiveTextEditorModel extends ITextEditorModel { + readonly textEditorModel: ITextModel; +} diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index ea099deb164..7c6487339f2 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -22,7 +22,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEdit, WorkspaceEdit, isResourceTextEdit } from 'vs/editor/common/modes'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { ITextEditorModel, ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService'; +import { IActiveTextEditorModel, ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService'; import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; import { CommandsRegistry, ICommand, ICommandEvent, ICommandHandler, ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -44,7 +44,7 @@ import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFolde import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -export class SimpleModel implements ITextEditorModel { +export class SimpleModel implements IActiveTextEditorModel { private model: ITextModel; private readonly _onDispose: Emitter; @@ -98,7 +98,7 @@ export class SimpleEditorModelResolverService implements ITextModelService { this.editor = editor; } - public createModelReference(resource: URI): Promise> { + public createModelReference(resource: URI): Promise> { let model: ITextModel | null = withTypedEditor(this.editor, (editor) => this.findModel(editor, resource), (diffEditor) => this.findModel(diffEditor.getOriginalEditor(), resource) || this.findModel(diffEditor.getModifiedEditor(), resource) diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index b300ee95fb5..b8279be7d5c 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -6,7 +6,7 @@ import { ITextModel, ITextBufferFactory } from 'vs/editor/common/model'; import { EditorModel } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; -import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextEditorModel, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -59,7 +59,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd }); } - get textEditorModel(): ITextModel { + get textEditorModel(): ITextModel | null { return this.textEditorModelHandle ? this.modelService.getModel(this.textEditorModelHandle) : null; } @@ -68,7 +68,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd /** * Creates the text editor model with the provided value, modeId (can be comma separated for multiple values) and optional resource URL. */ - protected createTextEditorModel(value: ITextBufferFactory, resource?: URI, modeId?: string): EditorModel { + protected createTextEditorModel(value: ITextBufferFactory, resource: URI, modeId?: string): EditorModel { const firstLineText = this.getFirstLineText(value); const languageSelection = this.getOrCreateMode(this.modeService, modeId, firstLineText); @@ -111,7 +111,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd * * @param firstLineText optional first line of the text buffer to set the mode on. This can be used to guess a mode from content. */ - protected getOrCreateMode(modeService: IModeService, modeId: string, firstLineText?: string): ILanguageSelection { + protected getOrCreateMode(modeService: IModeService, modeId: string | undefined, firstLineText?: string): ILanguageSelection { return modeService.create(modeId); } @@ -135,7 +135,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd return null; } - isResolved(): boolean { + isResolved(): this is IActiveTextEditorModel { return !!this.textEditorModelHandle; } diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index 28142311db4..93494c3bbc7 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -13,7 +13,7 @@ import { Range } from 'vs/editor/common/core/range'; import { EndOfLineSequence, IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; import { isResourceFileEdit, isResourceTextEdit, ResourceFileEdit, ResourceTextEdit, WorkspaceEdit } from 'vs/editor/common/modes'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { ITextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; import { localize } from 'vs/nls'; import { IFileService } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -53,7 +53,7 @@ class ModelEditTask implements IDisposable { private _expectedModelVersionId: number | undefined; protected _newEol: EndOfLineSequence; - constructor(private readonly _modelReference: IReference) { + constructor(private readonly _modelReference: IReference) { this._model = this._modelReference.object.textEditorModel; this._edits = []; } @@ -115,7 +115,7 @@ class EditorEditTask extends ModelEditTask { private _editor: ICodeEditor; - constructor(modelReference: IReference, editor: ICodeEditor) { + constructor(modelReference: IReference, editor: ICodeEditor) { super(modelReference); this._editor = editor; } diff --git a/src/vs/workbench/services/configuration/node/jsonEditingService.ts b/src/vs/workbench/services/configuration/node/jsonEditingService.ts index c02b276b524..e12ed97cf59 100644 --- a/src/vs/workbench/services/configuration/node/jsonEditingService.ts +++ b/src/vs/workbench/services/configuration/node/jsonEditingService.ts @@ -17,7 +17,7 @@ import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IFileService } from 'vs/platform/files/common/files'; -import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IJSONEditingService, IJSONValue, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing'; import { ITextModel } from 'vs/editor/common/model'; @@ -83,7 +83,7 @@ export class JSONEditingService implements IJSONEditingService { return setProperty(model.getValue(), [key], value, { tabSize, insertSpaces, eol }); } - private async resolveModelReference(resource: URI): Promise> { + private async resolveModelReference(resource: URI): Promise> { const exists = await this.fileService.existsFile(resource); if (!exists) { await this.fileService.updateContent(resource, '{}', { encoding: encoding.UTF8 }); @@ -97,18 +97,18 @@ export class JSONEditingService implements IJSONEditingService { return parseErrors.length > 0; } - private resolveAndValidate(resource: URI, checkDirty: boolean): Promise> { + private resolveAndValidate(resource: URI, checkDirty: boolean): Promise> { return this.resolveModelReference(resource) .then(reference => { const model = reference.object.textEditorModel; if (this.hasParseErrors(model)) { - return this.reject>(JSONEditingErrorCode.ERROR_INVALID_FILE); + return this.reject>(JSONEditingErrorCode.ERROR_INVALID_FILE); } // Target cannot be dirty if not writing into buffer if (checkDirty && this.textFileService.isDirty(resource)) { - return this.reject>(JSONEditingErrorCode.ERROR_FILE_DIRTY); + return this.reject>(JSONEditingErrorCode.ERROR_FILE_DIRTY); } return reference; }); diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index e7f9af79cf3..d492662209f 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -70,7 +70,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil private saveSequentializer: SaveSequentializer; private disposed: boolean; private lastSaveAttemptTime: number; - private createTextEditorModelPromise: Promise; + private createTextEditorModelPromise: Promise | null; private inConflictMode: boolean; private inOrphanMode: boolean; private inErrorMode: boolean; @@ -435,7 +435,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.updateSavedVersionId(); } - private doCreateTextModel(resource: URI, value: ITextBufferFactory, backup: URI): Promise { + private doCreateTextModel(resource: URI, value: ITextBufferFactory, backup: URI | undefined): Promise { this.logService.trace('load() - created text editor model', this.resource); this.createTextEditorModelPromise = this.doLoadBackup(backup).then(backupContent => { @@ -443,7 +443,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Create model const hasBackupContent = !!backupContent; - this.createTextEditorModel(hasBackupContent ? backupContent : value, resource); + this.createTextEditorModel(backupContent ? backupContent : value, resource); // We restored a backup so we have to set the model as being dirty // We also want to trigger auto save if it is enabled to simulate the exact same behaviour @@ -480,15 +480,15 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // where `value` was captured in the content change listener closure scope. // Content Change - this._register(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged())); + this._register(this.textEditorModel!.onDidChangeContent(() => this.onModelContentChanged())); } - private doLoadBackup(backup: URI): Promise { + private doLoadBackup(backup: URI | undefined): Promise { if (!backup) { return Promise.resolve(null); } - return this.backupFileService.resolveBackupContent(backup).then(backupContent => backupContent, error => null /* ignore errors */); + return this.backupFileService.resolveBackupContent(backup).then(backupContent => backupContent || null, error => null /* ignore errors */); } protected getOrCreateMode(modeService: IModeService, preferredModeIds: string | undefined, firstLineText?: string): ILanguageSelection { @@ -511,7 +511,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // In this case we clear the dirty flag and emit a SAVED event to indicate this state. // Note: we currently only do this check when auto-save is turned off because there you see // a dirty indicator that you want to get rid of when undoing to the saved version. - if (!this.autoSaveAfterMilliesEnabled && this.textEditorModel.getAlternativeVersionId() === this.bufferSavedVersionId) { + if (!this.autoSaveAfterMilliesEnabled && this.textEditorModel!.getAlternativeVersionId() === this.bufferSavedVersionId) { this.logService.trace('onModelContentChanged() - model content changed back to last saved version', this.resource); // Clear flags @@ -609,7 +609,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil if (this.saveSequentializer.hasPendingSave(versionId)) { this.logService.trace(`doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`, this.resource); - return this.saveSequentializer.pendingSave; + return this.saveSequentializer.pendingSave || Promise.resolve(undefined); } // Return early if not dirty (unless forced) or version changed meanwhile @@ -643,7 +643,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Push all edit operations to the undo stack so that the user has a chance to // Ctrl+Z back to the saved version. We only do this when auto-save is turned off if (!this.autoSaveAfterMilliesEnabled) { - this.textEditorModel.pushStackElement(); + this.textEditorModel!.pushStackElement(); } // A save participant can still change the model now and since we are so close to saving @@ -698,7 +698,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Save to Disk // mark the save operation as currently pending with the versionId (it might have changed from a save participant triggering) this.logService.trace(`doSave(${versionId}) - before updateContent()`, this.resource); - return this.saveSequentializer.setPending(newVersionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot(), { + return this.saveSequentializer.setPending(newVersionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot()!, { overwriteReadonly: options.overwriteReadonly, overwriteEncoding: options.overwriteEncoding, mtime: this.lastResolvedDiskStat.mtime, @@ -807,7 +807,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return ''; } - private getTelemetryData(reason: number): Object { + private getTelemetryData(reason: number | undefined): Object { const ext = extname(this.resource); const fileName = basename(this.resource); const telemetryData = { @@ -834,7 +834,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private doTouch(versionId: number): Promise { - return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot(), { + return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot()!, { mtime: this.lastResolvedDiskStat.mtime, encoding: this.getEncoding(), etag: this.lastResolvedDiskStat.etag @@ -915,7 +915,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } getETag(): string | null { - return this.lastResolvedDiskStat ? this.lastResolvedDiskStat.etag : null; + return this.lastResolvedDiskStat ? this.lastResolvedDiskStat.etag || null : null; } hasState(state: ModelState): boolean { @@ -1100,8 +1100,8 @@ export class SaveSequentializer { // so that we can return a promise that completes when the save operation // has completed. if (!this._nextSave) { - let promiseResolve: (() => void) | undefined; - let promiseReject: ((error: Error) => void) | undefined; + let promiseResolve: () => void; + let promiseReject: (error: Error) => void; const promise = new Promise((resolve, reject) => { promiseResolve = resolve; promiseReject = reject; @@ -1110,8 +1110,8 @@ export class SaveSequentializer { this._nextSave = { run, promise, - promiseResolve: promiseResolve, - promiseReject: promiseReject + promiseResolve: promiseResolve!, + promiseReject: promiseReject! }; } @@ -1120,7 +1120,7 @@ export class SaveSequentializer { this._nextSave.run = run; } - return this._nextSave.promise; + return this._nextSave!.promise; } } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts index b8f80e3f6b6..f90ff9bc7d6 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts @@ -117,7 +117,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE return 250; } - get(resource: URI): ITextFileEditorModel { + get(resource: URI): ITextFileEditorModel | undefined { return this.mapResourceToModel.get(resource); } @@ -158,7 +158,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE // Install state change listener this.mapResourceToStateChangeListener.set(resource, model.onDidStateChange(state => { - const event = new TextFileModelChangeEvent(model, state); + const event = new TextFileModelChangeEvent(model!, state); switch (state) { case StateChange.DIRTY: this._onModelDirty.fire(event); @@ -183,7 +183,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE // Install model content change listener this.mapResourceToModelContentChangeListener.set(resource, model.onDidContentChange(e => { - this._onModelContentChanged.fire(new TextFileModelChangeEvent(model, e)); + this._onModelContentChanged.fire(new TextFileModelChangeEvent(model!, e)); })); } @@ -207,7 +207,9 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE }, error => { // Free resources of this invalid model - model.dispose(); + if (model) { + model.dispose(); + } // Remove from pending loads this.mapResourceToPendingModelLoaders.delete(resource); diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 43d88b808ae..a51df6695ac 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -189,7 +189,7 @@ export interface ITextFileEditorModelManager { onModelsSaved: Event; onModelsReverted: Event; - get(resource: URI): ITextFileEditorModel; + get(resource: URI): ITextFileEditorModel | undefined; getAll(resource?: URI): ITextFileEditorModel[]; @@ -240,7 +240,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport updatePreferredEncoding(encoding: string): void; - save(options?: ISaveOptions): Promise; + save(options?: ISaveOptions): Promise | undefined; load(options?: ILoadOptions): Promise; From 0e6253f84a6f825478d9fd6dc8c457e706202c9d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Mar 2019 08:25:20 +0100 Subject: [PATCH 078/290] fix #69328 --- src/vs/base/node/storage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/node/storage.ts b/src/vs/base/node/storage.ts index 546396f1959..5197db44743 100644 --- a/src/vs/base/node/storage.ts +++ b/src/vs/base/node/storage.ts @@ -352,7 +352,7 @@ export class SQLiteStorageDatabase implements IStorageDatabase { rows.forEach(row => items.set(row.key, row.value)); if (this.logger.isTracing) { - this.logger.trace(`[storage ${this.name}] getItems(): ${mapToString(items)}`); + this.logger.trace(`[storage ${this.name}] getItems(): ${items.size} rows`); } return items; From b0bd70e6d8fd203781389629b326f262642e05cb Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Mar 2019 08:28:44 +0100 Subject: [PATCH 079/290] debt - Buffer requires /node/ layer --- src/tsconfig.strictNullChecks.json | 2 +- .../services/extensions/electron-browser/extensionHost.ts | 2 +- .../workbench/services/extensions/node/extensionHostProcess.ts | 2 +- .../extensions/{common => node}/extensionHostProtocol.ts | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/vs/workbench/services/extensions/{common => node}/extensionHostProtocol.ts (100%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 315d356b476..05f40f7f586 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -340,7 +340,6 @@ "./vs/workbench/services/editor/common/editorGroupsService.ts", "./vs/workbench/services/editor/common/editorService.ts", "./vs/workbench/services/extensionManagement/node/multiExtensionManagement.ts", - "./vs/workbench/services/extensions/common/extensionHostProtocol.ts", "./vs/workbench/services/extensions/common/extensions.ts", "./vs/workbench/services/extensions/common/extensionsRegistry.ts", "./vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts", @@ -350,6 +349,7 @@ "./vs/workbench/services/extensions/node/extensionDescriptionRegistry.ts", "./vs/workbench/services/extensions/node/extensionManagementServerService.ts", "./vs/workbench/services/extensions/node/extensionPoints.ts", + "./vs/workbench/services/extensions/node/extensionHostProtocol.ts", "./vs/workbench/services/extensions/node/lazyPromise.ts", "./vs/workbench/services/extensions/node/proxyIdentifier.ts", "./vs/workbench/services/extensions/node/rpcProtocol.ts", diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index f889ee4c832..43324615a90 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -33,7 +33,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IInitData } from 'vs/workbench/api/node/extHost.protocol'; -import { MessageType, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; +import { MessageType, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/node/extensionHostProtocol'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; export interface IExtensionHostStarter { diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcess.ts b/src/vs/workbench/services/extensions/node/extensionHostProcess.ts index 484cef96b1c..dab5ec2b636 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcess.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcess.ts @@ -11,7 +11,7 @@ import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/ipc'; import { Protocol } from 'vs/base/parts/ipc/node/ipc.net'; import product from 'vs/platform/product/node/product'; import { IInitData } from 'vs/workbench/api/node/extHost.protocol'; -import { MessageType, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/common/extensionHostProtocol'; +import { MessageType, createMessageOfType, isMessageOfType } from 'vs/workbench/services/extensions/node/extensionHostProtocol'; import { exit, ExtensionHostMain } from 'vs/workbench/services/extensions/node/extensionHostMain'; // With Electron 2.x and node.js 8.x the "natives" module diff --git a/src/vs/workbench/services/extensions/common/extensionHostProtocol.ts b/src/vs/workbench/services/extensions/node/extensionHostProtocol.ts similarity index 100% rename from src/vs/workbench/services/extensions/common/extensionHostProtocol.ts rename to src/vs/workbench/services/extensions/node/extensionHostProtocol.ts From ba066625bfb83037f547bb31b67b762be5a948f8 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Mar 2019 08:36:15 +0100 Subject: [PATCH 080/290] :lipstick: --- src/vs/base/common/extpath.ts | 6 +++--- src/vs/base/node/extfs.ts | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/base/common/extpath.ts b/src/vs/base/common/extpath.ts index eaf31396842..ab554f756bf 100644 --- a/src/vs/base/common/extpath.ts +++ b/src/vs/base/common/extpath.ts @@ -6,7 +6,7 @@ import { isWindows } from 'vs/base/common/platform'; import { startsWithIgnoreCase, equalsIgnoreCase } from 'vs/base/common/strings'; import { CharCode } from 'vs/base/common/charCode'; -import { sep } from 'vs/base/common/path'; +import { sep, posix } from 'vs/base/common/path'; function isPathSeparator(code: number) { return code === CharCode.Slash || code === CharCode.Backslash; @@ -18,7 +18,7 @@ function isPathSeparator(code: number) { * Using it on a Linux or MaxOS path might change it. */ export function toSlashes(osPath: string) { - return osPath.replace(/[\\/]/g, '/'); + return osPath.replace(/[\\/]/g, posix.sep); } /** @@ -26,7 +26,7 @@ export function toSlashes(osPath: string) { * `getRoot('files:///files/path') === files:///`, * or `getRoot('\\server\shares\path') === \\server\shares\` */ -export function getRoot(path: string, sep: string = '/'): string { +export function getRoot(path: string, sep: string = posix.sep): string { if (!path) { return ''; diff --git a/src/vs/base/node/extfs.ts b/src/vs/base/node/extfs.ts index 866ba70ddc9..a42ed5d8f95 100644 --- a/src/vs/base/node/extfs.ts +++ b/src/vs/base/node/extfs.ts @@ -219,7 +219,7 @@ export function del(path: string, tmpFolder: string, callback: (error: Error | n } function rmRecursive(path: string, callback: (error: Error | null) => void): void { - if (path === '\\' || path === '/') { + if (path === paths.win32.sep || path === paths.posix.sep) { return callback(new Error('Will not delete root!')); } @@ -277,6 +277,10 @@ function rmRecursive(path: string, callback: (error: Error | null) => void): voi } export function delSync(path: string): void { + if (path === paths.win32.sep || path === paths.posix.sep) { + throw new Error('Will not delete root!'); + } + try { const stat = fs.lstatSync(path); if (stat.isDirectory() && !stat.isSymbolicLink()) { From e4b70bca4a0a40836c7aae2b98ebaca824c488de Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Mar 2019 09:13:33 +0100 Subject: [PATCH 081/290] fix #69334 --- .../editor/common/services/getIconClasses.ts | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/common/services/getIconClasses.ts b/src/vs/editor/common/services/getIconClasses.ts index d8f7d5bf122..ca49de2528f 100644 --- a/src/vs/editor/common/services/getIconClasses.ts +++ b/src/vs/editor/common/services/getIconClasses.ts @@ -12,9 +12,11 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { FileKind } from 'vs/platform/files/common/files'; export function getIconClasses(modelService: IModelService, modeService: IModeService, resource: uri | undefined, fileKind?: FileKind): string[] { + // we always set these base classes even if we do not have a path const classes = fileKind === FileKind.ROOT_FOLDER ? ['rootfolder-icon'] : fileKind === FileKind.FOLDER ? ['folder-icon'] : ['file-icon']; if (resource) { + // Get the path and name of the resource. For data-URIs, we need to parse specially let name: string | undefined; let path: string | undefined; @@ -22,17 +24,19 @@ export function getIconClasses(modelService: IModelService, modeService: IModeSe const metadata = DataUri.parseMetaData(resource); name = metadata.get(DataUri.META_DATA_LABEL); path = name; - } - else { + } else { name = cssEscape(basenameOrAuthority(resource).toLowerCase()); path = resource.path.toLowerCase(); } + // Folders if (fileKind === FileKind.FOLDER) { classes.push(`${name}-name-folder-icon`); } + // Files else { + // Name & Extension(s) if (name) { classes.push(`${name}-name-file-icon`); @@ -42,8 +46,9 @@ export function getIconClasses(modelService: IModelService, modeService: IModeSe } classes.push(`ext-file-icon`); // extra segment to increase file-ext score } + // Configured Language - let configuredLangId: string | null = getConfiguredLangId(modelService, resource); + let configuredLangId: string | null = getConfiguredLangId(modelService, modeService, resource); configuredLangId = configuredLangId || (path ? modeService.getModeIdByFilepathOrFirstLine(path) : null); if (configuredLangId) { classes.push(`${cssEscape(configuredLangId)}-lang-file-icon`); @@ -53,16 +58,32 @@ export function getIconClasses(modelService: IModelService, modeService: IModeSe return classes; } -export function getConfiguredLangId(modelService: IModelService, resource: uri): string | null { +export function getConfiguredLangId(modelService: IModelService, modeService: IModeService, resource: uri): string | null { let configuredLangId: string | null = null; if (resource) { - const model = modelService.getModel(resource); - if (model) { - const modeId = model.getLanguageIdentifier().language; - if (modeId && modeId !== PLAINTEXT_MODE_ID) { - configuredLangId = modeId; // only take if the mode is specific (aka no just plain text) + let modeId: string | null = null; + + // Data URI: check for encoded metadata + if (resource.scheme === Schemas.data) { + const metadata = DataUri.parseMetaData(resource); + const mime = metadata.get(DataUri.META_DATA_MIME); + + if (mime) { + modeId = modeService.getModeId(mime); } } + + // Any other URI: check for model if existing + else { + const model = modelService.getModel(resource); + if (model) { + modeId = model.getLanguageIdentifier().language; + } + } + + if (modeId && modeId !== PLAINTEXT_MODE_ID) { + configuredLangId = modeId; // only take if the mode is specific (aka no just plain text) + } } return configuredLangId; From 4585f69a82082487d317c8854d8aa4d2eee25591 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 23 Feb 2019 15:56:03 +0100 Subject: [PATCH 082/290] fix compile error --- 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 97f0a3e9d6a..f24e0dee22e 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -386,7 +386,7 @@ class ResourceLabelWidget extends IconLabel { } if (this.label) { - const configuredLangId = this.label.resource ? getConfiguredLangId(this.modelService, this.label.resource) : null; + const configuredLangId = this.label.resource ? getConfiguredLangId(this.modelService, this.modeService, this.label.resource) : null; if (this.lastKnownConfiguredLangId !== configuredLangId) { clearIconCache = true; this.lastKnownConfiguredLangId = configuredLangId || undefined; From 900d58bfe522e812acedf8720076590d853787b3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 23 Feb 2019 15:56:03 +0100 Subject: [PATCH 083/290] debt - declare more services via registerSingleton() --- src/vs/base/common/path.ts | 47 ++++------- src/vs/base/common/process.ts | 27 +++++++ .../workbench/api/node/extHostDebugService.ts | 2 +- .../codeEditor/browser/selectionClipboard.ts | 1 + .../codeInset.contribution.ts | 2 +- .../workbench/electron-browser/workbench.ts | 80 ------------------- .../electron-browser/broadcastService.ts | 12 ++- .../browser/configurationResolverService.ts | 13 +-- .../common/variableResolver.ts | 3 +- .../configurationResolverService.test.ts | 32 +++++--- .../decorations/browser/decorationsService.ts | 7 +- .../dialogs/electron-browser/dialogService.ts | 2 +- .../editor/browser/codeEditorService.ts | 6 +- .../inactiveExtensionUrlHandler.ts | 3 + .../preferences/browser/preferencesService.ts | 6 +- .../progress/browser/progressService2.ts | 3 + .../services/search/node/searchService.ts | 3 + .../workspace/node/workspaceEditingService.ts | 3 + src/vs/workbench/workbench.main.ts | 33 ++++++++ 19 files changed, 148 insertions(+), 137 deletions(-) create mode 100644 src/vs/base/common/process.ts diff --git a/src/vs/base/common/path.ts b/src/vs/base/common/path.ts index a93084c42b7..844cdd246a9 100644 --- a/src/vs/base/common/path.ts +++ b/src/vs/base/common/path.ts @@ -29,7 +29,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { isWindows } from 'vs/base/common/platform'; +import * as process from 'vs/base/common/process'; const CHAR_UPPERCASE_A = 65;/* A */ const CHAR_LOWERCASE_A = 97; /* a */ @@ -41,19 +41,6 @@ const CHAR_BACKWARD_SLASH = 92; /* \ */ const CHAR_COLON = 58; /* : */ const CHAR_QUESTION_MARK = 63; /* ? */ -interface IProcess { - cwd(): string; - platform: string; - env: object; -} - -declare let process: IProcess; -const safeProcess: IProcess = (typeof process === 'undefined') ? { - cwd() { return '/'; }, - env: {}, - get platform() { return isWindows ? 'win32' : 'posix'; } -} : process; - class ErrorInvalidArgType extends Error { code: 'ERR_INVALID_ARG_TYPE'; constructor(name: string, expected: string, actual: string) { @@ -219,14 +206,14 @@ export const win32: IPath = { if (i >= 0) { path = pathSegments[i]; } else if (!resolvedDevice) { - path = safeProcess.cwd(); + path = process.cwd(); } else { // Windows has the concept of drive-specific current working // directories. If we've resolved a drive letter but not yet an // absolute path, get cwd for that drive, or the process cwd if // the drive cwd is not available. We're sure the device is not // a UNC path at this points, because UNC paths are always absolute. - path = safeProcess.env['=' + resolvedDevice] || safeProcess.cwd(); + path = process.env['=' + resolvedDevice] || process.cwd(); // Verify that a cwd was found and that it actually points // to our drive. If not, default to the drive's root. @@ -1208,7 +1195,7 @@ export const posix: IPath = { path = pathSegments[i]; } else { - path = safeProcess.cwd(); + path = process.cwd(); } validateString(path, 'path'); @@ -1682,16 +1669,16 @@ export const posix: IPath = { posix.win32 = win32.win32 = win32; posix.posix = win32.posix = posix; -export const normalize = (safeProcess.platform === 'win32' ? win32.normalize : posix.normalize); -export const isAbsolute = (safeProcess.platform === 'win32' ? win32.isAbsolute : posix.isAbsolute); -export const join = (safeProcess.platform === 'win32' ? win32.join : posix.join); -export const resolve = (safeProcess.platform === 'win32' ? win32.resolve : posix.resolve); -export const relative = (safeProcess.platform === 'win32' ? win32.relative : posix.relative); -export const dirname = (safeProcess.platform === 'win32' ? win32.dirname : posix.dirname); -export const basename = (safeProcess.platform === 'win32' ? win32.basename : posix.basename); -export const extname = (safeProcess.platform === 'win32' ? win32.extname : posix.extname); -export const format = (safeProcess.platform === 'win32' ? win32.format : posix.format); -export const parse = (safeProcess.platform === 'win32' ? win32.parse : posix.parse); -export const toNamespacedPath = (safeProcess.platform === 'win32' ? win32.toNamespacedPath : posix.toNamespacedPath); -export const sep = (safeProcess.platform === 'win32' ? win32.sep : posix.sep); -export const delimiter = (safeProcess.platform === 'win32' ? win32.delimiter : posix.delimiter); +export const normalize = (process.platform === 'win32' ? win32.normalize : posix.normalize); +export const isAbsolute = (process.platform === 'win32' ? win32.isAbsolute : posix.isAbsolute); +export const join = (process.platform === 'win32' ? win32.join : posix.join); +export const resolve = (process.platform === 'win32' ? win32.resolve : posix.resolve); +export const relative = (process.platform === 'win32' ? win32.relative : posix.relative); +export const dirname = (process.platform === 'win32' ? win32.dirname : posix.dirname); +export const basename = (process.platform === 'win32' ? win32.basename : posix.basename); +export const extname = (process.platform === 'win32' ? win32.extname : posix.extname); +export const format = (process.platform === 'win32' ? win32.format : posix.format); +export const parse = (process.platform === 'win32' ? win32.parse : posix.parse); +export const toNamespacedPath = (process.platform === 'win32' ? win32.toNamespacedPath : posix.toNamespacedPath); +export const sep = (process.platform === 'win32' ? win32.sep : posix.sep); +export const delimiter = (process.platform === 'win32' ? win32.delimiter : posix.delimiter); diff --git a/src/vs/base/common/process.ts b/src/vs/base/common/process.ts new file mode 100644 index 00000000000..386ad29df56 --- /dev/null +++ b/src/vs/base/common/process.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { isWindows, isMacintosh, setImmediate } from 'vs/base/common/platform'; + +interface IProcess { + platform: string; + env: object; + + cwd(): string; + nextTick(callback: (...args: any[]) => void): number; +} + +declare let process: IProcess; +const safeProcess: IProcess = (typeof process === 'undefined') ? { + cwd(): string { return '/'; }, + env: Object.create(null), + get platform(): string { return isWindows ? 'win32' : isMacintosh ? 'darwin' : 'linux'; }, + nextTick(callback: (...args: any[]) => void): number { return setImmediate(callback); } +} : process; + +export const cwd = safeProcess.cwd; +export const env = safeProcess.env; +export const platform = safeProcess.platform; +export const nextTick = safeProcess.nextTick; diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index 32d93fbbf95..c593cb4bf65 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -909,7 +909,7 @@ export class ExtHostVariableResolverService extends AbstractVariableResolverServ } return undefined; } - }); + }, process.env); } } diff --git a/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts b/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts index a1f46f8ff1d..4c3a8ba75ff 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/selectionClipboard.ts @@ -5,6 +5,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { Disposable } from 'vs/base/common/lifecycle'; +import * as process from 'vs/base/common/process'; import * as platform from 'vs/base/common/platform'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; diff --git a/src/vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution.ts b/src/vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution.ts index bce7c3f7d4f..a0369eaff5e 100644 --- a/src/vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution.ts +++ b/src/vs/workbench/contrib/codeinset/electron-browser/codeInset.contribution.ts @@ -309,7 +309,7 @@ export class CodeInsetController implements editorCommon.IEditorContribution { const widgetPromises = widgetRequests.map(request => { if (request.resolved) { - return Promise.resolve(void 0); + return Promise.resolve(undefined); } let a = new Promise(resolve => { this._pendingWebviews.set(request.symbol.id, element => { diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 7445d7b6645..c1e45f78c1c 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -44,33 +44,23 @@ import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/c import { IActivityService } from 'vs/workbench/services/activity/common/activity'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IFileService } from 'vs/platform/files/common/files'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IProgressService2 } from 'vs/platform/progress/common/progress'; -import { ProgressService2 } from 'vs/workbench/services/progress/browser/progressService2'; import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { LifecyclePhase, StartupKind, ILifecycleService, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; import { IWindowService, IWindowConfiguration, IPath, MenuBarVisibility, getTitleBarStyle, IWindowsService } from 'vs/platform/windows/common/windows'; import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; -import { IMenuService } from 'vs/platform/actions/common/actions'; -import { MenuService } from 'vs/platform/actions/common/menuService'; import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; -import { FileDecorationsService } from 'vs/workbench/services/decorations/browser/decorationsService'; -import { IDecorationsService } from 'vs/workbench/services/decorations/browser/decorations'; import { ActivityService } from 'vs/workbench/services/activity/browser/activityService'; -import { IListService, ListService } from 'vs/platform/list/browser/listService'; import { IViewsService } from 'vs/workbench/common/views'; import { ViewsService } from 'vs/workbench/browser/parts/views/views'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -102,34 +92,21 @@ import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { combinedAppender, LogAppender, NullTelemetryService, configurationTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; -import { IDownloadService } from 'vs/platform/download/common/download'; import { IExtensionGalleryService, IExtensionManagementServerService, IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { CommandService } from 'vs/workbench/services/commands/common/commandService'; -import { IMarkerService } from 'vs/platform/markers/common/markers'; -import { MarkerService } from 'vs/platform/markers/common/markerService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/workbenchModeService'; import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; import { IModelService } from 'vs/editor/common/services/modelService'; import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl'; -import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; -import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; -import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; -import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; -import { ISearchService } from 'vs/workbench/services/search/common/search'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { CodeEditorService } from 'vs/workbench/services/editor/browser/codeEditorService'; -import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { OpenerService } from 'vs/editor/browser/services/openerService'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { HistoryService } from 'vs/workbench/services/history/browser/history'; -import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/workbenchThemeService'; import { IProductService } from 'vs/platform/product/common/product'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; @@ -139,14 +116,12 @@ import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; import { JSONEditingService } from 'vs/workbench/services/configuration/node/jsonEditingService'; -import { WorkspaceEditingService } from 'vs/workbench/services/workspace/node/workspaceEditingService'; import { getDelayedChannel } from 'vs/base/parts/ipc/node/ipc'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties'; import { IRequestService } from 'vs/platform/request/node/request'; -import { DownloadService } from 'vs/platform/download/node/downloadService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/node/remoteAgentService'; import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc'; @@ -154,7 +129,6 @@ import { LogLevelSetterChannel } from 'vs/platform/log/node/logIpc'; import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService'; import { MultiExtensionManagementService } from 'vs/workbench/services/extensionManagement/node/multiExtensionManagement'; -import { SearchService } from 'vs/workbench/services/search/node/searchService'; import { LocalizationsChannelClient } from 'vs/platform/localizations/node/localizationsIpc'; import { AccessibilityService } from 'vs/platform/accessibility/node/accessibilityService'; import { ProductService } from 'vs/platform/product/node/productService'; @@ -164,11 +138,8 @@ import { RemoteFileService } from 'vs/workbench/services/files/node/remoteFileSe // import@electron-browser import { ContextMenuService as NativeContextMenuService } from 'vs/workbench/services/contextmenu/electron-browser/contextmenuService'; import { WorkbenchKeybindingService } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; -import { ClipboardService } from 'vs/platform/clipboard/electron-browser/clipboardService'; import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; -import { IExtensionUrlHandler, ExtensionUrlHandler } from 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler'; import { DialogService, FileDialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService'; -import { IBroadcastService, BroadcastService } from 'vs/workbench/services/broadcast/electron-browser/broadcastService'; import { WindowService } from 'vs/platform/windows/electron-browser/windowService'; import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; @@ -466,12 +437,6 @@ export class Workbench extends Disposable implements IPartService { // Labels serviceCollection.set(ILabelService, new SyncDescriptor(LabelService, undefined, true)); - // Clipboard - serviceCollection.set(IClipboardService, new SyncDescriptor(ClipboardService, undefined, true)); - - // Broadcast - serviceCollection.set(IBroadcastService, new SyncDescriptor(BroadcastService, [this.configuration.windowId], true)); - // Notifications this.notificationService = new NotificationService(); serviceCollection.set(INotificationService, this.notificationService); @@ -527,9 +492,6 @@ export class Workbench extends Disposable implements IPartService { // Request Service serviceCollection.set(IRequestService, new SyncDescriptor(RequestService, undefined, true)); - // Download Service - serviceCollection.set(IDownloadService, new SyncDescriptor(DownloadService, undefined, true)); - // Extension Gallery serviceCollection.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService, undefined, true)); @@ -567,9 +529,6 @@ export class Workbench extends Disposable implements IPartService { // Commands serviceCollection.set(ICommandService, new SyncDescriptor(CommandService, undefined, true)); - // Markers - serviceCollection.set(IMarkerService, new SyncDescriptor(MarkerService, undefined, true)); - // Editor Mode serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl)); @@ -582,38 +541,17 @@ export class Workbench extends Disposable implements IPartService { // Editor Models serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl, undefined, true)); - // Marker Decorations - serviceCollection.set(IMarkerDecorationsService, new SyncDescriptor(MarkerDecorationsService)); - - // Editor Worker - serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl)); - // Untitled Editors serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService, undefined, true)); - // Search - serviceCollection.set(ISearchService, new SyncDescriptor(SearchService)); - - // Code Editor - serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorService, undefined, true)); - - // Opener - serviceCollection.set(IOpenerService, new SyncDescriptor(OpenerService, undefined, true)); - // Localization const localizationsChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('localizations'))); serviceCollection.set(ILocalizationsService, new SyncDescriptor(LocalizationsChannelClient, [localizationsChannel])); - // Hash - // serviceCollection.set(IHashService, new SyncDescriptor(HashService, undefined, true)); - // Status bar this.statusbarPart = this.instantiationService.createInstance(StatusbarPart, Identifiers.STATUSBAR_PART); serviceCollection.set(IStatusbarService, this.statusbarPart); - // Progress 2 - serviceCollection.set(IProgressService2, new SyncDescriptor(ProgressService2)); - // Context Keys this.contextKeyService = this.instantiationService.createInstance(ContextKeyService); serviceCollection.set(IContextKeyService, this.contextKeyService); @@ -622,9 +560,6 @@ export class Workbench extends Disposable implements IPartService { this.keybindingService = this.instantiationService.createInstance(WorkbenchKeybindingService, window); serviceCollection.set(IKeybindingService, this.keybindingService); - // List - serviceCollection.set(IListService, this.instantiationService.createInstance(ListService)); - // Context view service this.contextViewService = this.instantiationService.createInstance(ContextViewService, this.workbench); serviceCollection.set(IContextViewService, this.contextViewService); @@ -636,9 +571,6 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IContextMenuService, new SyncDescriptor(NativeContextMenuService)); } - // Menus/Actions - serviceCollection.set(IMenuService, new SyncDescriptor(MenuService, undefined, true)); - // Sidebar part this.sidebarPart = this.instantiationService.createInstance(SidebarPart, Identifiers.SIDEBAR_PART); @@ -693,24 +625,12 @@ export class Workbench extends Disposable implements IPartService { // Text File Service serviceCollection.set(ITextFileService, new SyncDescriptor(TextFileService)); - // File Decorations - serviceCollection.set(IDecorationsService, new SyncDescriptor(FileDecorationsService)); - - // Inactive extension URL handler - serviceCollection.set(IExtensionUrlHandler, new SyncDescriptor(ExtensionUrlHandler)); - // Text Model Resolver Service serviceCollection.set(ITextModelService, new SyncDescriptor(TextModelResolverService, undefined, true)); // JSON Editing serviceCollection.set(IJSONEditingService, new SyncDescriptor(JSONEditingService, undefined, true)); - // Workspace Editing - serviceCollection.set(IWorkspaceEditingService, new SyncDescriptor(WorkspaceEditingService, undefined, true)); - - // Configuration Resolver - serviceCollection.set(IConfigurationResolverService, new SyncDescriptor(ConfigurationResolverService, [process.env], true)); - // Quick open service (quick open controller) this.quickOpen = this.instantiationService.createInstance(QuickOpenController); serviceCollection.set(IQuickOpenService, this.quickOpen); diff --git a/src/vs/workbench/services/broadcast/electron-browser/broadcastService.ts b/src/vs/workbench/services/broadcast/electron-browser/broadcastService.ts index a22264520c3..8c1b3c9f6aa 100644 --- a/src/vs/workbench/services/broadcast/electron-browser/broadcastService.ts +++ b/src/vs/workbench/services/broadcast/electron-browser/broadcastService.ts @@ -8,6 +8,8 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ipcRenderer as ipc } from 'electron'; import { ILogService } from 'vs/platform/log/common/log'; import { Disposable } from 'vs/base/common/lifecycle'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IWindowService } from 'vs/platform/windows/common/windows'; export const IBroadcastService = createDecorator('broadcastService'); @@ -30,12 +32,16 @@ export class BroadcastService extends Disposable implements IBroadcastService { private readonly _onBroadcast: Emitter = this._register(new Emitter()); get onBroadcast(): Event { return this._onBroadcast.event; } + private windowId: number; + constructor( - private windowId: number, + @IWindowService readonly windowService: IWindowService, @ILogService private readonly logService: ILogService ) { super(); + this.windowId = windowService.getCurrentWindowId(); + this.registerListeners(); } @@ -55,4 +61,6 @@ export class BroadcastService extends Disposable implements IBroadcastService { payload: b.payload }); } -} \ No newline at end of file +} + +registerSingleton(IBroadcastService, BroadcastService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index 24b3264415f..71aa1fd6d00 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -6,7 +6,6 @@ import { URI as uri } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; -import * as platform from 'vs/base/common/platform'; import * as Types from 'vs/base/common/types'; import { Schemas } from 'vs/base/common/network'; import { toResource } from 'vs/workbench/common/editor'; @@ -20,14 +19,16 @@ import { AbstractVariableResolverService } from 'vs/workbench/services/configura import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { IQuickInputService, IInputOptions, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; -import { ConfiguredInput } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import { ConfiguredInput, IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class ConfigurationResolverService extends AbstractVariableResolverService { static INPUT_OR_COMMAND_VARIABLES_PATTERN = /\${((input|command):(.*?))}/g; constructor( - envVariables: platform.IProcessEnvironment, + @IWindowService windowService: IWindowService, @IEditorService editorService: IEditorService, @IEnvironmentService environmentService: IEnvironmentService, @IConfigurationService private readonly configurationService: IConfigurationService, @@ -79,7 +80,7 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic } return undefined; } - }, envVariables); + }, windowService.getConfiguration().userEnv); } public resolveWithInteractionReplace(folder: IWorkspaceFolder, config: any, section?: string, variables?: IStringDictionary): Promise { @@ -287,4 +288,6 @@ export class ConfigurationResolverService extends AbstractVariableResolverServic } return Promise.reject(new Error(nls.localize('inputVariable.undefinedVariable', "Undefined input variable '{0}' encountered. Remove or define '{0}' to continue.", variable))); } -} \ No newline at end of file +} + +registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts index 88d1c2de2f0..82e83a3c2cd 100644 --- a/src/vs/workbench/services/configurationResolver/common/variableResolver.ts +++ b/src/vs/workbench/services/configurationResolver/common/variableResolver.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as paths from 'vs/base/common/path'; +import * as process from 'vs/base/common/process'; import * as types from 'vs/base/common/types'; import * as objects from 'vs/base/common/objects'; import { IStringDictionary } from 'vs/base/common/collections'; @@ -32,7 +33,7 @@ export class AbstractVariableResolverService implements IConfigurationResolverSe constructor( private _context: IVariableResolveContext, - private _envVariables: IProcessEnvironment = process.env + private _envVariables: IProcessEnvironment ) { if (isWindows) { this._envVariables = Object.create(null); diff --git a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts index af81556238a..4fc62f2dfbc 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-browser/configurationResolverService.test.ts @@ -11,16 +11,18 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { TestEnvironmentService, TestEditorService, TestContextService } from 'vs/workbench/test/workbenchTestServices'; +import { TestEnvironmentService, TestEditorService, TestContextService, TestWindowService } from 'vs/workbench/test/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { Disposable } from 'vs/base/common/lifecycle'; import { IQuickInputService, IQuickPickItem, QuickPickInput, IPickOptions, Omit, IInputOptions, IQuickInputButton, IQuickPick, IInputBox, IQuickNavigateConfiguration } from 'vs/platform/quickinput/common/quickInput'; import { CancellationToken } from 'vs/base/common/cancellation'; import * as Types from 'vs/base/common/types'; +import { IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows'; suite('Configuration Resolver Service', () => { let configurationResolverService: IConfigurationResolverService | null; let envVariables: { [key: string]: string } = { key1: 'Value for key1', key2: 'Value for key2' }; + let windowService: IWindowService; let mockCommandService: MockCommandService; let editorService: TestEditorService; let workspace: IWorkspaceFolder; @@ -30,13 +32,14 @@ suite('Configuration Resolver Service', () => { mockCommandService = new MockCommandService(); editorService = new TestEditorService(); quickInputService = new MockQuickInputService(); + windowService = new MockWindowService(envVariables); workspace = { uri: uri.parse('file:///VSCode/workspaceLocation'), name: 'hey', index: 0, toResource: () => null }; - configurationResolverService = new ConfigurationResolverService(envVariables, editorService, TestEnvironmentService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(), quickInputService); + configurationResolverService = new ConfigurationResolverService(windowService, editorService, TestEnvironmentService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(), quickInputService); }); teardown(() => { @@ -120,7 +123,7 @@ suite('Configuration Resolver Service', () => { } }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} xyz'), 'abc foo xyz'); }); @@ -137,7 +140,7 @@ suite('Configuration Resolver Service', () => { } }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo bar xyz'); }); @@ -154,7 +157,7 @@ suite('Configuration Resolver Service', () => { } }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); if (platform.isWindows) { assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${workspaceFolder} ${env:key1} xyz'), 'abc foo \\VSCode\\workspaceLocation Value for key1 xyz'); } else { @@ -175,7 +178,7 @@ suite('Configuration Resolver Service', () => { } }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); if (platform.isWindows) { assert.strictEqual(service.resolve(workspace, '${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} ${workspaceFolder} - ${workspaceFolder} ${env:key1} - ${env:key2}'), 'foo bar \\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for key1 - Value for key2'); } else { @@ -209,7 +212,7 @@ suite('Configuration Resolver Service', () => { } }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${config:editor.lineNumbers} ${config:editor.insertSpaces} xyz'), 'abc foo 123 false xyz'); }); @@ -219,7 +222,7 @@ suite('Configuration Resolver Service', () => { editor: {} }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); assert.strictEqual(service.resolve(workspace, 'abc ${unknownVariable} xyz'), 'abc ${unknownVariable} xyz'); assert.strictEqual(service.resolve(workspace, 'abc ${env:unknownVariable} xyz'), 'abc xyz'); }); @@ -232,7 +235,7 @@ suite('Configuration Resolver Service', () => { } }); - let service = new ConfigurationResolverService(envVariables, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); + let service = new ConfigurationResolverService(windowService, new TestEditorService(), TestEnvironmentService, configurationService, mockCommandService, new TestContextService(), quickInputService); assert.throws(() => service.resolve(workspace, 'abc ${env} xyz')); assert.throws(() => service.resolve(workspace, 'abc ${env:} xyz')); @@ -611,3 +614,14 @@ class MockInputsConfigurationService extends TestConfigurationService { return configuration; } } + +class MockWindowService extends TestWindowService { + + constructor(private env: platform.IProcessEnvironment) { + super(); + } + + getConfiguration(): IWindowConfiguration { + return { userEnv: this.env } as IWindowConfiguration; + } +} diff --git a/src/vs/workbench/services/decorations/browser/decorationsService.ts b/src/vs/workbench/services/decorations/browser/decorationsService.ts index e0ef2f3814f..5b3859f5fd8 100644 --- a/src/vs/workbench/services/decorations/browser/decorationsService.ts +++ b/src/vs/workbench/services/decorations/browser/decorationsService.ts @@ -18,6 +18,7 @@ import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import { localize } from 'vs/nls'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; class DecorationRule { @@ -353,8 +354,7 @@ export class FileDecorationsService implements IDecorationsService { ); constructor( - @IThemeService themeService: IThemeService, - cleanUpCount: number = 17 + @IThemeService themeService: IThemeService ) { this._decorationStyles = new DecorationStyles(themeService); @@ -362,7 +362,7 @@ export class FileDecorationsService implements IDecorationsService { // css styles that we don't need anymore let count = 0; let reg = this.onDidChangeDecorations(() => { - if (++count % cleanUpCount === 0) { + if (++count % 17 === 0) { this._decorationStyles.cleanUp(this._data.iterator()); } }); @@ -442,3 +442,4 @@ function getColor(theme: ITheme, color: string | undefined) { return 'inherit'; } +registerSingleton(IDecorationsService, FileDecorationsService); \ No newline at end of file diff --git a/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts b/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts index 4d16b57ee49..cec0ec1ff07 100644 --- a/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts +++ b/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts @@ -362,7 +362,7 @@ export class FileDialogService implements IFileDialogService { if (urisToOpen) { return this.windowService.openWindow(urisToOpen, { forceNewWindow, forceOpenWorkspaceAsFile }); } - return void 0; + return undefined; }); } diff --git a/src/vs/workbench/services/editor/browser/codeEditorService.ts b/src/vs/workbench/services/editor/browser/codeEditorService.ts index 0c98821626b..fe5bb0a5372 100644 --- a/src/vs/workbench/services/editor/browser/codeEditorService.ts +++ b/src/vs/workbench/services/editor/browser/codeEditorService.ts @@ -10,6 +10,8 @@ import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TextEditorOptions } from 'vs/workbench/common/editor'; import { ACTIVE_GROUP, IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class CodeEditorService extends CodeEditorServiceImpl { @@ -72,4 +74,6 @@ export class CodeEditorService extends CodeEditorServiceImpl { return null; }); } -} \ No newline at end of file +} + +registerSingleton(ICodeEditorService, CodeEditorService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts b/src/vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts index 80700c6aa9a..2713af6dad8 100644 --- a/src/vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts @@ -17,6 +17,7 @@ import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; const FIVE_MINUTES = 5 * 60 * 1000; const THIRTY_SECONDS = 30 * 1000; @@ -271,3 +272,5 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { this.uriBuffer.clear(); } } + +registerSingleton(IExtensionUrlHandler, ExtensionUrlHandler); \ No newline at end of file diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index ee6c999089f..9646b53859d 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -45,7 +45,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic private lastOpenedSettingsInput: PreferencesEditorInput | null = null; - private readonly _onDispose = new Emitter(); + private readonly _onDispose = this._register(new Emitter()); private _defaultUserSettingsUriCounter = 0; private _defaultUserSettingsContentModel: DefaultSettings; @@ -74,14 +74,14 @@ export class PreferencesService extends Disposable implements IPreferencesServic super(); // The default keybindings.json updates based on keyboard layouts, so here we make sure // if a model has been given out we update it accordingly. - keybindingService.onDidUpdateKeybindings(() => { + this._register(keybindingService.onDidUpdateKeybindings(() => { const model = modelService.getModel(this.defaultKeybindingsResource); if (!model) { // model has not been given out => nothing to do return; } modelService.updateModel(model, defaultKeybindingsContents(keybindingService)); - }); + })); } readonly defaultKeybindingsResource = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/keybindings.json' }); diff --git a/src/vs/workbench/services/progress/browser/progressService2.ts b/src/vs/workbench/services/progress/browser/progressService2.ts index da77ec66b8d..f61446ca4b9 100644 --- a/src/vs/workbench/services/progress/browser/progressService2.ts +++ b/src/vs/workbench/services/progress/browser/progressService2.ts @@ -15,6 +15,7 @@ import { ProgressBadge, IActivityService } from 'vs/workbench/services/activity/ import { INotificationService, Severity, INotificationHandle, INotificationActions } from 'vs/platform/notification/common/notification'; import { Action } from 'vs/base/common/actions'; import { Event } from 'vs/base/common/event'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class ProgressService2 implements IProgressService2 { @@ -267,3 +268,5 @@ export class ProgressService2 implements IProgressService2 { return promise; } } + +registerSingleton(IProgressService2, ProgressService2, true); \ 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 3eaafa4f31e..a61f1d7a986 100644 --- a/src/vs/workbench/services/search/node/searchService.ts +++ b/src/vs/workbench/services/search/node/searchService.ts @@ -29,6 +29,7 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un import { IRawSearchService, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess } from './search'; import { SearchChannelClient } from './searchIpc'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class SearchService extends Disposable implements ISearchService { _serviceBrand: any; @@ -586,3 +587,5 @@ export class DiskSearch implements ISearchResultProvider { return this.raw.clearCache(cacheKey); } } + +registerSingleton(ISearchService, SearchService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts index c91fa335414..a1884b928a5 100644 --- a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts @@ -26,6 +26,7 @@ import { isEqual, basename } from 'vs/base/common/resources'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IFileService } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class WorkspaceEditingService implements IWorkspaceEditingService { @@ -329,3 +330,5 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { return this.jsonEditingService.write(toWorkspace.configPath, { key: 'settings', value: targetWorkspaceConfiguration }, true); } } + +registerSingleton(IWorkspaceEditingService, WorkspaceEditingService, true); \ No newline at end of file diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index cf08e9d08ee..cbf781391bd 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -38,12 +38,45 @@ import 'vs/workbench/api/browser/viewsExtensionPoint'; //#region --- workbench services +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IMenuService } from 'vs/platform/actions/common/actions'; +import { MenuService } from 'vs/platform/actions/common/menuService'; +import { IListService, ListService } from 'vs/platform/list/browser/listService'; +import { OpenerService } from 'vs/editor/browser/services/openerService'; +import { IOpenerService } from 'vs/platform/opener/common/opener'; +import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; +import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl'; +import { MarkerDecorationsService } from 'vs/editor/common/services/markerDecorationsServiceImpl'; +import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; +import { IMarkerService } from 'vs/platform/markers/common/markers'; +import { MarkerService } from 'vs/platform/markers/common/markerService'; +import { IDownloadService } from 'vs/platform/download/common/download'; +import { DownloadService } from 'vs/platform/download/node/downloadService'; import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; import 'vs/workbench/services/integrity/node/integrityService'; import 'vs/workbench/services/keybinding/common/keybindingEditing'; import 'vs/workbench/services/hash/node/hashService'; import 'vs/workbench/services/textMate/electron-browser/textMateService'; +import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; +import 'vs/workbench/services/workspace/node/workspaceEditingService'; +import 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler'; +import 'vs/workbench/services/decorations/browser/decorationsService'; +import 'vs/workbench/services/search/node/searchService'; +import 'vs/workbench/services/progress/browser/progressService2'; +import 'vs/workbench/services/editor/browser/codeEditorService'; +import 'vs/workbench/services/broadcast/electron-browser/broadcastService'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ClipboardService } from 'vs/platform/clipboard/electron-browser/clipboardService'; + +registerSingleton(IMenuService, MenuService, true); +registerSingleton(IListService, ListService, true); +registerSingleton(IOpenerService, OpenerService, true); +registerSingleton(IEditorWorkerService, EditorWorkerServiceImpl); +registerSingleton(IMarkerDecorationsService, MarkerDecorationsService); +registerSingleton(IMarkerService, MarkerService, true); +registerSingleton(IDownloadService, DownloadService, true); +registerSingleton(IClipboardService, ClipboardService, true); //#endregion From 9c1b8851eb7521aecff46d02f4bac15513ef15f3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Mar 2019 09:50:12 +0100 Subject: [PATCH 084/290] :lipstick: imports --- src/vs/workbench/workbench.main.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index cbf781391bd..178d700f976 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -52,6 +52,8 @@ import { IMarkerService } from 'vs/platform/markers/common/markers'; import { MarkerService } from 'vs/platform/markers/common/markerService'; import { IDownloadService } from 'vs/platform/download/common/download'; import { DownloadService } from 'vs/platform/download/node/downloadService'; +import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ClipboardService } from 'vs/platform/clipboard/electron-browser/clipboardService'; import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; import 'vs/workbench/services/integrity/node/integrityService'; @@ -66,8 +68,6 @@ import 'vs/workbench/services/search/node/searchService'; import 'vs/workbench/services/progress/browser/progressService2'; import 'vs/workbench/services/editor/browser/codeEditorService'; import 'vs/workbench/services/broadcast/electron-browser/broadcastService'; -import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -import { ClipboardService } from 'vs/platform/clipboard/electron-browser/clipboardService'; registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); From 51891b88b917b10af22070c5b6d54491d05fd09e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sun, 24 Feb 2019 16:56:32 +0100 Subject: [PATCH 085/290] nodeless - set good default zoom factor --- src/vs/base/browser/browser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index c09210608f3..16414ef34d3 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -34,7 +34,7 @@ class WindowManager { } // --- Zoom Factor - private _zoomFactor: number = 0; + private _zoomFactor: number = 1; public getZoomFactor(): number { return this._zoomFactor; From c9ebd2e15a1c3997ed353507c28957ab6dff2b6a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 26 Feb 2019 15:26:34 +0100 Subject: [PATCH 086/290] nodeless - move window.title setting to workbench.contribution --- .../workbench/browser/workbench.contribution.ts | 16 ++++++++++++++++ .../electron-browser/main.contribution.ts | 6 ------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 1eb763e0023..e1f55c10fb7 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -243,6 +243,22 @@ import { isMacintosh } from 'vs/base/common/platform'; } }); + // Window + registry.registerConfiguration({ + 'id': 'window', + 'order': 8, + 'title': nls.localize('windowConfigurationTitle', "Window"), + 'type': 'object', + 'properties': { + 'window.title': { + 'type': 'string', + 'default': isMacintosh ? '${activeEditorShort}${separator}${rootName}' : '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}', + '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/myFileFolder/myFile.txt).\n- `\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt).\n- `\${activeFolderShort}`: the name of the folder the file is contained in (e.g. myFileFolder).\n- `\${activeFolderMedium}`: the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder).\n- `\${activeFolderLong}`: the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder).\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.") + } + } + }); + // Zen Mode registry.registerConfiguration({ 'id': 'zenMode', diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 0d9d443dc16..cd5983d7aa7 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -590,12 +590,6 @@ import { LogStorageAction } from 'vs/platform/storage/node/storageService'; 'default': 0, 'description': nls.localize('zoomLevel', "Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.") }, - 'window.title': { - 'type': 'string', - 'default': isMacintosh ? '${activeEditorShort}${separator}${rootName}' : '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}', - '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/myFileFolder/myFile.txt).\n- `\${activeEditorLong}`: the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt).\n- `\${activeFolderShort}`: the name of the folder the file is contained in (e.g. myFileFolder).\n- `\${activeFolderMedium}`: the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder).\n- `\${activeFolderLong}`: the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder).\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', 'enum': ['default', 'inherit', 'maximized', 'fullscreen'], From 739a9dd5ce02c0d1950973eafec45b1905e6b405 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 26 Feb 2019 15:54:55 +0100 Subject: [PATCH 087/290] debt - dragover needs preventDefault() --- src/vs/base/browser/dnd.ts | 4 +++- src/vs/base/browser/ui/list/listView.ts | 2 ++ src/vs/base/browser/ui/tree/abstractTree.ts | 2 ++ src/vs/base/parts/tree/browser/treeView.ts | 2 ++ src/vs/workbench/browser/dnd.ts | 2 ++ 5 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/dnd.ts b/src/vs/base/browser/dnd.ts index d7e6571b6f9..6ba70bd072a 100644 --- a/src/vs/base/browser/dnd.ts +++ b/src/vs/base/browser/dnd.ts @@ -16,7 +16,9 @@ export class DelayedDragHandler extends Disposable { constructor(container: HTMLElement, callback: () => void) { super(); - this._register(addDisposableListener(container, 'dragover', () => { + this._register(addDisposableListener(container, 'dragover', e => { + e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) + if (!this.timeout) { this.timeout = setTimeout(() => { callback(); diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index 3bf44fc334b..ac85245b2fe 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -786,6 +786,8 @@ export class ListView implements ISpliceable, IDisposable { } private onDragOver(event: IListDragEvent): boolean { + event.browserEvent.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) + this.onDragLeaveTimeout.dispose(); if (StaticDND.CurrentDragAndDropData && StaticDND.CurrentDragAndDropData.getData() === 'vscode-ui') { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 22839784b16..52f31490996 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -603,6 +603,8 @@ class TypeFilterController implements IDisposable { }; const onDragOver = (event: DragEvent) => { + event.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) + const x = event.screenX - left; if (event.dataTransfer) { event.dataTransfer.dropEffect = 'none'; diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 5e7e31b7d3e..39ed5525f7f 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -1422,6 +1422,8 @@ export class TreeView extends HeightMap { } private onDragOver(e: DragEvent): boolean { + e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) + let event = new Mouse.DragMouseEvent(e); let viewItem = this.getItemAround(event.target); diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index a494e038b78..9b036521f2e 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -447,6 +447,8 @@ export class DragAndDropObserver extends Disposable { })); this._register(addDisposableListener(this.element, EventType.DRAG_OVER, (e: DragEvent) => { + e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) + if (this.callbacks.onDragOver) { this.callbacks.onDragOver(e); } From 1e17319bfde04aefb34fd1b0648868dca208fa2c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Sat, 2 Mar 2019 11:00:09 +0100 Subject: [PATCH 088/290] fix #69588 --- src/vs/code/electron-main/main.ts | 6 ++--- src/vs/code/node/cli.ts | 25 +++++++++--------- src/vs/code/node/wait.ts | 26 ------------------- src/vs/code/test/node/argv.test.ts | 11 +++++++- src/vs/platform/environment/node/argv.ts | 14 ++++++++++ .../platform/environment/node/argvHelper.ts | 24 +++++++++++++++-- 6 files changed, 61 insertions(+), 45 deletions(-) delete mode 100644 src/vs/code/node/wait.ts diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index ac399cc99a2..49668099824 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -8,7 +8,8 @@ import { app, dialog } from 'electron'; import { assign } from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; import product from 'vs/platform/product/node/product'; -import { parseMainProcessArgv } from 'vs/platform/environment/node/argvHelper'; +import { parseMainProcessArgv, createWaitMarkerFile } from 'vs/platform/environment/node/argvHelper'; +import { addArg } from 'vs/platform/environment/node/argv'; import { mkdirp } from 'vs/base/node/pfs'; import { validatePaths } from 'vs/code/node/paths'; import { LifecycleService, ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain'; @@ -36,7 +37,6 @@ import { IDiagnosticsService, DiagnosticsService } from 'vs/platform/diagnostics import { BufferLogService } from 'vs/platform/log/common/bufferLog'; import { uploadLogs } from 'vs/code/electron-main/logUploader'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; -import { createWaitMarkerFile } from 'vs/code/node/wait'; class ExpectedError extends Error { readonly isExpected = true; @@ -359,7 +359,7 @@ function main(): void { if (args.wait && !args.waitMarkerFilePath) { createWaitMarkerFile(args.verbose).then(waitMarkerFilePath => { if (waitMarkerFilePath) { - process.argv.push('--waitMarkerFilePath', waitMarkerFilePath); + addArg(process.argv, '--waitMarkerFilePath', waitMarkerFilePath); args.waitMarkerFilePath = waitMarkerFilePath; } diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 12409054728..6f558debea5 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -5,7 +5,8 @@ import { spawn, ChildProcess } from 'child_process'; import { assign } from 'vs/base/common/objects'; -import { buildHelpMessage, buildVersionMessage } from 'vs/platform/environment/node/argv'; +import { buildHelpMessage, buildVersionMessage, addArg } from 'vs/platform/environment/node/argv'; +import { parseCLIProcessArgv, createWaitMarkerFile } from 'vs/platform/environment/node/argvHelper'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; import product from 'vs/platform/product/node/product'; import pkg from 'vs/platform/product/node/package'; @@ -19,8 +20,6 @@ import * as iconv from 'iconv-lite'; import { writeFileAndFlushSync } from 'vs/base/node/extfs'; import { isWindows } from 'vs/base/common/platform'; import { ProfilingSession, Target } from 'v8-inspect-profiler'; -import { createWaitMarkerFile } from 'vs/code/node/wait'; -import { parseCLIProcessArgv } from 'vs/platform/environment/node/argvHelper'; function shouldSpawnCliProcess(argv: ParsedArgs): boolean { return !!argv['install-source'] @@ -180,11 +179,11 @@ export async function main(argv: string[]): Promise { }); // Make sure to open tmp file - argv.push(stdinFilePath); + addArg(argv, stdinFilePath); // Enable --wait to get all data and ignore adding this to history - argv.push('--wait'); - argv.push('--skip-add-to-recently-opened'); + addArg(argv, '--wait'); + addArg(argv, '--skip-add-to-recently-opened'); args.wait = true; } @@ -232,7 +231,7 @@ export async function main(argv: string[]): Promise { if (args.wait) { waitMarkerFilePath = await createWaitMarkerFile(verbose); if (waitMarkerFilePath) { - argv.push('--waitMarkerFilePath', waitMarkerFilePath); + addArg(argv, '--waitMarkerFilePath', waitMarkerFilePath); } } @@ -252,11 +251,11 @@ export async function main(argv: string[]): Promise { const filenamePrefix = paths.join(os.homedir(), 'prof-' + Math.random().toString(16).slice(-4)); - argv.push(`--inspect-brk=${portMain}`); - argv.push(`--remote-debugging-port=${portRenderer}`); - argv.push(`--inspect-brk-extensions=${portExthost}`); - argv.push(`--prof-startup-prefix`, filenamePrefix); - argv.push(`--no-cached-data`); + addArg(argv, `--inspect-brk=${portMain}`); + addArg(argv, `--remote-debugging-port=${portRenderer}`); + addArg(argv, `--inspect-brk-extensions=${portExthost}`); + addArg(argv, `--prof-startup-prefix`, filenamePrefix); + addArg(argv, `--no-cached-data`); fs.writeFileSync(filenamePrefix, argv.slice(-6).join('|')); @@ -341,7 +340,7 @@ export async function main(argv: string[]): Promise { if (args['js-flags']) { const match = /max_old_space_size=(\d+)/g.exec(args['js-flags']); if (match && !args['max-memory']) { - argv.push(`--max-memory=${match[1]}`); + addArg(argv, `--max-memory=${match[1]}`); } } diff --git a/src/vs/code/node/wait.ts b/src/vs/code/node/wait.ts deleted file mode 100644 index 9f9b9aaa41d..00000000000 --- a/src/vs/code/node/wait.ts +++ /dev/null @@ -1,26 +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 { join } from 'vs/base/common/path'; -import { tmpdir } from 'os'; -import { writeFile } from 'vs/base/node/pfs'; - -export function createWaitMarkerFile(verbose?: boolean): Promise { - const randomWaitMarkerPath = join(tmpdir(), Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10)); - - return writeFile(randomWaitMarkerPath, '').then(() => { - if (verbose) { - console.log(`Marker file for --wait created: ${randomWaitMarkerPath}`); - } - - return randomWaitMarkerPath; - }, error => { - if (verbose) { - console.error(`Failed to create marker file for --wait: ${error}`); - } - - return Promise.resolve(undefined); - }); -} diff --git a/src/vs/code/test/node/argv.test.ts b/src/vs/code/test/node/argv.test.ts index 2988c631ee7..6ce5684fab0 100644 --- a/src/vs/code/test/node/argv.test.ts +++ b/src/vs/code/test/node/argv.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { formatOptions, Option } from 'vs/platform/environment/node/argv'; +import { formatOptions, Option, addArg } from 'vs/platform/environment/node/argv'; suite('formatOptions', () => { @@ -54,4 +54,13 @@ suite('formatOptions', () => { ' bar bar bar bar bar bar bar bar bar ' ]); }); + + test('addArg', () => { + assert.deepEqual(addArg([], 'foo'), ['foo']); + assert.deepEqual(addArg([], 'foo', 'bar'), ['foo', 'bar']); + assert.deepEqual(addArg(['foo'], 'bar'), ['foo', 'bar']); + assert.deepEqual(addArg(['--wait'], 'bar'), ['--wait', 'bar']); + assert.deepEqual(addArg(['--wait', '--', '--foo'], 'bar'), ['--wait', 'bar', '--', '--foo']); + assert.deepEqual(addArg(['--', '--foo'], 'bar'), ['bar', '--', '--foo']); + }); }); diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 7a304566aef..25b3fae01f6 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -239,3 +239,17 @@ export function hasArgs(arg: string | string[] | undefined): boolean { } return false; } + +export function addArg(argv: string[], ...args: string[]): string[] { + const endOfArgsMarkerIndex = argv.indexOf('--'); + if (endOfArgsMarkerIndex === -1) { + argv.push(...args); + } else { + // if the we have an argument "--" (end of argument marker) + // we cannot add arguments at the end. rather, we add + // arguments before the "--" marker. + argv.splice(endOfArgsMarkerIndex, 0, ...args); + } + + return argv; +} \ No newline at end of file diff --git a/src/vs/platform/environment/node/argvHelper.ts b/src/vs/platform/environment/node/argvHelper.ts index b31e7659e97..7e0819f77ab 100644 --- a/src/vs/platform/environment/node/argvHelper.ts +++ b/src/vs/platform/environment/node/argvHelper.ts @@ -4,12 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { tmpdir } from 'os'; import { firstIndex } from 'vs/base/common/arrays'; import { localize } from 'vs/nls'; import { ParsedArgs } from '../common/environment'; import { MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/common/files'; import { parseArgs } from 'vs/platform/environment/node/argv'; - +import { join } from 'vs/base/common/path'; +import { writeFile } from 'vs/base/node/pfs'; function validate(args: ParsedArgs): ParsedArgs { if (args.goto) { @@ -57,4 +59,22 @@ export function parseCLIProcessArgv(processArgv: string[]): ParsedArgs { } return validate(parseArgs(args)); -} \ No newline at end of file +} + +export function createWaitMarkerFile(verbose?: boolean): Promise { + const randomWaitMarkerPath = join(tmpdir(), Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10)); + + return writeFile(randomWaitMarkerPath, '').then(() => { + if (verbose) { + console.log(`Marker file for --wait created: ${randomWaitMarkerPath}`); + } + + return randomWaitMarkerPath; + }, error => { + if (verbose) { + console.error(`Failed to create marker file for --wait: ${error}`); + } + + return Promise.resolve(undefined); + }); +} From 02ca5bde963ff890433427da44c630d8379014fb Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Sat, 2 Mar 2019 19:09:32 +0900 Subject: [PATCH 089/290] Make an error message easier to understand --- build/gulpfile.hygiene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 1af30179a06..9ec4d5ef336 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -228,7 +228,7 @@ function hygiene(some) { let formatted = result.dest.replace(/\r\n/gm, '\n'); if (original !== formatted) { - console.error('File not formatted:', file.relative); + console.error('File not formatted with tsfmt:', file.relative); errorCount++; } cb(null, file); From e96ab81392ec49effa0369f4f086be8c128e5e2f Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Sat, 2 Mar 2019 20:57:46 +0100 Subject: [PATCH 090/290] extensionTestsLocationURI.fsPath normalizes path (for #69569) --- src/vs/workbench/api/node/extHostExtensionService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index cada07e1ff7..58ba2e568ef 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -5,6 +5,7 @@ import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; +import { originalFSPath } from 'vs/base/common/resources'; import { Barrier } from 'vs/base/common/async'; import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { TernarySearchTree } from 'vs/base/common/map'; @@ -614,7 +615,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return Promise.resolve(undefined); } - const extensionTestsPath = extensionTestsLocationURI.fsPath; + const extensionTestsPath = originalFSPath(extensionTestsLocationURI); // Require the test runner via node require from the provided path let testRunner: ITestRunner | undefined; From eb17fc81bb96f137909d30b44f76c89c4d9a3fee Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Sun, 3 Mar 2019 07:38:40 +0300 Subject: [PATCH 091/290] Fixes useExec promise not returning if there's no work to do --- src/vs/base/node/processes.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index 0dab519e6a4..e16c0722a57 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -321,14 +321,14 @@ export abstract class AbstractProcess { private useExec(): Promise { return new Promise((c, e) => { if (!this.shell || !Platform.isWindows) { - c(false); + return c(false); } let cmdShell = cp.spawn(getWindowsShell(), ['/s', '/c']); cmdShell.on('error', (error: Error) => { - c(true); + return c(true); }); cmdShell.on('exit', (data: any) => { - c(false); + return c(false); }); }); } @@ -470,4 +470,4 @@ export namespace win32 { } return path.join(cwd, command); } -} \ No newline at end of file +} From def23176f224e6399fc789a06b8ae1efa9b3c2dd Mon Sep 17 00:00:00 2001 From: Filipe Correia Date: Sun, 3 Mar 2019 10:57:42 +0000 Subject: [PATCH 092/290] Update vscode.d.ts --- 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 b2ac03e4fcd..9305f29a4c3 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3701,7 +3701,7 @@ declare module 'vscode' { } /** - * A line based folding range. To be valid, start and end line must a zero or larger and smaller than the number of lines in the document. + * A line based folding range. To be valid, start and end line must be bigger than zero and smaller than the number of lines in the document. * Invalid ranges will be ignored. */ export class FoldingRange { From 2702c1421cf2a87bc31c6ba5211d66d3b09ce757 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 08:40:35 +0100 Subject: [PATCH 093/290] debt - work on untangling layout things out of workbench --- src/vs/base/browser/ui/splitview/panelview.ts | 5 +- src/vs/workbench/browser/composite.ts | 16 +- .../parts/activitybar/activitybarPart.ts | 24 +- .../workbench/browser/parts/compositePart.ts | 7 +- .../browser/parts/panel/panelActions.ts | 2 +- .../browser/parts/panel/panelPart.ts | 75 +- .../browser/parts/sidebar/sidebarPart.ts | 54 +- .../browser/parts/titlebar/titlebarPart.ts | 14 +- src/vs/workbench/common/panel.ts | 4 + src/vs/workbench/common/viewlet.ts | 5 + .../contrib/debug/browser/debugCommands.ts | 2 +- .../debug/browser/debugEditorActions.ts | 2 +- .../markers/browser/markers.contribution.ts | 10 +- .../workbench/electron-browser/workbench.ts | 960 +++++++++--------- .../activity/browser/activityService.ts | 1 - 15 files changed, 598 insertions(+), 583 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/panelview.ts b/src/vs/base/browser/ui/splitview/panelview.ts index fb9897920a5..e83b324542d 100644 --- a/src/vs/base/browser/ui/splitview/panelview.ts +++ b/src/vs/base/browser/ui/splitview/panelview.ts @@ -172,8 +172,9 @@ export abstract class Panel implements IView { this.renderHeader(this.header); const focusTracker = trackFocus(this.header); - focusTracker.onDidFocus(() => addClass(this.header, 'focused')); - focusTracker.onDidBlur(() => removeClass(this.header, 'focused')); + this.disposables.push(focusTracker); + focusTracker.onDidFocus(() => addClass(this.header, 'focused'), null, this.disposables); + focusTracker.onDidBlur(() => removeClass(this.header, 'focused'), null, this.disposables); this.updateHeader(); diff --git a/src/vs/workbench/browser/composite.ts b/src/vs/workbench/browser/composite.ts index 894aa1d77b9..4fc60b1cc1d 100644 --- a/src/vs/workbench/browser/composite.ts +++ b/src/vs/workbench/browser/composite.ts @@ -38,7 +38,7 @@ export abstract class Composite extends Component implements IComposite { private _onDidFocus: Emitter; get onDidFocus(): Event { if (!this._onDidFocus) { - this._registerFocusTrackEvents(); + this.registerFocusTrackEvents(); } return this._onDidFocus.event; @@ -47,13 +47,13 @@ export abstract class Composite extends Component implements IComposite { private _onDidBlur: Emitter; get onDidBlur(): Event { if (!this._onDidBlur) { - this._registerFocusTrackEvents(); + this.registerFocusTrackEvents(); } return this._onDidBlur.event; } - private _registerFocusTrackEvents(): void { + private registerFocusTrackEvents(): void { this._onDidFocus = this._register(new Emitter()); this._onDidBlur = this._register(new Emitter()); @@ -217,11 +217,11 @@ export abstract class CompositeDescriptor { constructor( private readonly ctor: IConstructorSignature0, - public readonly id: string, - public readonly name: string, - public readonly cssClass?: string, - public readonly order?: number, - public readonly keybindingId?: string, + readonly id: string, + readonly name: string, + readonly cssClass?: string, + readonly order?: number, + readonly keybindingId?: string, ) { } instantiate(instantiationService: IInstantiationService): T { diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index b8b8e289b18..f54dadfb511 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -110,6 +110,7 @@ export class ActivitybarPart extends Part implements ISerializableView { private registerListeners(): void { + // Viewlet registration this._register(this.viewletService.onDidViewletRegister(viewlet => this.onDidRegisterViewlets([viewlet]))); this._register(this.viewletService.onDidViewletDeregister(({ id }) => this.removeComposite(id, true))); @@ -119,6 +120,7 @@ export class ActivitybarPart extends Part implements ISerializableView { // Deactivate viewlet action on close this._register(this.viewletService.onDidViewletClose(viewlet => this.compositeBar.deactivateComposite(viewlet.getId()))); + // Extension registration let disposables: IDisposable[] = []; this._register(this.extensionService.onDidRegisterExtensions(() => { disposables = dispose(disposables); @@ -126,11 +128,13 @@ export class ActivitybarPart extends Part implements ISerializableView { this.compositeBar.onDidChange(() => this.saveCachedViewlets(), this, disposables); this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e), this, disposables); })); + this._register(toDisposable(() => dispose(disposables))); } private onDidRegisterExtensions(): void { this.removeNotExistingComposites(); + for (const viewlet of this.viewletService.getViewlets()) { this.enableCompositeActions(viewlet); const viewContainer = this.getViewContainer(viewlet.id); @@ -142,6 +146,7 @@ export class ActivitybarPart extends Part implements ISerializableView { } } } + this.saveCachedViewlets(); } @@ -154,6 +159,7 @@ export class ActivitybarPart extends Part implements ISerializableView { } private onDidViewletOpen(viewlet: IViewlet): void { + // Update the composite bar by adding this.compositeBar.addComposite(this.viewletService.getViewlet(viewlet.getId())); this.compositeBar.activateComposite(viewlet.getId()); @@ -162,8 +168,7 @@ export class ActivitybarPart extends Part implements ISerializableView { if (viewContainer) { const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer); if (viewDescriptors && viewDescriptors.activeViewDescriptors.length === 0) { - // Update the composite bar by hiding - this.removeComposite(viewletDescriptor.id, true); + this.removeComposite(viewletDescriptor.id, true); // Update the composite bar by hiding } } } @@ -325,6 +330,7 @@ export class ActivitybarPart extends Part implements ISerializableView { } else { this.compositeBar.removeComposite(compositeId); } + const compositeActions = this.compositeActions[compositeId]; if (compositeActions) { compositeActions.activityAction.dispose(); @@ -338,6 +344,7 @@ export class ActivitybarPart extends Part implements ISerializableView { if (activityAction instanceof PlaceHolderViewletActivityAction) { activityAction.setActivity(viewlet); } + if (pinnedAction instanceof PlaceHolderToggleCompositePinnedAction) { pinnedAction.setActivity(viewlet); } @@ -345,6 +352,7 @@ export class ActivitybarPart extends Part implements ISerializableView { getPinnedViewletIds(): string[] { const pinnedCompositeIds = this.compositeBar.getPinnedComposites().map(v => v.id); + return this.viewletService.getViewlets() .filter(v => this.compositeBar.isPinned(v.id)) .sort((v1, v2) => pinnedCompositeIds.indexOf(v1.id) - pinnedCompositeIds.indexOf(v2.id)) @@ -369,8 +377,7 @@ export class ActivitybarPart extends Part implements ISerializableView { let availableHeight = this.dimension.height; if (this.globalActionBar) { - // adjust height for global actions showing - availableHeight -= (this.globalActionBar.items.length * ActivitybarPart.ACTION_HEIGHT); + availableHeight -= (this.globalActionBar.items.length * ActivitybarPart.ACTION_HEIGHT); // adjust height for global actions showing } this.compositeBar.layout(new Dimension(dim1 instanceof Dimension ? dim1.width : dim1, availableHeight)); @@ -414,8 +421,9 @@ export class ActivitybarPart extends Part implements ISerializableView { private saveCachedViewlets(): void { const state: ICachedViewlet[] = []; - const compositeItems = this.compositeBar.getCompositeBarItems(); const allViewlets = this.viewletService.getViewlets(); + + const compositeItems = this.compositeBar.getCompositeBarItems(); for (const compositeItem of compositeItems) { const viewContainer = this.getViewContainer(compositeItem.id); const viewlet = allViewlets.filter(({ id }) => id === compositeItem.id)[0]; @@ -432,6 +440,7 @@ export class ActivitybarPart extends Part implements ISerializableView { state.push({ id: compositeItem.id, iconUrl: viewlet.iconUrl, views, pinned: compositeItem && compositeItem.pinned, order: compositeItem ? compositeItem.order : undefined, visible: compositeItem && compositeItem.visible }); } } + this.cachedViewletsValue = JSON.stringify(state); } @@ -442,6 +451,7 @@ export class ActivitybarPart extends Part implements ISerializableView { serialized.visible = isUndefinedOrNull(serialized.visible) ? true : serialized.visible; return serialized; }); + for (const old of this.loadOldCachedViewlets()) { const cachedViewlet = cachedViewlets.filter(cached => cached.id === old.id)[0]; if (cachedViewlet) { @@ -449,6 +459,7 @@ export class ActivitybarPart extends Part implements ISerializableView { cachedViewlet.views = old.views; } } + return cachedViewlets; } @@ -456,6 +467,7 @@ export class ActivitybarPart extends Part implements ISerializableView { const previousState = this.storageService.get('workbench.activity.placeholderViewlets', StorageScope.GLOBAL, '[]'); const result = (JSON.parse(previousState)); this.storageService.remove('workbench.activity.placeholderViewlets', StorageScope.GLOBAL); + return result; } @@ -464,6 +476,7 @@ export class ActivitybarPart extends Part implements ISerializableView { if (!this._cachedViewletsValue) { this._cachedViewletsValue = this.getStoredCachedViewletsValue(); } + return this._cachedViewletsValue; } @@ -487,6 +500,7 @@ export class ActivitybarPart extends Part implements ISerializableView { if (viewletId === SCM_VIEWLET_ID) { return null; } + const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); return viewContainerRegistry.get(viewletId); } diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index 30f54594cf3..a9a2883e398 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -98,6 +98,7 @@ export abstract class CompositePart extends Part { } protected openComposite(id: string, focus?: boolean): Composite | undefined { + // Check if composite already visible and just focus in that case if (this.activeComposite && this.activeComposite.getId() === id) { if (focus) { @@ -449,6 +450,7 @@ export abstract class CompositePart extends Part { getProgressIndicator(id: string): IProgressService | null { const compositeItem = this.instantiatedCompositeItems.get(id); + return compositeItem ? compositeItem.progressService : null; } @@ -467,6 +469,7 @@ export abstract class CompositePart extends Part { layout(dimension: Dimension): Dimension[]; layout(width: number, height: number): void; layout(dim1: Dimension | number, dim2?: number): Dimension[] | void { + // Pass to super const sizes = super.layout(dim1 instanceof Dimension ? dim1 : new Dimension(dim1, dim2!)); @@ -483,8 +486,7 @@ export abstract class CompositePart extends Part { protected removeComposite(compositeId: string): boolean { if (this.activeComposite && this.activeComposite.getId() === compositeId) { - // do not remove active compoiste - return false; + return false; // do not remove active composite } delete this.mapCompositeToCompositeContainer[compositeId]; @@ -495,6 +497,7 @@ export abstract class CompositePart extends Part { dispose(compositeItem.disposable); this.instantiatedCompositeItems.delete(compositeId); } + return true; } diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index adb1d3b18d5..e5f639f4449 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -249,7 +249,7 @@ export class NextPanelViewAction extends SwitchPanelViewAction { super(id, name, panelService); } - public run(): Promise { + run(): Promise { return super.run(1); } } diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index d6bd16824cc..87c274bf9ea 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -8,7 +8,7 @@ import { IAction } from 'vs/base/common/actions'; import { Event, Emitter } from 'vs/base/common/event'; import { Registry } from 'vs/platform/registry/common/platform'; import { ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IPanel } from 'vs/workbench/common/panel'; +import { IPanel, ActivePanelContext, PanelFocusContext } from 'vs/workbench/common/panel'; import { CompositePart, ICompositeTitleLabel } from 'vs/workbench/browser/parts/compositePart'; import { Panel, PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel'; import { IPanelService, IPanelIdentifier } from 'vs/workbench/services/panel/common/panelService'; @@ -29,15 +29,12 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { Dimension, trackFocus } from 'vs/base/browser/dom'; import { localize } from 'vs/nls'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { ISerializableView } from 'vs/base/browser/ui/grid/grid'; import { LayoutPriority } from 'vs/base/browser/ui/grid/gridview'; -export const ActivePanelContext = new RawContextKey('activePanel', ''); -export const PanelFocusContext = new RawContextKey('panelFocus', false); - interface ICachedPanel { id: string; pinned: boolean; @@ -66,11 +63,16 @@ export class PanelPart extends CompositePart implements IPanelService, IS private _onDidChange = this._register(new Emitter<{ width: number; height: number; }>()); get onDidChange(): Event<{ width: number, height: number }> { return this._onDidChange.event; } + get onDidPanelOpen(): Event<{ panel: IPanel, focus: boolean }> { return Event.map(this.onDidCompositeOpen.event, compositeOpen => ({ panel: compositeOpen.composite, focus: compositeOpen.focus })); } + get onDidPanelClose(): Event { return this.onDidCompositeClose.event; } + private activePanelContextKey: IContextKey; private panelFocusContextKey: IContextKey; - private blockOpeningPanel: boolean; + private compositeBar: CompositeBar; private compositeActions: { [compositeId: string]: { activityAction: PanelActivityAction, pinnedAction: ToggleCompositePinnedAction } } = Object.create(null); + + private blockOpeningPanel: boolean; private dimension: Dimension; constructor( @@ -142,25 +144,13 @@ export class PanelPart extends CompositePart implements IPanelService, IS this.registerListeners(); } - create(parent: HTMLElement): void { - this.element = parent; - - super.create(parent); - - const focusTracker = trackFocus(parent); - - focusTracker.onDidFocus(() => { - this.panelFocusContextKey.set(true); - }); - focusTracker.onDidBlur(() => { - this.panelFocusContextKey.set(false); - }); - } - private registerListeners(): void { - this._register(this.onDidPanelOpen(({ panel }) => this._onDidPanelOpen(panel))); - this._register(this.onDidPanelClose(this._onDidPanelClose, this)); + // Panel open/close + this._register(this.onDidPanelOpen(({ panel }) => this.onPanelOpen(panel))); + this._register(this.onDidPanelClose(this.onPanelClose, this)); + + // Panel register/deregister this._register(this.registry.onDidRegister(panelDescriptor => this.compositeBar.addComposite(panelDescriptor))); this._register(this.registry.onDidDeregister(panelDescriptor => { this.compositeBar.hideComposite(panelDescriptor.id); @@ -176,17 +166,18 @@ export class PanelPart extends CompositePart implements IPanelService, IS // Deactivate panel action on close this._register(this.onDidPanelClose(panel => this.compositeBar.deactivateComposite(panel.getId()))); + // State this.lifecycleService.when(LifecyclePhase.Eventually).then(() => { this._register(this.compositeBar.onDidChange(() => this.saveCachedPanels())); this._register(this.storageService.onDidChangeStorage(e => this.onDidStorageChange(e))); }); } - private _onDidPanelOpen(panel: IPanel): void { + private onPanelOpen(panel: IPanel): void { this.activePanelContextKey.set(panel.getId()); } - private _onDidPanelClose(panel: IPanel): void { + private onPanelClose(panel: IPanel): void { const id = panel.getId(); if (this.activePanelContextKey.get() === id) { @@ -194,12 +185,14 @@ export class PanelPart extends CompositePart implements IPanelService, IS } } - get onDidPanelOpen(): Event<{ panel: IPanel, focus: boolean }> { - return Event.map(this.onDidCompositeOpen.event, compositeOpen => ({ panel: compositeOpen.composite, focus: compositeOpen.focus })); - } + create(parent: HTMLElement): void { + this.element = parent; - get onDidPanelClose(): Event { - return this.onDidCompositeClose.event; + super.create(parent); + + const focusTracker = this._register(trackFocus(parent)); + this._register(focusTracker.onDidFocus(() => this.panelFocusContextKey.set(true))); + this._register(focusTracker.onDidBlur(() => this.panelFocusContextKey.set(false))); } updateStyles(): void { @@ -241,6 +234,10 @@ export class PanelPart extends CompositePart implements IPanelService, IS return this.getPanels().filter(p => p.id === panelId).pop(); } + hasPanel(panelId: string): boolean { + return !!this.getPanels().filter(p => p.id === panelId).length; + } + getPanels(): PanelDescriptor[] { return Registry.as(PanelExtensions.Panels).getPanels() .sort((v1, v2) => typeof v1.order === 'number' && typeof v2.order === 'number' ? v1.order - v2.order : NaN); @@ -303,8 +300,7 @@ export class PanelPart extends CompositePart implements IPanelService, IS const { width, height } = dim1 instanceof Dimension ? dim1 : { width: dim1, height: dim2 }; if (this.partService.getPanelPosition() === Position.RIGHT) { - // Take into account the 1px border when layouting - this.dimension = new Dimension(width - 1, height!); + this.dimension = new Dimension(width - 1, height!); // Take into account the 1px border when layouting } else { this.dimension = new Dimension(width, height!); } @@ -321,9 +317,9 @@ export class PanelPart extends CompositePart implements IPanelService, IS if (this.dimension) { let availableWidth = this.dimension.width - 40; // take padding into account if (this.toolBar) { - // adjust height for global actions showing - availableWidth = Math.max(PanelPart.MIN_COMPOSITE_BAR_WIDTH, availableWidth - this.getToolbarWidth()); + availableWidth = Math.max(PanelPart.MIN_COMPOSITE_BAR_WIDTH, availableWidth - this.getToolbarWidth()); // adjust height for global actions showing } + this.compositeBar.layout(new Dimension(availableWidth, this.dimension.height)); } } @@ -337,6 +333,7 @@ export class PanelPart extends CompositePart implements IPanelService, IS }; this.compositeActions[compositeId] = compositeActions; } + return compositeActions; } @@ -348,8 +345,10 @@ export class PanelPart extends CompositePart implements IPanelService, IS compositeActions.pinnedAction.dispose(); delete this.compositeActions[compositeId]; } + return true; } + return false; } @@ -358,6 +357,7 @@ export class PanelPart extends CompositePart implements IPanelService, IS if (!activePanel) { return 0; } + return this.toolBar.getItemsWidth(); } @@ -396,22 +396,26 @@ export class PanelPart extends CompositePart implements IPanelService, IS private saveCachedPanels(): void { const state: ICachedPanel[] = []; + const compositeItems = this.compositeBar.getCompositeBarItems(); for (const compositeItem of compositeItems) { state.push({ id: compositeItem.id, pinned: compositeItem.pinned, order: compositeItem.order, visible: compositeItem.visible }); } + this.cachedPanelsValue = JSON.stringify(state); } private getCachedPanels(): ICachedPanel[] { - const storedStates = >JSON.parse(this.cachedPanelsValue); const registeredPanels = this.getPanels(); + + const storedStates = >JSON.parse(this.cachedPanelsValue); const cachedPanels = storedStates.map(c => { const serialized: ICachedPanel = typeof c === 'string' /* migration from pinned states to composites states */ ? { id: c, pinned: true, order: undefined, visible: true } : c; const registered = registeredPanels.some(p => p.id === serialized.id); serialized.visible = registered ? isUndefinedOrNull(serialized.visible) ? true : serialized.visible : false; return serialized; }); + return cachedPanels; } @@ -420,6 +424,7 @@ export class PanelPart extends CompositePart implements IPanelService, IS if (!this._cachedPanelsValue) { this._cachedPanelsValue = this.getStoredCachedPanelsValue(); } + return this._cachedPanelsValue; } diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index 653dde866ac..d1d90205df5 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -13,7 +13,7 @@ import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/wor import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IPartService, Parts, Position as SideBarPosition } from 'vs/workbench/services/part/common/partService'; -import { IViewlet } from 'vs/workbench/common/viewlet'; +import { IViewlet, SidebarFocusContext, ActiveViewletContext } from 'vs/workbench/common/viewlet'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -27,16 +27,12 @@ import { SIDE_BAR_TITLE_FOREGROUND, SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND, SI import { INotificationService } from 'vs/platform/notification/common/notification'; import { EventType, addDisposableListener, trackFocus, Dimension } from 'vs/base/browser/dom'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; -import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { ISerializableView } from 'vs/base/browser/ui/grid/grid'; import { LayoutPriority } from 'vs/base/browser/ui/grid/gridview'; -export const SidebarVisibleContext = new RawContextKey('sidebarVisible', false); -export const SidebarFocusContext = new RawContextKey('sideBarFocus', false); -export const ActiveViewletContext = new RawContextKey('activeViewlet', ''); - export class SidebarPart extends CompositePart implements ISerializableView, IViewletService { _serviceBrand: any; @@ -54,11 +50,18 @@ export class SidebarPart extends CompositePart implements ISerializable private _onDidChange = this._register(new Emitter<{ width: number; height: number; }>()); get onDidChange(): Event<{ width: number, height: number }> { return this._onDidChange.event; } + get onDidViewletRegister(): Event { return >this.viewletRegistry.onDidRegister; } + + private _onDidViewletDeregister = this._register(new Emitter()); + get onDidViewletDeregister(): Event { return this._onDidViewletDeregister.event; } + + get onDidViewletOpen(): Event { return Event.map(this.onDidCompositeOpen.event, compositeEvent => compositeEvent.composite); } + get onDidViewletClose(): Event { return this.onDidCompositeClose.event as Event; } + private viewletRegistry: ViewletRegistry; private sideBarFocusContextKey: IContextKey; private activeViewletContextKey: IContextKey; private blockOpeningViewlet: boolean; - private _onDidViewletDeregister = this._register(new Emitter()); constructor( id: string, @@ -92,52 +95,47 @@ export class SidebarPart extends CompositePart implements ISerializable { hasTitle: true, borderWidth: () => (this.getColor(SIDE_BAR_BORDER) || this.getColor(contrastBorder)) ? 1 : 0 } ); - this.sideBarFocusContextKey = SidebarFocusContext.bindTo(contextKeyService); this.viewletRegistry = Registry.as(ViewletExtensions.Viewlets); + this.sideBarFocusContextKey = SidebarFocusContext.bindTo(contextKeyService); this.activeViewletContextKey = ActiveViewletContext.bindTo(contextKeyService); + this.registerListeners(); + } + + private registerListeners(): void { + + // Viewlet open this._register(this.onDidViewletOpen(viewlet => { this.activeViewletContextKey.set(viewlet.getId()); })); + + // Viewlet close this._register(this.onDidViewletClose(viewlet => { if (this.activeViewletContextKey.get() === viewlet.getId()) { this.activeViewletContextKey.reset(); } })); + + // Viewlet deregister this._register(this.registry.onDidDeregister(async (viewletDescriptor: ViewletDescriptor) => { if (this.getActiveViewlet().getId() === viewletDescriptor.id) { await this.openViewlet(this.getDefaultViewletId()); } + this.removeComposite(viewletDescriptor.id); this._onDidViewletDeregister.fire(viewletDescriptor); })); } - get onDidViewletRegister(): Event { return >this.viewletRegistry.onDidRegister; } - get onDidViewletDeregister(): Event { return this._onDidViewletDeregister.event; } - - get onDidViewletOpen(): Event { - return Event.map(this.onDidCompositeOpen.event, compositeEvent => compositeEvent.composite); - } - - get onDidViewletClose(): Event { - return this.onDidCompositeClose.event as Event; - } - create(parent: HTMLElement): void { this.element = parent; super.create(parent); - const focusTracker = trackFocus(parent); - - focusTracker.onDidFocus(() => { - this.sideBarFocusContextKey.set(true); - }); - focusTracker.onDidBlur(() => { - this.sideBarFocusContextKey.set(false); - }); + const focusTracker = this._register(trackFocus(parent)); + this._register(focusTracker.onDidFocus(() => this.sideBarFocusContextKey.set(true))); + this._register(focusTracker.onDidBlur(() => this.sideBarFocusContextKey.set(false))); } createTitleArea(parent: HTMLElement): HTMLElement { @@ -205,11 +203,13 @@ export class SidebarPart extends CompositePart implements ISerializable if (this.getViewlet(id)) { return Promise.resolve(this.doOpenViewlet(id, focus)); } + return this.extensionService.whenInstalledExtensionsRegistered() .then(() => { if (this.getViewlet(id)) { return this.doOpenViewlet(id, focus); } + return null; }); } diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 3ab509fad99..768cbe3ef10 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -52,9 +52,12 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi get minimumHeight(): number { return isMacintosh ? 22 / getZoomFactor() : (30 / (this.configurationService.getValue('window.menuBarVisibility') === 'hidden' ? getZoomFactor() : 1)); } get maximumHeight(): number { return isMacintosh ? 22 / getZoomFactor() : (30 / (this.configurationService.getValue('window.menuBarVisibility') === 'hidden' ? getZoomFactor() : 1)); } - private _onDidChange = this._register(new Emitter<{ width: number; height: number; }>()); + private _onDidChange = this._register(new Emitter<{ width: number, height: number }>()); get onDidChange(): Event<{ width: number, height: number }> { return this._onDidChange.event; } + private _onMenubarVisibilityChange = this._register(new Emitter()); + get onMenubarVisibilityChange(): Event { return this._onMenubarVisibilityChange.event; } + _serviceBrand: any; private title: HTMLElement; @@ -141,6 +144,8 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi } this.adjustTitleMarginToCenter(); + + this._onMenubarVisibilityChange.fire(visible); } } @@ -154,10 +159,6 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi } } - onMenubarVisibilityChange(): Event { - return this.menubarPart.onVisibilityChange; - } - private onActiveEditorChange(): void { // Dispose old listeners @@ -494,8 +495,7 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi const setting = this.configurationService.getValue('window.doubleClickIconToClose'); if (setting) { this.appIcon.style['-webkit-app-region'] = 'no-drag'; - } - else { + } else { this.appIcon.style['-webkit-app-region'] = 'drag'; } } diff --git a/src/vs/workbench/common/panel.ts b/src/vs/workbench/common/panel.ts index 57c365b0a62..628846c404a 100644 --- a/src/vs/workbench/common/panel.ts +++ b/src/vs/workbench/common/panel.ts @@ -4,5 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { IComposite } from 'vs/workbench/common/composite'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; + +export const ActivePanelContext = new RawContextKey('activePanel', ''); +export const PanelFocusContext = new RawContextKey('panelFocus', false); export interface IPanel extends IComposite { } diff --git a/src/vs/workbench/common/viewlet.ts b/src/vs/workbench/common/viewlet.ts index aa90d23fb94..b213967decd 100644 --- a/src/vs/workbench/common/viewlet.ts +++ b/src/vs/workbench/common/viewlet.ts @@ -4,6 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { IComposite } from 'vs/workbench/common/composite'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; + +export const SidebarVisibleContext = new RawContextKey('sidebarVisible', false); +export const SidebarFocusContext = new RawContextKey('sideBarFocus', false); +export const ActiveViewletContext = new RawContextKey('activeViewlet', ''); export interface IViewlet extends IComposite { diff --git a/src/vs/workbench/contrib/debug/browser/debugCommands.ts b/src/vs/workbench/contrib/debug/browser/debugCommands.ts index b231d8a4853..ffb98ba210f 100644 --- a/src/vs/workbench/contrib/debug/browser/debugCommands.ts +++ b/src/vs/workbench/contrib/debug/browser/debugCommands.ts @@ -22,7 +22,7 @@ import { openBreakpointSource } from 'vs/workbench/contrib/debug/browser/breakpo import { INotificationService } from 'vs/platform/notification/common/notification'; import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { PanelFocusContext } from 'vs/workbench/browser/parts/panel/panelPart'; +import { PanelFocusContext } from 'vs/workbench/common/panel'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { onUnexpectedError } from 'vs/base/common/errors'; diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts index e4bef65fcc3..7b460194b62 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorActions.ts @@ -16,7 +16,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { openBreakpointSource } from 'vs/workbench/contrib/debug/browser/breakpointsView'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { PanelFocusContext } from 'vs/workbench/browser/parts/panel/panelPart'; +import { PanelFocusContext } from 'vs/workbench/common/panel'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; export const TOGGLE_BREAKPOINT_ID = 'editor.debug.action.toggleBreakpoint'; diff --git a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts index 7d759e601b8..2176ac7a9ef 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import 'vs/workbench/contrib/markers/browser/markersFileDecorations'; import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; -import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; @@ -23,9 +24,8 @@ import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } fr import { IMarkersWorkbenchService, MarkersWorkbenchService, ActivityUpdater } from 'vs/workbench/contrib/markers/browser/markers'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; - -import './markersFileDecorations'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { ActivePanelContext } from 'vs/workbench/common/panel'; registerSingleton(IMarkersWorkbenchService, MarkersWorkbenchService, false); @@ -182,7 +182,7 @@ registerAction({ category: localize('problems', "Problems"), menu: { menuId: MenuId.CommandPalette, - when: new RawContextKey('activePanel', Constants.MARKERS_PANEL_ID) + when: ActivePanelContext.isEqualTo(Constants.MARKERS_PANEL_ID) } }); registerAction({ @@ -198,7 +198,7 @@ registerAction({ category: localize('problems', "Problems"), menu: { menuId: MenuId.CommandPalette, - when: new RawContextKey('activePanel', Constants.MARKERS_PANEL_ID) + when: ActivePanelContext.isEqualTo(Constants.MARKERS_PANEL_ID) } }); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index c1e45f78c1c..a6bc3e655bf 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -21,7 +21,7 @@ import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { IEditorInputFactoryRegistry, Extensions as EditorExtensions, IUntitledResourceInput, IResourceDiffInput, InEditorZenModeContext } from 'vs/workbench/common/editor'; import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart'; -import { SidebarPart, SidebarVisibleContext } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; +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'; @@ -111,6 +111,7 @@ import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/work import { IProductService } from 'vs/platform/product/common/product'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; +import { SidebarVisibleContext } from 'vs/workbench/common/viewlet'; // import@node import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; @@ -146,65 +147,42 @@ import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browse import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService'; import { RequestService } from 'vs/platform/request/electron-browser/requestService'; -interface IZenModeSettings { - fullScreen: boolean; - centerLayout: boolean; - hideTabs: boolean; - hideActivityBar: boolean; - hideStatusBar: boolean; - hideLineNumbers: boolean; - restore: boolean; +enum Identifiers { + TITLEBAR_PART = 'workbench.parts.titlebar', + ACTIVITYBAR_PART = 'workbench.parts.activitybar', + SIDEBAR_PART = 'workbench.parts.sidebar', + PANEL_PART = 'workbench.parts.panel', + EDITOR_PART = 'workbench.parts.editor', + STATUSBAR_PART = 'workbench.parts.statusbar' } -interface IWorkbenchStartedInfo { - customKeybindingsCount: number; - pinnedViewlets: string[]; - restoredViewlet: string; - restoredEditorsCount: number; +enum Settings { + MENUBAR_VISIBLE = 'window.menuBarVisibility', + ACTIVITYBAR_VISIBLE = 'workbench.activityBar.visible', + STATUSBAR_VISIBLE = 'workbench.statusBar.visible', + + SIDEBAR_POSITION = 'workbench.sideBar.location', + PANEL_POSITION = 'workbench.panel.defaultLocation', + + FONT_ALIASING = 'workbench.fontAliasing', + ZEN_MODE_RESTORE = 'zenMode.restore' } + type FontAliasingOption = 'default' | 'antialiased' | 'none' | 'auto'; - const fontAliasingValues: FontAliasingOption[] = ['antialiased', 'none', 'auto']; -const Identifiers = { - WORKBENCH_CONTAINER: 'workbench.main.container', - TITLEBAR_PART: 'workbench.parts.titlebar', - ACTIVITYBAR_PART: 'workbench.parts.activitybar', - SIDEBAR_PART: 'workbench.parts.sidebar', - PANEL_PART: 'workbench.parts.panel', - EDITOR_PART: 'workbench.parts.editor', - STATUSBAR_PART: 'workbench.parts.statusbar' -}; +enum State { + SIDEBAR_HIDDEN = 'workbench.sidebar.hidden', -interface IZenMode { - active: boolean; - transitionedToFullScreen: boolean; - transitionedToCenteredEditorLayout: boolean; - transitionDisposeables: IDisposable[]; - wasSideBarVisible: boolean; - wasPanelVisible: boolean; -} + PANEL_HIDDEN = 'workbench.panel.hidden', + PANEL_POSITION = 'workbench.panel.location', -interface IWorkbenchUIState { - lastPanelHeight?: number; - lastPanelWidth?: number; - lastSidebarDimension?: number; + ZEN_MODE_ENABLED = 'workbench.zenmode.active', + CENTERED_LAYOUT_ENABLED = 'workbench.centerededitorlayout.active', } export class Workbench extends Disposable implements IPartService { - private static readonly sidebarHiddenStorageKey = 'workbench.sidebar.hidden'; - private static readonly menubarVisibilityConfigurationKey = 'window.menuBarVisibility'; - private static readonly panelHiddenStorageKey = 'workbench.panel.hidden'; - private static readonly zenModeActiveStorageKey = 'workbench.zenmode.active'; - private static readonly centeredEditorLayoutActiveStorageKey = 'workbench.centerededitorlayout.active'; - private static readonly panelPositionStorageKey = 'workbench.panel.location'; - private static readonly defaultPanelPositionStorageKey = 'workbench.panel.defaultLocation'; - private static readonly sidebarPositionConfigurationKey = 'workbench.sideBar.location'; - private static readonly statusbarVisibleConfigurationKey = 'workbench.statusBar.visible'; - private static readonly activityBarVisibleConfigurationKey = 'workbench.activityBar.visible'; - private static readonly fontAliasingConfigurationKey = 'workbench.fontAliasing'; - _serviceBrand: any; private readonly _onShutdown = this._register(new Emitter()); @@ -214,12 +192,12 @@ export class Workbench extends Disposable implements IPartService { get onWillShutdown(): Event { return this._onWillShutdown.event; } private previousErrorValue: string; - private previousErrorTime: number = 0; + private previousErrorTime = 0; private workbench: HTMLElement; - private workbenchStarted: boolean; - private workbenchRestored: boolean; - private workbenchShutdown: boolean; + + private restored: boolean; + private disposed: boolean; private editorService: EditorService; private editorGroupService: IEditorGroupsService; @@ -232,10 +210,6 @@ export class Workbench extends Disposable implements IPartService { private telemetryService: ITelemetryService; private windowService: IWindowService; private lifecycleService: LifecycleService; - private fileService: IFileService; - private quickInput: QuickInputService; - - private workbenchGrid: Grid | WorkbenchLayout; private titlebarPart: TitlebarPart; private activitybarPart: ActivitybarPart; @@ -244,36 +218,13 @@ export class Workbench extends Disposable implements IPartService { private editorPart: EditorPart; private statusbarPart: StatusbarPart; - private titlebarPartView: View; - private activitybarPartView: View; - private sidebarPartView: View; - private panelPartView: View; - private editorPartView: View; - private statusbarPartView: View; - private quickOpen: QuickOpenController; + private quickInput: QuickInputService; + private notificationsCenter: NotificationsCenter; private notificationsToasts: NotificationsToasts; - private editorHidden: boolean; - private sideBarHidden: boolean; - private statusBarHidden: boolean; - private activityBarHidden: boolean; - private menubarToggled: boolean; - private sideBarPosition: Position; - private panelPosition: Position; - private panelHidden: boolean; - private menubarVisibility: MenuBarVisibility; - private zenMode: IZenMode; private fontAliasing: FontAliasingOption; - private hasInitialFilesToOpen: boolean; - private shouldCenterLayout = false; - private uiState: IWorkbenchUIState = { - lastPanelHeight: 350, - lastPanelWidth: 350, - lastSidebarDimension: 300, - }; - private inZenModeContext: IContextKey; private sideBarVisibleContext: IContextKey; @@ -291,11 +242,6 @@ export class Workbench extends Disposable implements IPartService { ) { super(); - this.hasInitialFilesToOpen = !!( - (configuration.filesToCreate && configuration.filesToCreate.length > 0) || - (configuration.filesToOpen && configuration.filesToOpen.length > 0) || - (configuration.filesToDiff && configuration.filesToDiff.length > 0)); - this.registerErrorHandler(); } @@ -358,7 +304,6 @@ export class Workbench extends Disposable implements IPartService { } private doStartup(): Promise { - this.workbenchStarted = true; // Logging this.logService.trace('workbench configuration', JSON.stringify(this.configuration)); @@ -381,9 +326,6 @@ export class Workbench extends Disposable implements IPartService { // Warm up font cache information before building up too many dom elements restoreFontInfo(this.storageService); readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), getZoomLevel())); - this._register(this.storageService.onWillSaveState(() => { - saveFontInfo(this.storageService); // Keep font info for next startup around - })); // Create Workbench Container this.createWorkbench(); @@ -400,7 +342,7 @@ export class Workbench extends Disposable implements IPartService { this.registerListeners(); // Settings - this.initSettings(); + this.initState(); // Create Workbench and Parts this.renderWorkbench(); @@ -421,7 +363,6 @@ export class Workbench extends Disposable implements IPartService { private createWorkbench(): void { this.workbench = document.createElement('div'); - this.workbench.id = Identifiers.WORKBENCH_CONTAINER; const platformClass = isWindows ? 'windows' : isLinux ? 'linux' : 'mac'; @@ -565,7 +506,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IContextViewService, this.contextViewService); // Use themable context menus when custom titlebar is enabled to match custom menubar - if (!isMacintosh && this.useCustomTitleBarStyle()) { + if (!isMacintosh && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { serviceCollection.set(IContextMenuService, new SyncDescriptor(HTMLContextMenuService, [null])); } else { serviceCollection.set(IContextMenuService, new SyncDescriptor(NativeContextMenuService)); @@ -589,13 +530,13 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IActivityService, new SyncDescriptor(ActivityService, [this.activitybarPart, this.panelPart], true)); // File Service - this.fileService = this.instantiationService.createInstance(RemoteFileService); - serviceCollection.set(IFileService, this.fileService); - this.configurationService.acquireFileService(this.fileService); - this.themeService.acquireFileService(this.fileService); + const fileService = this.instantiationService.createInstance(RemoteFileService); + serviceCollection.set(IFileService, fileService); + this.configurationService.acquireFileService(fileService); + this.themeService.acquireFileService(fileService); // Editor and Group services - this.editorPart = this.instantiationService.createInstance(EditorPart, Identifiers.EDITOR_PART, !this.hasInitialFilesToOpen); + this.editorPart = this.instantiationService.createInstance(EditorPart, Identifiers.EDITOR_PART, !this.hasInitialFilesToOpen()); this.editorGroupService = this.editorPart; serviceCollection.set(IEditorGroupsService, this.editorPart); this.editorService = this.instantiationService.createInstance(EditorService); @@ -657,6 +598,13 @@ export class Workbench extends Disposable implements IPartService { this.configurationService.acquireInstantiationService(this.instantiationService); } + private hasInitialFilesToOpen(): boolean { + return !!( + (this.configuration.filesToCreate && this.configuration.filesToCreate.length > 0) || + (this.configuration.filesToOpen && this.configuration.filesToOpen.length > 0) || + (this.configuration.filesToDiff && this.configuration.filesToDiff.length > 0)); + } + //#region event handling private registerListeners(): void { @@ -665,21 +613,38 @@ export class Workbench extends Disposable implements IPartService { this._register(this.storageService.onWillSaveState(e => this.saveState(e))); // Restore editor if hidden and it changes - this._register(this.editorService.onDidVisibleEditorsChange(() => this.restoreHiddenEditor())); - this._register(this.editorPart.onDidActivateGroup(() => this.restoreHiddenEditor())); + this._register(this.editorService.onDidVisibleEditorsChange(() => this.setEditorHidden(false))); + this._register(this.editorPart.onDidActivateGroup(() => this.setEditorHidden(false))); // Configuration changes + this._register(this.configurationService.onDidChangeConfiguration(() => this.setFontAliasing())); this._register(this.configurationService.onDidChangeConfiguration(() => this.onDidUpdateConfiguration())); // Fullscreen changes this._register(onDidChangeFullscreen(() => this.onFullscreenChanged())); // Group changes - this._register(this.editorGroupService.onDidAddGroup(() => this.centerEditorLayout(this.shouldCenterLayout))); - this._register(this.editorGroupService.onDidRemoveGroup(() => this.centerEditorLayout(this.shouldCenterLayout))); + this._register(this.editorGroupService.onDidAddGroup(() => this.centerEditorLayout(this.state.editor.centered))); + this._register(this.editorGroupService.onDidRemoveGroup(() => this.centerEditorLayout(this.state.editor.centered))); // Prevent workbench from scrolling #55456 this._register(addDisposableListener(this.workbench, EventType.SCROLL, () => this.workbench.scrollTop = 0)); + + // Menubar visibility changes + if ((isWindows || isLinux) && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { + this._register(this.titlebarPart.onMenubarVisibilityChange(visible => this.onMenubarToggled(visible))); + } + } + + private onMenubarToggled(visible: boolean) { + if (visible !== this.state.menuBar.toggled) { + this.state.menuBar.toggled = visible; + + if (isFullscreen() && (this.state.menuBar.visibility === 'toggle' || this.state.menuBar.visibility === 'default')) { + this._onTitleBarVisibilityChange.fire(); + this.layout(); + } + } } private onFullscreenChanged(): void { @@ -690,65 +655,18 @@ export class Workbench extends Disposable implements IPartService { } else { removeClass(this.workbench, 'fullscreen'); - if (this.zenMode.transitionedToFullScreen && this.zenMode.active) { + if (this.state.zenMode.transitionedToFullScreen && this.state.zenMode.active) { this.toggleZenMode(); } } // Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update - if (this.useCustomTitleBarStyle()) { + if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { this._onTitleBarVisibilityChange.fire(); this.layout(); // handle title bar when fullscreen changes } } - private onMenubarToggled(visible: boolean) { - if (visible !== this.menubarToggled) { - this.menubarToggled = visible; - - if (isFullscreen() && (this.menubarVisibility === 'toggle' || this.menubarVisibility === 'default')) { - this._onTitleBarVisibilityChange.fire(); - this.layout(); - } - } - } - - private restoreHiddenEditor(): void { - if (this.editorHidden) { - this.setEditorHidden(false); - } - } - - private onDidUpdateConfiguration(skipLayout?: boolean): void { - const newSidebarPositionValue = this.configurationService.getValue(Workbench.sidebarPositionConfigurationKey); - const newSidebarPosition = (newSidebarPositionValue === 'right') ? Position.RIGHT : Position.LEFT; - if (newSidebarPosition !== this.getSideBarPosition()) { - this.setSideBarPosition(newSidebarPosition); - } - - this.setPanelPositionFromStorageOrConfig(); - - const fontAliasing = this.configurationService.getValue(Workbench.fontAliasingConfigurationKey); - if (fontAliasing !== this.fontAliasing) { - this.setFontAliasing(fontAliasing); - } - - if (!this.zenMode.active) { - const newStatusbarHiddenValue = !this.configurationService.getValue(Workbench.statusbarVisibleConfigurationKey); - if (newStatusbarHiddenValue !== this.statusBarHidden) { - this.setStatusBarHidden(newStatusbarHiddenValue, skipLayout); - } - - const newActivityBarHiddenValue = !this.configurationService.getValue(Workbench.activityBarVisibleConfigurationKey); - if (newActivityBarHiddenValue !== this.activityBarHidden) { - this.setActivityBarHidden(newActivityBarHiddenValue, skipLayout); - } - } - - const newMenubarVisibility = this.configurationService.getValue(Workbench.menubarVisibilityConfigurationKey); - this.setMenubarVisibility(newMenubarVisibility, !!skipLayout); - } - //#endregion private restoreParts(): Promise { @@ -777,7 +695,7 @@ export class Workbench extends Disposable implements IPartService { // Restore Sidebar let viewletIdToRestore: string | undefined; - if (!this.sideBarHidden) { + if (!this.state.sideBar.hidden) { this.sideBarVisibleContext.set(true); if (this.shouldRestoreLastOpenedViewlet()) { @@ -797,28 +715,26 @@ export class Workbench extends Disposable implements IPartService { // Restore Panel const panelRegistry = Registry.as(PanelExtensions.Panels); const panelId = this.storageService.get(PanelPart.activePanelSettingsKey, StorageScope.WORKSPACE, panelRegistry.getDefaultPanelId()); - if (!this.panelHidden && !!panelId) { + if (!this.state.panel.hidden && !!panelId) { mark('willRestorePanel'); - const isPanelToRestoreEnabled = !!this.panelPart.getPanels().filter(p => p.id === panelId).length; - const panelIdToRestore = isPanelToRestoreEnabled ? panelId : panelRegistry.getDefaultPanelId(); + const panelIdToRestore = this.panelPart.hasPanel(panelId) ? panelId : panelRegistry.getDefaultPanelId(); this.panelPart.openPanel(panelIdToRestore, false); mark('didRestorePanel'); } // Restore Zen Mode if active and supported for restore on startup - const zenConfig = this.configurationService.getValue('zenMode'); - const wasZenActive = this.storageService.getBoolean(Workbench.zenModeActiveStorageKey, StorageScope.WORKSPACE, false); - if (wasZenActive && zenConfig.restore) { + const wasZenActive = this.storageService.getBoolean(State.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false); + if (wasZenActive && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE)) { this.toggleZenMode(true, true); } // Restore Forced Editor Center Mode - if (this.storageService.getBoolean(Workbench.centeredEditorLayoutActiveStorageKey, StorageScope.WORKSPACE, false)) { + if (this.storageService.getBoolean(State.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false)) { this.centerEditorLayout(true); } const onRestored = (error?: Error): void => { - this.workbenchRestored = true; + this.restored = true; // Set lifecycle phase to `Restored` this.lifecycleService.phase = LifecyclePhase.Restored; @@ -835,18 +751,13 @@ export class Workbench extends Disposable implements IPartService { onUnexpectedError(error); } - this.logStartupTelemetry({ - customKeybindingsCount: this.keybindingService.customKeybindingsCount(), - pinnedViewlets: this.activitybarPart.getPinnedViewletIds(), - restoredViewlet: viewletIdToRestore, - restoredEditorsCount: this.editorService.visibleEditors.length - }); + this.logStartupTelemetry(viewletIdToRestore); }; return Promise.all(restorePromises).then(() => onRestored(), error => onRestored(error)); } - private logStartupTelemetry(info: IWorkbenchStartedInfo): void { + private logStartupTelemetry(restoredViewlet: string): void { const { filesToOpen, filesToCreate, filesToDiff } = this.configuration; /* __GDPR__ @@ -877,12 +788,12 @@ export class Workbench extends Disposable implements IPartService { 'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0, 'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0, 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, - customKeybindingsCount: info.customKeybindingsCount, + customKeybindingsCount: this.keybindingService.customKeybindingsCount(), theme: this.themeService.getColorTheme().id, language, - pinnedViewlets: info.pinnedViewlets, - restoredViewlet: info.restoredViewlet, - restoredEditors: info.restoredEditorsCount, + pinnedViewlets: this.activitybarPart.getPinnedViewletIds(), + restoredViewlet: restoredViewlet, + restoredEditors: this.editorService.visibleEditors.length, startupKind: this.lifecycleService.startupKind }); @@ -902,7 +813,7 @@ export class Workbench extends Disposable implements IPartService { private resolveEditorsToOpen(): Promise | IResourceEditor[] { // Files to open, diff or create - if (this.hasInitialFilesToOpen) { + if (this.hasInitialFilesToOpen()) { // Files to diff is exclusive const filesToDiff = this.toInputs(this.configuration.filesToDiff, false); @@ -980,165 +891,23 @@ export class Workbench extends Disposable implements IPartService { return startupEditor.value === 'newUntitledFile'; } - private initSettings(): void { - - // Editor visiblity - this.editorHidden = false; - - // Sidebar visibility - this.sideBarHidden = this.storageService.getBoolean(Workbench.sidebarHiddenStorageKey, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); - - // Panel part visibility - const panelRegistry = Registry.as(PanelExtensions.Panels); - this.panelHidden = this.storageService.getBoolean(Workbench.panelHiddenStorageKey, StorageScope.WORKSPACE, true); - if (!panelRegistry.getDefaultPanelId()) { - this.panelHidden = true; // we hide panel part if there is no default panel - } - - // Sidebar position - const sideBarPosition = this.configurationService.getValue(Workbench.sidebarPositionConfigurationKey); - this.sideBarPosition = (sideBarPosition === 'right') ? Position.RIGHT : Position.LEFT; - - // Panel position - this.setPanelPositionFromStorageOrConfig(); - - // Menubar visibility - const menuBarVisibility = this.configurationService.getValue(Workbench.menubarVisibilityConfigurationKey); - this.setMenubarVisibility(menuBarVisibility, true); - - // Statusbar visibility - const statusBarVisible = this.configurationService.getValue(Workbench.statusbarVisibleConfigurationKey); - this.statusBarHidden = !statusBarVisible; - - // Activity bar visibility - const activityBarVisible = this.configurationService.getValue(Workbench.activityBarVisibleConfigurationKey); - this.activityBarHidden = !activityBarVisible; - - // Font aliasing - this.fontAliasing = this.configurationService.getValue(Workbench.fontAliasingConfigurationKey); - - // Zen mode - this.zenMode = { - active: false, - transitionedToFullScreen: false, - transitionedToCenteredEditorLayout: false, - wasSideBarVisible: false, - wasPanelVisible: false, - transitionDisposeables: [] - }; - } - - private setPanelPositionFromStorageOrConfig() { - const defaultPanelPosition = this.configurationService.getValue(Workbench.defaultPanelPositionStorageKey); - const panelPosition = this.storageService.get(Workbench.panelPositionStorageKey, StorageScope.WORKSPACE, defaultPanelPosition); - - this.panelPosition = (panelPosition === 'right') ? Position.RIGHT : Position.BOTTOM; - } - - private useCustomTitleBarStyle(): boolean { - return getTitleBarStyle(this.configurationService, this.environmentService) === 'custom'; - } - - private saveLastPanelDimension(): void { - if (!(this.workbenchGrid instanceof Grid)) { - return; - } - - if (this.panelPosition === Position.BOTTOM) { - this.uiState.lastPanelHeight = this.workbenchGrid.getViewSize(this.panelPartView); - } else { - this.uiState.lastPanelWidth = this.workbenchGrid.getViewSize(this.panelPartView); - } - } - - private getLastPanelDimension(position: Position): number | undefined { - return position === Position.BOTTOM ? this.uiState.lastPanelHeight : this.uiState.lastPanelWidth; - } - - private setStatusBarHidden(hidden: boolean, skipLayout?: boolean): void { - this.statusBarHidden = hidden; - - // Adjust CSS - if (hidden) { - addClass(this.workbench, 'nostatusbar'); - } else { - removeClass(this.workbench, 'nostatusbar'); - } - - // Layout - if (!skipLayout) { - if (this.workbenchGrid instanceof Grid) { - this.layout(); - } else { - this.workbenchGrid.layout(); - } - } - } - - private setFontAliasing(aliasing: FontAliasingOption) { - this.fontAliasing = aliasing; - - // Remove all - removeClasses(this.workbench, ...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); - - // Add specific - if (fontAliasingValues.some(option => option === aliasing)) { - addClass(this.workbench, `monaco-font-aliasing-${aliasing}`); - } - } - - private createWorkbenchLayout(): void { - if (this.configurationService.getValue('workbench.useExperimentalGridLayout')) { - - // Create view wrappers for all parts - this.titlebarPartView = new View(this.titlebarPart); - this.sidebarPartView = new View(this.sidebarPart); - this.activitybarPartView = new View(this.activitybarPart); - this.editorPartView = new View(this.editorPart); - this.panelPartView = new View(this.panelPart); - this.statusbarPartView = new View(this.statusbarPart); - - this.workbenchGrid = new Grid(this.editorPartView, { proportionalLayout: false }); - - this.workbench.prepend(this.workbenchGrid.element); - } else { - this.workbenchGrid = this.instantiationService.createInstance( - WorkbenchLayout, - this.container, - this.workbench, - { - titlebar: this.titlebarPart, - activitybar: this.activitybarPart, - editor: this.editorPart, - sidebar: this.sidebarPart, - panel: this.panelPart, - statusbar: this.statusbarPart, - }, - this.quickOpen, - this.quickInput, - this.notificationsCenter, - this.notificationsToasts - ); - } - } - private renderWorkbench(): void { // Apply sidebar state as CSS class - if (this.sideBarHidden) { + if (this.state.sideBar.hidden) { addClass(this.workbench, 'nosidebar'); } - if (this.panelHidden) { + if (this.state.panel.hidden) { addClass(this.workbench, 'nopanel'); } - if (this.statusBarHidden) { + if (this.state.statusBar.hidden) { addClass(this.workbench, 'nostatusbar'); } // Apply font aliasing - this.setFontAliasing(this.fontAliasing); + this.setFontAliasing(); // Apply fullscreen state if (isFullscreen()) { @@ -1156,55 +925,66 @@ export class Workbench extends Disposable implements IPartService { // Notification Handlers this.createNotificationsHandlers(); - - // Menubar visibility changes - if ((isWindows || isLinux) && this.useCustomTitleBarStyle()) { - this.titlebarPart.onMenubarVisibilityChange()(e => this.onMenubarToggled(e)); - } - // Add Workbench to DOM this.container.appendChild(this.workbench); } + private setFontAliasing() { + const aliasing = this.configurationService.getValue(Settings.FONT_ALIASING); + if (this.fontAliasing === aliasing) { + return; + } + + this.fontAliasing = aliasing; + + // Remove all + removeClasses(this.workbench, ...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); + + // Add specific + if (fontAliasingValues.some(option => option === aliasing)) { + addClass(this.workbench, `monaco-font-aliasing-${aliasing}`); + } + } + private createTitlebarPart(): void { - const titlebarContainer = this.createPart(Identifiers.TITLEBAR_PART, ['part', 'titlebar'], 'contentinfo'); + const titlebarContainer = this.createPart(Identifiers.TITLEBAR_PART, 'contentinfo', 'titlebar'); this.titlebarPart.create(titlebarContainer); } private createActivityBarPart(): void { - const activitybarPartContainer = this.createPart(Identifiers.ACTIVITYBAR_PART, ['part', 'activitybar', this.sideBarPosition === Position.LEFT ? 'left' : 'right'], 'navigation'); + const activitybarPartContainer = this.createPart(Identifiers.ACTIVITYBAR_PART, 'navigation', 'activitybar', this.state.sideBar.position === Position.LEFT ? 'left' : 'right'); this.activitybarPart.create(activitybarPartContainer); } private createSidebarPart(): void { - const sidebarPartContainer = this.createPart(Identifiers.SIDEBAR_PART, ['part', 'sidebar', this.sideBarPosition === Position.LEFT ? 'left' : 'right'], 'complementary'); + const sidebarPartContainer = this.createPart(Identifiers.SIDEBAR_PART, 'complementary', 'sidebar', this.state.sideBar.position === Position.LEFT ? 'left' : 'right'); this.sidebarPart.create(sidebarPartContainer); } private createPanelPart(): void { - const panelPartContainer = this.createPart(Identifiers.PANEL_PART, ['part', 'panel', this.panelPosition === Position.BOTTOM ? 'bottom' : 'right'], 'complementary'); + const panelPartContainer = this.createPart(Identifiers.PANEL_PART, 'complementary', 'panel', this.state.panel.position === Position.BOTTOM ? 'bottom' : 'right'); this.panelPart.create(panelPartContainer); } private createEditorPart(): void { - const editorContainer = this.createPart(Identifiers.EDITOR_PART, ['part', 'editor'], 'main'); + const editorContainer = this.createPart(Identifiers.EDITOR_PART, 'main', 'editor'); this.editorPart.create(editorContainer); } private createStatusbarPart(): void { - const statusbarContainer = this.createPart(Identifiers.STATUSBAR_PART, ['part', 'statusbar'], 'contentinfo'); + const statusbarContainer = this.createPart(Identifiers.STATUSBAR_PART, 'contentinfo', 'statusbar'); this.statusbarPart.create(statusbarContainer); } - private createPart(id: string, classes: string[], role: string): HTMLElement { + private createPart(id: string, role: string, ...classes: string[]): HTMLElement { const part = document.createElement('div'); - classes.forEach(clazz => addClass(part, clazz)); + addClasses(part, 'part', ...classes); part.id = id; part.setAttribute('role', role); @@ -1246,25 +1026,28 @@ export class Workbench extends Disposable implements IPartService { } private saveState(e: IWillSaveStateEvent): void { - if (this.zenMode.active) { - this.storageService.store(Workbench.zenModeActiveStorageKey, true, StorageScope.WORKSPACE); + + // Zen Mode + if (this.state.zenMode.active) { + this.storageService.store(State.ZEN_MODE_ENABLED, true, StorageScope.WORKSPACE); } else { - this.storageService.remove(Workbench.zenModeActiveStorageKey, StorageScope.WORKSPACE); + this.storageService.remove(State.ZEN_MODE_ENABLED, StorageScope.WORKSPACE); } - if (e.reason === WillSaveStateReason.SHUTDOWN && this.zenMode.active) { - const zenConfig = this.configurationService.getValue('zenMode'); - if (!zenConfig.restore) { - // We will not restore zen mode, need to clear all zen mode state changes - this.toggleZenMode(true); + if (e.reason === WillSaveStateReason.SHUTDOWN && this.state.zenMode.active) { + if (!this.configurationService.getValue(Settings.ZEN_MODE_RESTORE)) { + this.toggleZenMode(true); // We will not restore zen mode, need to clear all zen mode state changes } } + + // Font info + saveFontInfo(this.storageService); } dispose(): void { super.dispose(); - this.workbenchShutdown = true; + this.disposed = true; } //#region IPartService @@ -1274,8 +1057,130 @@ export class Workbench extends Disposable implements IPartService { get onEditorLayout(): Event { return this.editorPart.onDidLayout; } + private workbenchGrid: Grid | WorkbenchLayout; + + private titleBarPartView: View; + private activityBarPartView: View; + private sideBarPartView: View; + private panelPartView: View; + private editorPartView: View; + private statusBarPartView: View; + + private state = { + menuBar: { + visibility: undefined as MenuBarVisibility, + toggled: false + }, + + activityBar: { + hidden: false + }, + + sideBar: { + hidden: false, + position: undefined as Position, + width: 300 + }, + + editor: { + hidden: false, + centered: false + }, + + panel: { + hidden: false, + position: undefined as Position, + height: 350, + width: 350 + }, + + statusBar: { + hidden: false + }, + + zenMode: { + active: false, + transitionedToFullScreen: false, + transitionedToCenteredEditorLayout: false, + wasSideBarVisible: false, + wasPanelVisible: false, + transitionDisposeables: [] as IDisposable[] + } + }; + + private onDidUpdateConfiguration(skipLayout?: boolean): void { + + // Sidebar Position + const newSidebarPositionValue = this.configurationService.getValue(Settings.SIDEBAR_POSITION); + const newSidebarPosition = (newSidebarPositionValue === 'right') ? Position.RIGHT : Position.LEFT; + if (newSidebarPosition !== this.getSideBarPosition()) { + this.setSideBarPosition(newSidebarPosition); + } + + // Panel Position + this.setPanelPositionFromStorageOrConfig(); + + if (!this.state.zenMode.active) { + + // Statusbar Visibility + const newStatusbarHiddenValue = !this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); + if (newStatusbarHiddenValue !== this.state.statusBar.hidden) { + this.setStatusBarHidden(newStatusbarHiddenValue, skipLayout); + } + + // Activitybar Visibility + const newActivityBarHiddenValue = !this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); + if (newActivityBarHiddenValue !== this.state.activityBar.hidden) { + this.setActivityBarHidden(newActivityBarHiddenValue, skipLayout); + } + } + + // Menubar Visibility + const newMenubarVisibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); + this.setMenubarVisibility(newMenubarVisibility, !!skipLayout); + } + + private initState(): void { + + // Sidebar visibility + this.state.sideBar.hidden = this.storageService.getBoolean(State.SIDEBAR_HIDDEN, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); + + // Panel part visibility + const panelRegistry = Registry.as(PanelExtensions.Panels); + this.state.panel.hidden = this.storageService.getBoolean(State.PANEL_HIDDEN, StorageScope.WORKSPACE, true); + if (!panelRegistry.getDefaultPanelId()) { + this.state.panel.hidden = true; // we hide panel part if there is no default panel + } + + // Sidebar Position + const sideBarPosition = this.configurationService.getValue(Settings.SIDEBAR_POSITION); + this.state.sideBar.position = (sideBarPosition === 'right') ? Position.RIGHT : Position.LEFT; + + // Panel Position + this.setPanelPositionFromStorageOrConfig(); + + // Menubar visibility + const menuBarVisibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); + this.setMenubarVisibility(menuBarVisibility, true); + + // Statusbar visibility + const statusBarVisible = this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); + this.state.statusBar.hidden = !statusBarVisible; + + // Activity bar visibility + const activityBarVisible = this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); + this.state.activityBar.hidden = !activityBarVisible; + } + + private setPanelPositionFromStorageOrConfig() { + const defaultPanelPosition = this.configurationService.getValue(Settings.PANEL_POSITION); + const panelPosition = this.storageService.get(State.PANEL_POSITION, StorageScope.WORKSPACE, defaultPanelPosition); + + this.state.panel.position = (panelPosition === 'right') ? Position.RIGHT : Position.BOTTOM; + } + isRestored(): boolean { - return !!(this.workbenchRestored && this.workbenchStarted); + return this.restored; } hasFocus(part: Parts): boolean { @@ -1285,6 +1190,7 @@ export class Workbench extends Disposable implements IPartService { } const container = this.getContainer(part); + return isAncestor(activeElement, container); } @@ -1310,29 +1216,29 @@ export class Workbench extends Disposable implements IPartService { isVisible(part: Parts): boolean { switch (part) { case Parts.TITLEBAR_PART: - if (!this.useCustomTitleBarStyle()) { + if (getTitleBarStyle(this.configurationService, this.environmentService) === 'native') { return false; } else if (!isFullscreen()) { return true; } else if (isMacintosh) { return false; - } else if (this.menubarVisibility === 'visible') { + } else if (this.state.menuBar.visibility === 'visible') { return true; - } else if (this.menubarVisibility === 'toggle' || this.menubarVisibility === 'default') { - return this.menubarToggled; + } else if (this.state.menuBar.visibility === 'toggle' || this.state.menuBar.visibility === 'default') { + return this.state.menuBar.toggled; } return false; case Parts.SIDEBAR_PART: - return !this.sideBarHidden; + return !this.state.sideBar.hidden; case Parts.PANEL_PART: - return !this.panelHidden; + return !this.state.panel.hidden; case Parts.STATUSBAR_PART: - return !this.statusBarHidden; + return !this.state.statusBar.hidden; case Parts.ACTIVITYBAR_PART: - return !this.activityBarHidden; + return !this.state.activityBar.hidden; case Parts.EDITOR_PART: - return this.workbenchGrid instanceof Grid ? !this.editorHidden : true; + return this.workbenchGrid instanceof Grid ? !this.state.editor.hidden : true; } return true; // any other part cannot be hidden @@ -1346,7 +1252,7 @@ export class Workbench extends Disposable implements IPartService { } else { offset = this.workbenchGrid.partLayoutInfo.titlebar.height; - if (isMacintosh || this.menubarVisibility === 'hidden') { + if (isMacintosh || this.state.menuBar.visibility === 'hidden') { offset /= getZoomFactor(); } } @@ -1360,8 +1266,8 @@ export class Workbench extends Disposable implements IPartService { } toggleZenMode(skipLayout?: boolean, restoring = false): void { - this.zenMode.active = !this.zenMode.active; - this.zenMode.transitionDisposeables = dispose(this.zenMode.transitionDisposeables); + this.state.zenMode.active = !this.state.zenMode.active; + this.state.zenMode.transitionDisposeables = dispose(this.state.zenMode.transitionDisposeables); // Check if zen mode transitioned to full screen and if now we are out of zen mode // -> we need to go out of full screen (same goes for the centered editor layout) @@ -1376,14 +1282,21 @@ export class Workbench extends Disposable implements IPartService { }; // Zen Mode Active - if (this.zenMode.active) { - const config = this.configurationService.getValue('zenMode'); + if (this.state.zenMode.active) { + const config: { + fullScreen: boolean; + centerLayout: boolean; + hideTabs: boolean; + hideActivityBar: boolean; + hideStatusBar: boolean; + hideLineNumbers: boolean; + } = this.configurationService.getValue('zenMode'); toggleFullScreen = !isFullscreen() && config.fullScreen; - this.zenMode.transitionedToFullScreen = restoring ? config.fullScreen : toggleFullScreen; - this.zenMode.transitionedToCenteredEditorLayout = !this.isEditorLayoutCentered() && config.centerLayout; - this.zenMode.wasSideBarVisible = this.isVisible(Parts.SIDEBAR_PART); - this.zenMode.wasPanelVisible = this.isVisible(Parts.PANEL_PART); + this.state.zenMode.transitionedToFullScreen = restoring ? config.fullScreen : toggleFullScreen; + this.state.zenMode.transitionedToCenteredEditorLayout = !this.isEditorLayoutCentered() && config.centerLayout; + this.state.zenMode.wasSideBarVisible = this.isVisible(Parts.SIDEBAR_PART); + this.state.zenMode.wasPanelVisible = this.isVisible(Parts.PANEL_PART); this.setPanelHidden(true, true); this.setSideBarHidden(true, true); @@ -1398,11 +1311,11 @@ export class Workbench extends Disposable implements IPartService { if (config.hideLineNumbers) { setLineNumbers('off'); - this.zenMode.transitionDisposeables.push(this.editorService.onDidVisibleEditorsChange(() => setLineNumbers('off'))); + this.state.zenMode.transitionDisposeables.push(this.editorService.onDidVisibleEditorsChange(() => setLineNumbers('off'))); } if (config.hideTabs && this.editorPart.partOptions.showTabs) { - this.zenMode.transitionDisposeables.push(this.editorPart.enforcePartOptions({ showTabs: false })); + this.state.zenMode.transitionDisposeables.push(this.editorPart.enforcePartOptions({ showTabs: false })); } if (config.centerLayout) { @@ -1412,15 +1325,15 @@ export class Workbench extends Disposable implements IPartService { // Zen Mode Inactive else { - if (this.zenMode.wasPanelVisible) { + if (this.state.zenMode.wasPanelVisible) { this.setPanelHidden(false, true); } - if (this.zenMode.wasSideBarVisible) { + if (this.state.zenMode.wasSideBarVisible) { this.setSideBarHidden(false, true); } - if (this.zenMode.transitionedToCenteredEditorLayout) { + if (this.state.zenMode.transitionedToCenteredEditorLayout) { this.centerEditorLayout(false, true); } setLineNumbers(this.configurationService.getValue('editor.lineNumbers')); @@ -1430,10 +1343,10 @@ export class Workbench extends Disposable implements IPartService { this.editorGroupService.activeGroup.focus(); - toggleFullScreen = this.zenMode.transitionedToFullScreen && isFullscreen(); + toggleFullScreen = this.state.zenMode.transitionedToFullScreen && isFullscreen(); } - this.inZenModeContext.set(this.zenMode.active); + this.inZenModeContext.set(this.state.zenMode.active); if (!skipLayout) { this.layout(); @@ -1444,98 +1357,65 @@ export class Workbench extends Disposable implements IPartService { } } - private updateGrid(): void { - if (!(this.workbenchGrid instanceof Grid)) { - return; + private setStatusBarHidden(hidden: boolean, skipLayout?: boolean): void { + this.state.statusBar.hidden = hidden; + + // Adjust CSS + if (hidden) { + addClass(this.workbench, 'nostatusbar'); + } else { + removeClass(this.workbench, 'nostatusbar'); } - let panelInGrid = this.workbenchGrid.hasView(this.panelPartView); - let sidebarInGrid = this.workbenchGrid.hasView(this.sidebarPartView); - let activityBarInGrid = this.workbenchGrid.hasView(this.activitybarPartView); - let statusBarInGrid = this.workbenchGrid.hasView(this.statusbarPartView); - let titlebarInGrid = this.workbenchGrid.hasView(this.titlebarPartView); - - // Add parts to grid - if (!statusBarInGrid) { - this.workbenchGrid.addView(this.statusbarPartView, Sizing.Split, this.editorPartView, Direction.Down); - statusBarInGrid = true; + // Layout + if (!skipLayout) { + if (this.workbenchGrid instanceof Grid) { + this.layout(); + } else { + this.workbenchGrid.layout(); + } } + } - if (!titlebarInGrid && this.useCustomTitleBarStyle()) { - this.workbenchGrid.addView(this.titlebarPartView, Sizing.Split, this.editorPartView, Direction.Up); - titlebarInGrid = true; - } + private createWorkbenchLayout(): void { + if (this.configurationService.getValue('workbench.useExperimentalGridLayout')) { - if (!activityBarInGrid) { - this.workbenchGrid.addView(this.activitybarPartView, Sizing.Split, panelInGrid && this.sideBarPosition === this.panelPosition ? this.panelPartView : this.editorPartView, this.sideBarPosition === Position.RIGHT ? Direction.Right : Direction.Left); - activityBarInGrid = true; - } + // Create view wrappers for all parts + this.titleBarPartView = new View(this.titlebarPart); + this.sideBarPartView = new View(this.sidebarPart); + this.activityBarPartView = new View(this.activitybarPart); + this.editorPartView = new View(this.editorPart); + this.panelPartView = new View(this.panelPart); + this.statusBarPartView = new View(this.statusbarPart); - if (!sidebarInGrid) { - this.workbenchGrid.addView(this.sidebarPartView, this.uiState.lastSidebarDimension !== undefined ? this.uiState.lastSidebarDimension : Sizing.Split, this.activitybarPartView, this.sideBarPosition === Position.LEFT ? Direction.Right : Direction.Left); - sidebarInGrid = true; - } + this.workbenchGrid = new Grid(this.editorPartView, { proportionalLayout: false }); - if (!panelInGrid) { - this.workbenchGrid.addView(this.panelPartView, this.getLastPanelDimension(this.panelPosition) !== undefined ? this.getLastPanelDimension(this.panelPosition) : Sizing.Split, this.editorPartView, this.panelPosition === Position.BOTTOM ? Direction.Down : Direction.Right); - panelInGrid = true; - } - - // Hide parts - if (this.panelHidden) { - this.panelPartView.hide(); - } - - if (this.statusBarHidden) { - this.statusbarPartView.hide(); - } - - if (!this.isVisible(Parts.TITLEBAR_PART)) { - this.titlebarPartView.hide(); - } - - if (this.activityBarHidden) { - this.activitybarPartView.hide(); - } - - if (this.sideBarHidden) { - this.sidebarPartView.hide(); - } - - if (this.editorHidden) { - this.editorPartView.hide(); - } - - // Show visible parts - if (!this.editorHidden) { - this.editorPartView.show(); - } - - if (!this.statusBarHidden) { - this.statusbarPartView.show(); - } - - if (this.isVisible(Parts.TITLEBAR_PART)) { - this.titlebarPartView.show(); - } - - if (!this.activityBarHidden) { - this.activitybarPartView.show(); - } - - if (!this.sideBarHidden) { - this.sidebarPartView.show(); - } - - if (!this.panelHidden) { - this.panelPartView.show(); + this.workbench.prepend(this.workbenchGrid.element); + } else { + this.workbenchGrid = this.instantiationService.createInstance( + WorkbenchLayout, + this.container, + this.workbench, + { + titlebar: this.titlebarPart, + activitybar: this.activitybarPart, + editor: this.editorPart, + sidebar: this.sidebarPart, + panel: this.panelPart, + statusbar: this.statusbarPart, + }, + this.quickOpen, + this.quickInput, + this.notificationsCenter, + this.notificationsToasts + ); } } layout(options?: ILayoutOptions): void { this.contextViewService.layout(); - if (this.workbenchStarted && !this.workbenchShutdown) { + if (!this.disposed) { if (this.workbenchGrid instanceof Grid) { const dimensions = getClientArea(this.container); position(this.workbench, 0, 0, 0, 0, 'relative'); @@ -1550,21 +1430,110 @@ export class Workbench extends Disposable implements IPartService { this.notificationsCenter.layout(dimensions); this.notificationsToasts.layout(dimensions); - // Update grid view membership - this.updateGrid(); + // Layout Grid + this.layoutGrid(); } else { this.workbenchGrid.layout(options); } } } + private layoutGrid(): void { + if (!(this.workbenchGrid instanceof Grid)) { + return; + } + + let panelInGrid = this.workbenchGrid.hasView(this.panelPartView); + let sidebarInGrid = this.workbenchGrid.hasView(this.sideBarPartView); + let activityBarInGrid = this.workbenchGrid.hasView(this.activityBarPartView); + let statusBarInGrid = this.workbenchGrid.hasView(this.statusBarPartView); + let titlebarInGrid = this.workbenchGrid.hasView(this.titleBarPartView); + + // Add parts to grid + if (!statusBarInGrid) { + this.workbenchGrid.addView(this.statusBarPartView, Sizing.Split, this.editorPartView, Direction.Down); + statusBarInGrid = true; + } + + if (!titlebarInGrid && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { + this.workbenchGrid.addView(this.titleBarPartView, Sizing.Split, this.editorPartView, Direction.Up); + titlebarInGrid = true; + } + + if (!activityBarInGrid) { + this.workbenchGrid.addView(this.activityBarPartView, Sizing.Split, panelInGrid && this.state.sideBar.position === this.state.panel.position ? this.panelPartView : this.editorPartView, this.state.sideBar.position === Position.RIGHT ? Direction.Right : Direction.Left); + activityBarInGrid = true; + } + + if (!sidebarInGrid) { + this.workbenchGrid.addView(this.sideBarPartView, this.state.sideBar.width !== undefined ? this.state.sideBar.width : Sizing.Split, this.activityBarPartView, this.state.sideBar.position === Position.LEFT ? Direction.Right : Direction.Left); + sidebarInGrid = true; + } + + if (!panelInGrid) { + this.workbenchGrid.addView(this.panelPartView, this.getPanelDimension(this.state.panel.position) !== undefined ? this.getPanelDimension(this.state.panel.position) : Sizing.Split, this.editorPartView, this.state.panel.position === Position.BOTTOM ? Direction.Down : Direction.Right); + panelInGrid = true; + } + + // Hide parts + if (this.state.panel.hidden) { + this.panelPartView.hide(); + } + + if (this.state.statusBar.hidden) { + this.statusBarPartView.hide(); + } + + if (!this.isVisible(Parts.TITLEBAR_PART)) { + this.titleBarPartView.hide(); + } + + if (this.state.activityBar.hidden) { + this.activityBarPartView.hide(); + } + + if (this.state.sideBar.hidden) { + this.sideBarPartView.hide(); + } + + if (this.state.editor.hidden) { + this.editorPartView.hide(); + } + + // Show visible parts + if (!this.state.editor.hidden) { + this.editorPartView.show(); + } + + if (!this.state.statusBar.hidden) { + this.statusBarPartView.show(); + } + + if (this.isVisible(Parts.TITLEBAR_PART)) { + this.titleBarPartView.show(); + } + + if (!this.state.activityBar.hidden) { + this.activityBarPartView.show(); + } + + if (!this.state.sideBar.hidden) { + this.sideBarPartView.show(); + } + + if (!this.state.panel.hidden) { + this.panelPartView.show(); + } + } + isEditorLayoutCentered(): boolean { - return this.shouldCenterLayout; + return this.state.editor.centered; } centerEditorLayout(active: boolean, skipLayout?: boolean): void { - this.storageService.store(Workbench.centeredEditorLayoutActiveStorageKey, active, StorageScope.WORKSPACE); - this.shouldCenterLayout = active; + this.storageService.store(State.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE); + this.state.editor.centered = active; + let smartActive = active; if (this.editorPart.groups.length > 1 && this.configurationService.getValue('workbench.editor.centeredLayoutAutoResize')) { smartActive = false; // Respect the auto resize setting - do not go into centered layout if there is more than 1 group. @@ -1584,7 +1553,7 @@ export class Workbench extends Disposable implements IPartService { let view: View; switch (part) { case Parts.SIDEBAR_PART: - view = this.sidebarPartView; + view = this.sideBarPartView; case Parts.PANEL_PART: view = this.panelPartView; case Parts.EDITOR_PART: @@ -1601,7 +1570,7 @@ export class Workbench extends Disposable implements IPartService { } setActivityBarHidden(hidden: boolean, skipLayout?: boolean): void { - this.activityBarHidden = hidden; + this.state.activityBar.hidden = hidden; // Layout if (!skipLayout) { @@ -1614,14 +1583,14 @@ export class Workbench extends Disposable implements IPartService { } setEditorHidden(hidden: boolean, skipLayout?: boolean): void { - if (!(this.workbenchGrid instanceof Grid)) { + if (!(this.workbenchGrid instanceof Grid) || hidden === this.state.editor.hidden) { return; } - this.editorHidden = hidden; + this.state.editor.hidden = hidden; // The editor and the panel cannot be hidden at the same time - if (this.editorHidden && this.panelHidden) { + if (this.state.editor.hidden && this.state.panel.hidden) { this.setPanelHidden(false, true); } @@ -1631,7 +1600,7 @@ export class Workbench extends Disposable implements IPartService { } setSideBarHidden(hidden: boolean, skipLayout?: boolean): void { - this.sideBarHidden = hidden; + this.state.sideBar.hidden = hidden; this.sideBarVisibleContext.set(!hidden); // Adjust CSS @@ -1644,9 +1613,9 @@ export class Workbench extends Disposable implements IPartService { // If sidebar becomes hidden, also hide the current active Viewlet if any if (hidden && this.sidebarPart.getActiveViewlet()) { this.sidebarPart.hideActiveViewlet(); - const activePanel = this.panelPart.getActivePanel(); // Pass Focus to Editor or Panel if Sidebar is now hidden + const activePanel = this.panelPart.getActivePanel(); if (this.hasFocus(Parts.PANEL_PART) && activePanel) { activePanel.focus(); } else { @@ -1668,9 +1637,9 @@ export class Workbench extends Disposable implements IPartService { // Remember in settings const defaultHidden = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY; if (hidden !== defaultHidden) { - this.storageService.store(Workbench.sidebarHiddenStorageKey, hidden ? 'true' : 'false', StorageScope.WORKSPACE); + this.storageService.store(State.SIDEBAR_HIDDEN, hidden ? 'true' : 'false', StorageScope.WORKSPACE); } else { - this.storageService.remove(Workbench.sidebarHiddenStorageKey, StorageScope.WORKSPACE); + this.storageService.remove(State.SIDEBAR_HIDDEN, StorageScope.WORKSPACE); } // Layout @@ -1684,7 +1653,7 @@ export class Workbench extends Disposable implements IPartService { } setPanelHidden(hidden: boolean, skipLayout?: boolean): void { - this.panelHidden = hidden; + this.state.panel.hidden = hidden; // Adjust CSS if (hidden) { @@ -1710,13 +1679,13 @@ export class Workbench extends Disposable implements IPartService { // Remember in settings if (!hidden) { - this.storageService.store(Workbench.panelHiddenStorageKey, 'false', StorageScope.WORKSPACE); + this.storageService.store(State.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE); } else { - this.storageService.remove(Workbench.panelHiddenStorageKey, StorageScope.WORKSPACE); + this.storageService.remove(State.PANEL_HIDDEN, StorageScope.WORKSPACE); } - // The editor and panel cannot be hiddne at the same time - if (hidden && this.editorHidden) { + // The editor and panel cannot be hidden at the same time + if (hidden && this.state.editor.hidden) { this.setEditorHidden(false, true); } @@ -1751,19 +1720,19 @@ export class Workbench extends Disposable implements IPartService { } getSideBarPosition(): Position { - return this.sideBarPosition; + return this.state.sideBar.position; } - setSideBarPosition(position: Position): void { - const wasHidden = this.sideBarHidden; + private setSideBarPosition(position: Position): void { + const wasHidden = this.state.sideBar.hidden; - if (this.sideBarHidden) { + if (this.state.sideBar.hidden) { this.setSideBarHidden(false, true /* Skip Layout */); } const newPositionValue = (position === Position.LEFT) ? 'left' : 'right'; - const oldPositionValue = (this.sideBarPosition === Position.LEFT) ? 'left' : 'right'; - this.sideBarPosition = position; + const oldPositionValue = (this.state.sideBar.position === Position.LEFT) ? 'left' : 'right'; + this.state.sideBar.position = position; // Adjust CSS removeClass(this.activitybarPart.getContainer(), oldPositionValue); @@ -1777,15 +1746,14 @@ export class Workbench extends Disposable implements IPartService { // Layout if (this.workbenchGrid instanceof Grid) { - if (!wasHidden) { - this.uiState.lastSidebarDimension = this.workbenchGrid.getViewSize(this.sidebarPartView); + this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView); } - this.workbenchGrid.removeView(this.sidebarPartView); - this.workbenchGrid.removeView(this.activitybarPartView); + this.workbenchGrid.removeView(this.sideBarPartView); + this.workbenchGrid.removeView(this.activityBarPartView); - if (!this.panelHidden && this.panelPosition === Position.BOTTOM) { + if (!this.state.panel.hidden && this.state.panel.position === Position.BOTTOM) { this.workbenchGrid.removeView(this.panelPartView); } @@ -1796,8 +1764,8 @@ export class Workbench extends Disposable implements IPartService { } setMenubarVisibility(visibility: MenuBarVisibility, skipLayout: boolean): void { - if (this.menubarVisibility !== visibility) { - this.menubarVisibility = visibility; + if (this.state.menuBar.visibility !== visibility) { + this.state.menuBar.visibility = visibility; // Layout if (!skipLayout) { @@ -1812,26 +1780,26 @@ export class Workbench extends Disposable implements IPartService { } getMenubarVisibility(): MenuBarVisibility { - return this.menubarVisibility; + return this.state.menuBar.visibility; } getPanelPosition(): Position { - return this.panelPosition; + return this.state.panel.position; } setPanelPosition(position: Position): void { - const wasHidden = this.panelHidden; + const wasHidden = this.state.panel.hidden; - if (this.panelHidden) { + if (this.state.panel.hidden) { this.setPanelHidden(false, true /* Skip Layout */); } else { - this.saveLastPanelDimension(); + this.savePanelDimension(); } const newPositionValue = (position === Position.BOTTOM) ? 'bottom' : 'right'; - const oldPositionValue = (this.panelPosition === Position.BOTTOM) ? 'bottom' : 'right'; - this.panelPosition = position; - this.storageService.store(Workbench.panelPositionStorageKey, PositionToString(this.panelPosition).toLowerCase(), StorageScope.WORKSPACE); + const oldPositionValue = (this.state.panel.position === Position.BOTTOM) ? 'bottom' : 'right'; + this.state.panel.position = position; + this.storageService.store(State.PANEL_POSITION, PositionToString(this.state.panel.position).toLowerCase(), StorageScope.WORKSPACE); // Adjust CSS removeClass(this.panelPart.getContainer(), oldPositionValue); @@ -1843,7 +1811,7 @@ export class Workbench extends Disposable implements IPartService { // Layout if (this.workbenchGrid instanceof Grid) { if (!wasHidden) { - this.saveLastPanelDimension(); + this.savePanelDimension(); } this.workbenchGrid.removeView(this.panelPartView); @@ -1853,5 +1821,21 @@ export class Workbench extends Disposable implements IPartService { } } + private getPanelDimension(position: Position): number | undefined { + return position === Position.BOTTOM ? this.state.panel.height : this.state.panel.width; + } + + private savePanelDimension(): void { + if (!(this.workbenchGrid instanceof Grid)) { + return; + } + + if (this.state.panel.position === Position.BOTTOM) { + this.state.panel.height = this.workbenchGrid.getViewSize(this.panelPartView); + } else { + this.state.panel.width = this.workbenchGrid.getViewSize(this.panelPartView); + } + } + //#endregion -} +} \ No newline at end of file diff --git a/src/vs/workbench/services/activity/browser/activityService.ts b/src/vs/workbench/services/activity/browser/activityService.ts index a5230bd32ae..e75331d2e3c 100644 --- a/src/vs/workbench/services/activity/browser/activityService.ts +++ b/src/vs/workbench/services/activity/browser/activityService.ts @@ -30,5 +30,4 @@ export class ActivityService implements IActivityService { getPinnedViewletIds(): string[] { return this.activitybarPart.getPinnedViewletIds(); } - } From cdbe7bff05ef8232726c4c2da00046dc2314f561 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 08:42:51 +0100 Subject: [PATCH 094/290] resolve #69734 on master --- src/vs/workbench/browser/media/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/media/style.css b/src/vs/workbench/browser/media/style.css index 0bd743e7af5..488552dc37c 100644 --- a/src/vs/workbench/browser/media/style.css +++ b/src/vs/workbench/browser/media/style.css @@ -91,16 +91,16 @@ body { cursor: pointer; } -.monaco-workbench .monaco-font-aliasing-antialiased { +.monaco-workbench.monaco-font-aliasing-antialiased { -webkit-font-smoothing: antialiased; } -.monaco-workbench .monaco-font-aliasing-none { +.monaco-workbench.monaco-font-aliasing-none { -webkit-font-smoothing: none; } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { - .monaco-workbench .monaco-font-aliasing-auto { + .monaco-workbench.monaco-font-aliasing-auto { -webkit-font-smoothing: antialiased; } } From f6703e50429d4885132381eea457ad560945bd60 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 09:18:00 +0100 Subject: [PATCH 095/290] debt - group context keys in one place --- src/vs/workbench/browser/contextkeys.ts | 33 +++++++++++++++++-- .../workbench/electron-browser/workbench.ts | 24 +++++--------- .../services/part/common/partService.ts | 5 +++ 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/browser/contextkeys.ts b/src/vs/workbench/browser/contextkeys.ts index 098badbdae0..79e2037b343 100644 --- a/src/vs/workbench/browser/contextkeys.ts +++ b/src/vs/workbench/browser/contextkeys.ts @@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { InputFocusedContext } from 'vs/platform/contextkey/common/contextkeys'; import { IWindowConfiguration, IWindowService } from 'vs/platform/windows/common/windows'; -import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically } from 'vs/workbench/common/editor'; +import { ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, TEXT_DIFF_EDITOR_ID, SplitEditorsVertically, InEditorZenModeContext } from 'vs/workbench/common/editor'; import { IsMacContext, IsLinuxContext, IsWindowsContext, HasMacNativeTabsContext, IsDevelopmentContext, SupportsWorkspacesContext, SupportsOpenFileFolderContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/common/contextkeys'; import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom'; import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -17,18 +17,28 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { EditorGroupsServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; +import { SidebarVisibleContext } from 'vs/workbench/common/viewlet'; +import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; export class WorkbenchContextKeysHandler extends Disposable { private inputFocusedContext: IContextKey; + private activeEditorContext: IContextKey; private editorsVisibleContext: IContextKey; private textCompareEditorVisibleContext: IContextKey; private textCompareEditorActiveContext: IContextKey; private activeEditorGroupEmpty: IContextKey; private multipleEditorGroupsContext: IContextKey; + private splitEditorsVerticallyContext: IContextKey; + private workbenchStateContext: IContextKey; private workspaceFolderCountContext: IContextKey; - private splitEditorsVerticallyContext: IContextKey; + + + private inZenModeContext: IContextKey; + + private sideBarVisibleContext: IContextKey; constructor( @IContextKeyService private contextKeyService: IContextKeyService, @@ -37,7 +47,9 @@ export class WorkbenchContextKeysHandler extends Disposable { @IEnvironmentService private environmentService: IEnvironmentService, @IWindowService private windowService: IWindowService, @IEditorService private editorService: IEditorService, - @IEditorGroupsService private editorGroupService: EditorGroupsServiceImpl + @IEditorGroupsService private editorGroupService: EditorGroupsServiceImpl, + @IPartService private partService: IPartService, + @IViewletService private viewletService: IViewletService ) { super(); @@ -63,6 +75,11 @@ export class WorkbenchContextKeysHandler extends Disposable { this.updateSplitEditorsVerticallyContext(); } })); + + this._register(this.partService.onZenModeChange(enabled => this.inZenModeContext.set(enabled))); + + this._register(this.viewletService.onDidViewletClose(() => this.updateSideBarContextKeys())); + this._register(this.viewletService.onDidViewletOpen(() => this.updateSideBarContextKeys())); } private initContextKeys(): void { @@ -105,6 +122,12 @@ export class WorkbenchContextKeysHandler extends Disposable { // Editor Layout this.splitEditorsVerticallyContext = SplitEditorsVertically.bindTo(this.contextKeyService); this.updateSplitEditorsVerticallyContext(); + + // Zen Mode + this.inZenModeContext = InEditorZenModeContext.bindTo(this.contextKeyService); + + // Sidebar + this.sideBarVisibleContext = SidebarVisibleContext.bindTo(this.contextKeyService); } private updateEditorContextKeys(): void { @@ -178,4 +201,8 @@ export class WorkbenchContextKeysHandler extends Disposable { case WorkbenchState.WORKSPACE: return 'workspace'; } } + + private updateSideBarContextKeys(): void { + this.sideBarVisibleContext.set(this.partService.isVisible(Parts.SIDEBAR_PART)); + } } \ 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 a6bc3e655bf..50ec10caaf9 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -19,7 +19,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { isWindows, isLinux, isMacintosh, language } 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, IUntitledResourceInput, IResourceDiffInput, InEditorZenModeContext } from 'vs/workbench/common/editor'; +import { IEditorInputFactoryRegistry, Extensions as EditorExtensions, IUntitledResourceInput, IResourceDiffInput } from 'vs/workbench/common/editor'; import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart'; import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart'; @@ -40,7 +40,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IActivityService } from 'vs/workbench/services/activity/common/activity'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IFileService } from 'vs/platform/files/common/files'; @@ -111,7 +111,6 @@ import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/work import { IProductService } from 'vs/platform/product/common/product'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; -import { SidebarVisibleContext } from 'vs/workbench/common/viewlet'; // import@node import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; @@ -202,7 +201,6 @@ export class Workbench extends Disposable implements IPartService { private editorService: EditorService; private editorGroupService: IEditorGroupsService; private contextViewService: ContextViewService; - private contextKeyService: IContextKeyService; private keybindingService: IKeybindingService; private backupFileService: IBackupFileService; private notificationService: NotificationService; @@ -225,8 +223,6 @@ export class Workbench extends Disposable implements IPartService { private notificationsToasts: NotificationsToasts; private fontAliasing: FontAliasingOption; - private inZenModeContext: IContextKey; - private sideBarVisibleContext: IContextKey; constructor( private container: HTMLElement, @@ -335,8 +331,6 @@ export class Workbench extends Disposable implements IPartService { // Context Keys this._register(this.instantiationService.createInstance(WorkbenchContextKeysHandler)); - this.inZenModeContext = InEditorZenModeContext.bindTo(this.contextKeyService); - this.sideBarVisibleContext = SidebarVisibleContext.bindTo(this.contextKeyService); // Register Listeners this.registerListeners(); @@ -494,8 +488,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IStatusbarService, this.statusbarPart); // Context Keys - this.contextKeyService = this.instantiationService.createInstance(ContextKeyService); - serviceCollection.set(IContextKeyService, this.contextKeyService); + serviceCollection.set(IContextKeyService, new SyncDescriptor(ContextKeyService)); // Keybindings this.keybindingService = this.instantiationService.createInstance(WorkbenchKeybindingService, window); @@ -696,8 +689,6 @@ export class Workbench extends Disposable implements IPartService { // Restore Sidebar let viewletIdToRestore: string | undefined; if (!this.state.sideBar.hidden) { - this.sideBarVisibleContext.set(true); - if (this.shouldRestoreLastOpenedViewlet()) { viewletIdToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE); } @@ -1055,6 +1046,9 @@ export class Workbench extends Disposable implements IPartService { private readonly _onTitleBarVisibilityChange: Emitter = this._register(new Emitter()); get onTitleBarVisibilityChange(): Event { return this._onTitleBarVisibilityChange.event; } + private readonly _onZenMode: Emitter = this._register(new Emitter()); + get onZenModeChange(): Event { return this._onZenMode.event; } + get onEditorLayout(): Event { return this.editorPart.onDidLayout; } private workbenchGrid: Grid | WorkbenchLayout; @@ -1346,8 +1340,6 @@ export class Workbench extends Disposable implements IPartService { toggleFullScreen = this.state.zenMode.transitionedToFullScreen && isFullscreen(); } - this.inZenModeContext.set(this.state.zenMode.active); - if (!skipLayout) { this.layout(); } @@ -1355,6 +1347,9 @@ export class Workbench extends Disposable implements IPartService { if (toggleFullScreen) { this.windowService.toggleFullScreen(); } + + // Event + this._onZenMode.fire(this.state.zenMode.active); } private setStatusBarHidden(hidden: boolean, skipLayout?: boolean): void { @@ -1601,7 +1596,6 @@ export class Workbench extends Disposable implements IPartService { setSideBarHidden(hidden: boolean, skipLayout?: boolean): void { this.state.sideBar.hidden = hidden; - this.sideBarVisibleContext.set(!hidden); // Adjust CSS if (hidden) { diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index c779417568b..07c381500f6 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -49,6 +49,11 @@ export interface IPartService { */ onTitleBarVisibilityChange: Event; + /** + * Emits when the zen mode is enabled or disabled. + */ + onZenModeChange: Event; + /** * Emits when the editor part's layout changes. */ From c10ea17d96516e53a542b3982f556a1bca1c99cb Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 4 Mar 2019 09:31:27 +0100 Subject: [PATCH 096/290] Syntax highlighting and check for .ipy files. Fixes #69694 --- extensions/python/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/python/package.json b/extensions/python/package.json index c81942af764..53ca25bd88f 100644 --- a/extensions/python/package.json +++ b/extensions/python/package.json @@ -10,7 +10,7 @@ "contributes": { "languages": [{ "id": "python", - "extensions": [ ".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi", ".snakefile", ".smk", ".pyi"], + "extensions": [ ".py", ".rpy", ".pyw", ".cpy", ".gyp", ".gypi", ".snakefile", ".smk", ".pyi", ".ipy"], "aliases": [ "Python", "py" ], "firstLine": "^#!\\s*/.*\\bpython[0-9.-]*\\b", "configuration": "./language-configuration.json" From 6311e9ba1c21150a9d65a8371e0d9f50f08d4409 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 09:42:33 +0100 Subject: [PATCH 097/290] fix compile --- src/vs/workbench/test/workbenchTestServices.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index d605a994a11..a3ff5279c3c 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -444,6 +444,8 @@ export class TestPartService implements IPartService { public _serviceBrand: any; + onZenModeChange: Event = Event.None; + private _onTitleBarVisibilityChange = new Emitter(); private _onMenubarVisibilityChange = new Emitter(); private _onEditorLayout = new Emitter(); From 595ac89613b2626e53025746b4a95bc5e9f4513f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 10:35:08 +0100 Subject: [PATCH 098/290] debt - move more things into workbench state object --- src/vs/workbench/browser/panel.ts | 7 + .../browser/parts/panel/panelPart.ts | 4 - .../workbench/electron-browser/workbench.ts | 336 ++++++++++-------- 3 files changed, 185 insertions(+), 162 deletions(-) diff --git a/src/vs/workbench/browser/panel.ts b/src/vs/workbench/browser/panel.ts index eee8dbfc218..d33465167e2 100644 --- a/src/vs/workbench/browser/panel.ts +++ b/src/vs/workbench/browser/panel.ts @@ -61,6 +61,13 @@ export class PanelRegistry extends CompositeRegistry { getDefaultPanelId(): string { return this.defaultPanelId; } + + /** + * Find out if a panel exists with the provided ID. + */ + hasPanel(id: string): boolean { + return this.getPanels().some(panel => panel.id === id); + } } /** diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 87c274bf9ea..04dbc490a5c 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -234,10 +234,6 @@ export class PanelPart extends CompositePart implements IPanelService, IS return this.getPanels().filter(p => p.id === panelId).pop(); } - hasPanel(panelId: string): boolean { - return !!this.getPanels().filter(p => p.id === panelId).length; - } - getPanels(): PanelDescriptor[] { return Registry.as(PanelExtensions.Panels).getPanels() .sort((v1, v2) => typeof v1.order === 'number' && typeof v2.order === 'number' ? v1.order - v2.order : NaN); diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 50ec10caaf9..77d601e49b3 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -28,6 +28,7 @@ import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart'; import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actions'; import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel'; +import { ViewletRegistry, Extensions as ViewletExtensions } from 'vs/workbench/browser/viewlet'; import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickOpenController'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { QuickInputService } from 'vs/workbench/browser/parts/quickinput/quickInput'; @@ -677,78 +678,63 @@ export class Workbench extends Disposable implements IPartService { return Promise.resolve(undefined); } - const editorsToOpen = this.resolveEditorsToOpen(); - - if (Array.isArray(editorsToOpen)) { - return openEditors(editorsToOpen, this.editorService); + if (Array.isArray(this.state.editor.editorsToOpen)) { + return openEditors(this.state.editor.editorsToOpen, this.editorService); } - return editorsToOpen.then(editors => openEditors(editors, this.editorService)); + return this.state.editor.editorsToOpen.then(editors => openEditors(editors, this.editorService)); }).then(() => mark('didRestoreEditors'))); // Restore Sidebar - let viewletIdToRestore: string | undefined; - if (!this.state.sideBar.hidden) { - if (this.shouldRestoreLastOpenedViewlet()) { - viewletIdToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE); - } - - if (!viewletIdToRestore) { - viewletIdToRestore = this.sidebarPart.getDefaultViewletId(); - } - + if (this.state.sideBar.viewletToRestore) { mark('willRestoreViewlet'); - restorePromises.push(this.sidebarPart.openViewlet(viewletIdToRestore) + restorePromises.push(this.sidebarPart.openViewlet(this.state.sideBar.viewletToRestore) .then(viewlet => viewlet || this.sidebarPart.openViewlet(this.sidebarPart.getDefaultViewletId())) .then(() => mark('didRestoreViewlet'))); } // Restore Panel - const panelRegistry = Registry.as(PanelExtensions.Panels); - const panelId = this.storageService.get(PanelPart.activePanelSettingsKey, StorageScope.WORKSPACE, panelRegistry.getDefaultPanelId()); - if (!this.state.panel.hidden && !!panelId) { + if (this.state.panel.panelToRestore) { mark('willRestorePanel'); - const panelIdToRestore = this.panelPart.hasPanel(panelId) ? panelId : panelRegistry.getDefaultPanelId(); - this.panelPart.openPanel(panelIdToRestore, false); + this.panelPart.openPanel(this.state.panel.panelToRestore, false); mark('didRestorePanel'); } - // Restore Zen Mode if active and supported for restore on startup - const wasZenActive = this.storageService.getBoolean(State.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false); - if (wasZenActive && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE)) { + // Restore Zen Mode + if (this.state.zenMode.restore) { this.toggleZenMode(true, true); } - // Restore Forced Editor Center Mode - if (this.storageService.getBoolean(State.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false)) { + // Restore Editor Center Mode + if (this.state.editor.restoreCentered) { this.centerEditorLayout(true); } - const onRestored = (error?: Error): void => { - this.restored = true; - - // Set lifecycle phase to `Restored` - this.lifecycleService.phase = LifecyclePhase.Restored; - - // Set lifecycle phase to `Eventually` after a short delay and when - // idle (min 2.5sec, max 5sec) - setTimeout(() => { - this._register(runWhenIdle(() => { - this.lifecycleService.phase = LifecyclePhase.Eventually; - }, 2500)); - }, 2500); - - if (error) { - onUnexpectedError(error); - } - - this.logStartupTelemetry(viewletIdToRestore); - }; - - return Promise.all(restorePromises).then(() => onRestored(), error => onRestored(error)); + return Promise.all(restorePromises).then(() => this.whenRestored(), error => this.whenRestored(error)); } - private logStartupTelemetry(restoredViewlet: string): void { + private whenRestored(error?: Error): void { + this.restored = true; + + // Set lifecycle phase to `Restored` + this.lifecycleService.phase = LifecyclePhase.Restored; + + // Set lifecycle phase to `Eventually` after a short delay and when + // idle (min 2.5sec, max 5sec) + setTimeout(() => { + this._register(runWhenIdle(() => { + this.lifecycleService.phase = LifecyclePhase.Eventually; + }, 2500)); + }, 2500); + + if (error) { + onUnexpectedError(error); + } + + this.logStartupTelemetry(); + } + + private logStartupTelemetry(): void { const { filesToOpen, filesToCreate, filesToDiff } = this.configuration; /* __GDPR__ @@ -783,7 +769,7 @@ export class Workbench extends Disposable implements IPartService { theme: this.themeService.getColorTheme().id, language, pinnedViewlets: this.activitybarPart.getPinnedViewletIds(), - restoredViewlet: restoredViewlet, + restoredViewlet: this.state.sideBar.viewletToRestore, restoredEditors: this.editorService.visibleEditors.length, startupKind: this.lifecycleService.startupKind }); @@ -792,96 +778,6 @@ export class Workbench extends Disposable implements IPartService { mark('didStartWorkbench'); } - private shouldRestoreLastOpenedViewlet(): boolean { - if (!this.environmentService.isBuilt) { - return true; // always restore sidebar when we are in development mode - } - - // always restore sidebar when the window was reloaded - return this.lifecycleService.startupKind === StartupKind.ReloadedWindow; - } - - private resolveEditorsToOpen(): Promise | IResourceEditor[] { - - // Files to open, diff or create - if (this.hasInitialFilesToOpen()) { - - // Files to diff is exclusive - const filesToDiff = this.toInputs(this.configuration.filesToDiff, false); - if (filesToDiff && filesToDiff.length === 2) { - return [{ - leftResource: filesToDiff[0].resource, - rightResource: filesToDiff[1].resource, - options: { pinned: true }, - forceFile: true - }]; - } - - const filesToCreate = this.toInputs(this.configuration.filesToCreate, true); - const filesToOpen = this.toInputs(this.configuration.filesToOpen, false); - - // Otherwise: Open/Create files - return [...filesToOpen, ...filesToCreate]; - } - - // Empty workbench - else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && this.openUntitledFile()) { - const isEmpty = this.editorGroupService.count === 1 && this.editorGroupService.activeGroup.count === 0; - if (!isEmpty) { - return []; // do not open any empty untitled file if we restored editors from previous session - } - - return this.backupFileService.hasBackups().then(hasBackups => { - if (hasBackups) { - return []; // do not open any empty untitled file if we have backups to restore - } - - return [{}]; - }); - } - - return []; - } - - private toInputs(paths: IPath[], isNew: boolean): Array { - if (!paths || !paths.length) { - return []; - } - - return paths.map(p => { - const resource = p.fileUri; - let input: IResourceInput | IUntitledResourceInput; - if (isNew) { - input = { filePath: resource.fsPath, options: { pinned: true } } as IUntitledResourceInput; - } else { - input = { resource, options: { pinned: true }, forceFile: true } as IResourceInput; - } - - if (!isNew && p.lineNumber) { - input.options.selection = { - startLineNumber: p.lineNumber, - startColumn: p.columnNumber - }; - } - - return input; - }); - } - - private openUntitledFile() { - const startupEditor = this.configurationService.inspect('workbench.startupEditor'); - - // Fallback to previous workbench.welcome.enabled setting in case startupEditor is not defined - if (!startupEditor.user && !startupEditor.workspace) { - const welcomeEnabledValue = this.configurationService.getValue('workbench.welcome.enabled'); - if (typeof welcomeEnabledValue === 'boolean') { - return !welcomeEnabledValue; - } - } - - return startupEditor.value === 'newUntitledFile'; - } - private renderWorkbench(): void { // Apply sidebar state as CSS class @@ -1073,19 +969,23 @@ export class Workbench extends Disposable implements IPartService { sideBar: { hidden: false, position: undefined as Position, - width: 300 + width: 300, + viewletToRestore: undefined as string }, editor: { hidden: false, - centered: false + centered: false, + restoreCentered: false, + editorsToOpen: undefined as Promise | IResourceEditor[] }, panel: { hidden: false, position: undefined as Position, height: 350, - width: 350 + width: 350, + panelToRestore: undefined as string }, statusBar: { @@ -1094,6 +994,7 @@ export class Workbench extends Disposable implements IPartService { zenMode: { active: false, + restore: false, transitionedToFullScreen: false, transitionedToCenteredEditorLayout: false, wasSideBarVisible: false, @@ -1136,34 +1037,153 @@ export class Workbench extends Disposable implements IPartService { private initState(): void { + // Menubar visibility + this.state.menuBar.visibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); + + // Activity bar visibility + this.state.activityBar.hidden = !this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); + // Sidebar visibility this.state.sideBar.hidden = this.storageService.getBoolean(State.SIDEBAR_HIDDEN, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); - // Panel part visibility - const panelRegistry = Registry.as(PanelExtensions.Panels); - this.state.panel.hidden = this.storageService.getBoolean(State.PANEL_HIDDEN, StorageScope.WORKSPACE, true); - if (!panelRegistry.getDefaultPanelId()) { - this.state.panel.hidden = true; // we hide panel part if there is no default panel + // Sidebar position + this.state.sideBar.position = (this.configurationService.getValue(Settings.SIDEBAR_POSITION) === 'right') ? Position.RIGHT : Position.LEFT; + + // Sidebar viewlet + if (!this.state.sideBar.hidden) { + const viewletRegistry = Registry.as(ViewletExtensions.Viewlets); + + // Only restore last viewlet if window was reloaded or we are in development mode + let viewletToRestore: string; + if (!this.environmentService.isBuilt || this.lifecycleService.startupKind === StartupKind.ReloadedWindow) { + viewletToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE, viewletRegistry.getDefaultViewletId()); + } else { + viewletToRestore = viewletRegistry.getDefaultViewletId(); + } + + if (viewletToRestore) { + this.state.sideBar.viewletToRestore = viewletToRestore; + } else { + this.state.sideBar.hidden = true; // we hide sidebar if there is no viewlet to restore + } } - // Sidebar Position - const sideBarPosition = this.configurationService.getValue(Settings.SIDEBAR_POSITION); - this.state.sideBar.position = (sideBarPosition === 'right') ? Position.RIGHT : Position.LEFT; + // Editor centered layout + this.state.editor.restoreCentered = this.storageService.getBoolean(State.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false); - // Panel Position + // Editors to open + this.state.editor.editorsToOpen = this.resolveEditorsToOpen(); + + // Panel visibility + this.state.panel.hidden = this.storageService.getBoolean(State.PANEL_HIDDEN, StorageScope.WORKSPACE, true); + + // Panel position this.setPanelPositionFromStorageOrConfig(); - // Menubar visibility - const menuBarVisibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); - this.setMenubarVisibility(menuBarVisibility, true); + // Panel to restore + if (!this.state.panel.hidden) { + const panelRegistry = Registry.as(PanelExtensions.Panels); + + let panelToRestore = this.storageService.get(PanelPart.activePanelSettingsKey, StorageScope.WORKSPACE, panelRegistry.getDefaultPanelId()); + if (!panelRegistry.hasPanel(panelToRestore)) { + panelToRestore = panelRegistry.getDefaultPanelId(); // fallback to default if panel is unknown + } + + if (panelToRestore) { + this.state.panel.panelToRestore = panelToRestore; + } else { + this.state.panel.hidden = true; // we hide panel if there is no panel to restore + } + } // Statusbar visibility const statusBarVisible = this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); this.state.statusBar.hidden = !statusBarVisible; - // Activity bar visibility - const activityBarVisible = this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); - this.state.activityBar.hidden = !activityBarVisible; + // Zen mode enablement + const wasZenActive = this.storageService.getBoolean(State.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false); + this.state.zenMode.restore = wasZenActive && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); + } + + private resolveEditorsToOpen(): Promise | IResourceEditor[] { + + // Files to open, diff or create + if (this.hasInitialFilesToOpen()) { + + // Files to diff is exclusive + const filesToDiff = this.toInputs(this.configuration.filesToDiff, false); + if (filesToDiff && filesToDiff.length === 2) { + return [{ + leftResource: filesToDiff[0].resource, + rightResource: filesToDiff[1].resource, + options: { pinned: true }, + forceFile: true + }]; + } + + const filesToCreate = this.toInputs(this.configuration.filesToCreate, true); + const filesToOpen = this.toInputs(this.configuration.filesToOpen, false); + + // Otherwise: Open/Create files + return [...filesToOpen, ...filesToCreate]; + } + + // Empty workbench + else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && this.openUntitledFile()) { + const isEmpty = this.editorGroupService.count === 1 && this.editorGroupService.activeGroup.count === 0; + if (!isEmpty) { + return []; // do not open any empty untitled file if we restored editors from previous session + } + + return this.backupFileService.hasBackups().then(hasBackups => { + if (hasBackups) { + return []; // do not open any empty untitled file if we have backups to restore + } + + return [{}]; + }); + } + + return []; + } + + private toInputs(paths: IPath[], isNew: boolean): Array { + if (!paths || !paths.length) { + return []; + } + + return paths.map(p => { + const resource = p.fileUri; + let input: IResourceInput | IUntitledResourceInput; + if (isNew) { + input = { filePath: resource.fsPath, options: { pinned: true } } as IUntitledResourceInput; + } else { + input = { resource, options: { pinned: true }, forceFile: true } as IResourceInput; + } + + if (!isNew && p.lineNumber) { + input.options.selection = { + startLineNumber: p.lineNumber, + startColumn: p.columnNumber + }; + } + + return input; + }); + } + + private openUntitledFile(): boolean { + const startupEditor = this.configurationService.inspect('workbench.startupEditor'); + + // Fallback to previous workbench.welcome.enabled setting in case startupEditor is not defined + if (!startupEditor.user && !startupEditor.workspace) { + const welcomeEnabledValue = this.configurationService.getValue('workbench.welcome.enabled'); + if (typeof welcomeEnabledValue === 'boolean') { + return !welcomeEnabledValue; + } + } + + return startupEditor.value === 'newUntitledFile'; } private setPanelPositionFromStorageOrConfig() { From bf8c66a079d36f5c17ceadf5a068a015df24d4be Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 10:39:43 +0100 Subject: [PATCH 099/290] fix #69753 --- src/vs/workbench/api/node/extHostFileSystem.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 2d6c3792d51..20f4f98a453 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -276,7 +276,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { this._watches.set(session, subscription); } - $unwatch(session: number): void { + $unwatch(_handle: number, session: number): void { let subscription = this._watches.get(session); if (subscription) { subscription.dispose(); From d88970796edaf01e284ba50fb2777837f4c026a9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 10:39:59 +0100 Subject: [PATCH 100/290] storage - getInteger() => getNumber() --- src/vs/base/node/storage.ts | 10 +++++----- src/vs/base/test/node/storage/storage.test.ts | 6 +++--- .../contrib/find/test/findController.test.ts | 4 ++-- .../contrib/multicursor/test/multicursor.test.ts | 2 +- .../electron-browser/lifecycleService.ts | 2 +- src/vs/platform/storage/common/storage.ts | 8 ++++---- .../platform/storage/node/storageMainService.ts | 12 ++++++------ src/vs/platform/storage/node/storageService.ts | 8 ++++---- .../storage/test/node/storageService.test.ts | 16 ++++++++-------- src/vs/workbench/browser/layout.ts | 8 ++++---- .../browser/parts/views/viewsViewlet.ts | 2 +- .../contrib/debug/browser/debugToolbar.ts | 2 +- .../contrib/quickopen/browser/commandsHandler.ts | 2 +- .../languageSurveys.contribution.ts | 8 ++++---- .../surveys/electron-browser/nps.contribution.ts | 2 +- .../contrib/update/electron-browser/update.ts | 2 +- .../node/textResourcePropertiesService.ts | 2 +- 17 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/vs/base/node/storage.ts b/src/vs/base/node/storage.ts index 5197db44743..455b278aac7 100644 --- a/src/vs/base/node/storage.ts +++ b/src/vs/base/node/storage.ts @@ -61,8 +61,8 @@ export interface IStorage extends IDisposable { getBoolean(key: string, fallbackValue: boolean): boolean; getBoolean(key: string, fallbackValue?: boolean): boolean | undefined; - getInteger(key: string, fallbackValue: number): number; - getInteger(key: string, fallbackValue?: number): number | undefined; + getNumber(key: string, fallbackValue: number): number; + getNumber(key: string, fallbackValue?: number): number | undefined; set(key: string, value: string | boolean | number): Promise; delete(key: string): Promise; @@ -195,9 +195,9 @@ export class Storage extends Disposable implements IStorage { return value === 'true'; } - getInteger(key: string, fallbackValue: number): number; - getInteger(key: string, fallbackValue?: number): number | undefined; - getInteger(key: string, fallbackValue?: number): number | undefined { + getNumber(key: string, fallbackValue: number): number; + getNumber(key: string, fallbackValue?: number): number | undefined; + getNumber(key: string, fallbackValue?: number): number | undefined { const value = this.get(key); if (isUndefinedOrNull(value)) { diff --git a/src/vs/base/test/node/storage/storage.test.ts b/src/vs/base/test/node/storage/storage.test.ts index 67c918e9e77..bbd9e00d992 100644 --- a/src/vs/base/test/node/storage/storage.test.ts +++ b/src/vs/base/test/node/storage/storage.test.ts @@ -31,7 +31,7 @@ suite('Storage Library', () => { // Empty fallbacks equal(storage.get('foo', 'bar'), 'bar'); - equal(storage.getInteger('foo', 55), 55); + equal(storage.getNumber('foo', 55), 55); equal(storage.getBoolean('foo', true), true); let changes = new Set(); @@ -45,7 +45,7 @@ suite('Storage Library', () => { const set3Promise = storage.set('barBoolean', true); equal(storage.get('bar'), 'foo'); - equal(storage.getInteger('barNumber'), 55); + equal(storage.getNumber('barNumber'), 55); equal(storage.getBoolean('barBoolean'), true); equal(changes.size, 3); @@ -71,7 +71,7 @@ suite('Storage Library', () => { const delete3Promise = storage.delete('barBoolean'); ok(!storage.get('bar')); - ok(!storage.getInteger('barNumber')); + ok(!storage.getNumber('barNumber')); ok(!storage.getBoolean('barBoolean')); equal(changes.size, 3); diff --git a/src/vs/editor/contrib/find/test/findController.test.ts b/src/vs/editor/contrib/find/test/findController.test.ts index 41b06546a59..2e8e1c92f5d 100644 --- a/src/vs/editor/contrib/find/test/findController.test.ts +++ b/src/vs/editor/contrib/find/test/findController.test.ts @@ -65,7 +65,7 @@ suite('FindController', () => { onWillSaveState: Event.None, get: (key: string) => queryState[key], getBoolean: (key: string) => !!queryState[key], - getInteger: (key: string) => undefined, + getNumber: (key: string) => undefined, store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); }, remove: (key) => undefined } as any); @@ -440,7 +440,7 @@ suite('FindController query options persistence', () => { onWillSaveState: Event.None, get: (key: string) => queryState[key], getBoolean: (key: string) => !!queryState[key], - getInteger: (key: string) => undefined, + getNumber: (key: string) => undefined, store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); }, remove: (key) => undefined } as any); diff --git a/src/vs/editor/contrib/multicursor/test/multicursor.test.ts b/src/vs/editor/contrib/multicursor/test/multicursor.test.ts index c26d0b0fd58..f2715cbe06a 100644 --- a/src/vs/editor/contrib/multicursor/test/multicursor.test.ts +++ b/src/vs/editor/contrib/multicursor/test/multicursor.test.ts @@ -65,7 +65,7 @@ suite('Multicursor selection', () => { onWillSaveState: Event.None, get: (key: string) => queryState[key], getBoolean: (key: string) => !!queryState[key], - getInteger: (key: string) => undefined!, + getNumber: (key: string) => undefined!, store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); }, remove: (key) => undefined } as IStorageService); diff --git a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts index d073ecdeb60..7e74fc62cde 100644 --- a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts +++ b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts @@ -57,7 +57,7 @@ export class LifecycleService extends Disposable implements ILifecycleService { } private resolveStartupKind(): StartupKind { - const lastShutdownReason = this.storageService.getInteger(LifecycleService.LAST_SHUTDOWN_REASON_KEY, StorageScope.WORKSPACE); + const lastShutdownReason = this.storageService.getNumber(LifecycleService.LAST_SHUTDOWN_REASON_KEY, StorageScope.WORKSPACE); this.storageService.remove(LifecycleService.LAST_SHUTDOWN_REASON_KEY, StorageScope.WORKSPACE); let startupKind: StartupKind; diff --git a/src/vs/platform/storage/common/storage.ts b/src/vs/platform/storage/common/storage.ts index 13089daf59f..1861da449bd 100644 --- a/src/vs/platform/storage/common/storage.ts +++ b/src/vs/platform/storage/common/storage.ts @@ -67,8 +67,8 @@ export interface IStorageService { * The scope argument allows to define the scope of the storage * operation to either the current workspace only or all workspaces. */ - getInteger(key: string, scope: StorageScope, fallbackValue: number): number; - getInteger(key: string, scope: StorageScope, fallbackValue?: number): number | undefined; + getNumber(key: string, scope: StorageScope, fallbackValue: number): number; + getNumber(key: string, scope: StorageScope, fallbackValue?: number): number | undefined; /** * Store a value under the given key to storage. The value will be converted to a string. @@ -142,8 +142,8 @@ export class InMemoryStorageService extends Disposable implements IStorageServic return value === 'true'; } - getInteger(key: string, scope: StorageScope, fallbackValue: number): number; - getInteger(key: string, scope: StorageScope, fallbackValue?: number): number | undefined { + getNumber(key: string, scope: StorageScope, fallbackValue: number): number; + getNumber(key: string, scope: StorageScope, fallbackValue?: number): number | undefined { const value = this.getCache(scope).get(key); if (isUndefinedOrNull(value)) { diff --git a/src/vs/platform/storage/node/storageMainService.ts b/src/vs/platform/storage/node/storageMainService.ts index fdd88608429..eacff97fbc1 100644 --- a/src/vs/platform/storage/node/storageMainService.ts +++ b/src/vs/platform/storage/node/storageMainService.ts @@ -52,8 +52,8 @@ export interface IStorageMainService { * the provided defaultValue if the element is null or undefined. The element * will be converted to a number using parseInt with a base of 10. */ - getInteger(key: string, fallbackValue: number): number; - getInteger(key: string, fallbackValue?: number): number | undefined; + getNumber(key: string, fallbackValue: number): number; + getNumber(key: string, fallbackValue?: number): number | undefined; /** * Store a string value under the given key to storage. The value will @@ -362,10 +362,10 @@ export class StorageMainService extends Disposable implements IStorageMainServic return this.storage.getBoolean(key, fallbackValue); } - getInteger(key: string, fallbackValue: number): number; - getInteger(key: string, fallbackValue?: number): number | undefined; - getInteger(key: string, fallbackValue?: number): number | undefined { - return this.storage.getInteger(key, fallbackValue); + getNumber(key: string, fallbackValue: number): number; + getNumber(key: string, fallbackValue?: number): number | undefined; + getNumber(key: string, fallbackValue?: number): number | undefined { + return this.storage.getNumber(key, fallbackValue); } store(key: string, value: any): Promise { diff --git a/src/vs/platform/storage/node/storageService.ts b/src/vs/platform/storage/node/storageService.ts index 7e05b32576d..06870260f32 100644 --- a/src/vs/platform/storage/node/storageService.ts +++ b/src/vs/platform/storage/node/storageService.ts @@ -170,10 +170,10 @@ export class StorageService extends Disposable implements IStorageService { return this.getStorage(scope).getBoolean(key, fallbackValue); } - getInteger(key: string, scope: StorageScope, fallbackValue: number): number; - getInteger(key: string, scope: StorageScope): number | undefined; - getInteger(key: string, scope: StorageScope, fallbackValue?: number): number | undefined { - return this.getStorage(scope).getInteger(key, fallbackValue); + getNumber(key: string, scope: StorageScope, fallbackValue: number): number; + getNumber(key: string, scope: StorageScope): number | undefined; + getNumber(key: string, scope: StorageScope, fallbackValue?: number): number | undefined { + return this.getStorage(scope).getNumber(key, fallbackValue); } store(key: string, value: string | boolean | number, scope: StorageScope): void { diff --git a/src/vs/platform/storage/test/node/storageService.test.ts b/src/vs/platform/storage/test/node/storageService.test.ts index 634967a79a7..91478086ce4 100644 --- a/src/vs/platform/storage/test/node/storageService.test.ts +++ b/src/vs/platform/storage/test/node/storageService.test.ts @@ -48,8 +48,8 @@ suite('StorageService', () => { strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, 'foobar'), 'foobar'); strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, ''), ''); - strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, 5), 5); - strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, 0), 0); + strictEqual(storage.getNumber('Monaco.IDE.Core.Storage.Test.getNumber', scope, 5), 5); + strictEqual(storage.getNumber('Monaco.IDE.Core.Storage.Test.getNumber', scope, 0), 0); strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, true), true); strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, false), false); @@ -59,11 +59,11 @@ suite('StorageService', () => { storage.store('Monaco.IDE.Core.Storage.Test.get', '', scope); strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.get', scope, (undefined)!), ''); - storage.store('Monaco.IDE.Core.Storage.Test.getInteger', 5, scope); - strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, (undefined)!), 5); + storage.store('Monaco.IDE.Core.Storage.Test.getNumber', 5, scope); + strictEqual(storage.getNumber('Monaco.IDE.Core.Storage.Test.getNumber', scope, (undefined)!), 5); - storage.store('Monaco.IDE.Core.Storage.Test.getInteger', 0, scope); - strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getInteger', scope, (undefined)!), 0); + storage.store('Monaco.IDE.Core.Storage.Test.getNumber', 0, scope); + strictEqual(storage.getNumber('Monaco.IDE.Core.Storage.Test.getNumber', scope, (undefined)!), 0); storage.store('Monaco.IDE.Core.Storage.Test.getBoolean', true, scope); strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, (undefined)!), true); @@ -72,7 +72,7 @@ suite('StorageService', () => { strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBoolean', scope, (undefined)!), false); strictEqual(storage.get('Monaco.IDE.Core.Storage.Test.getDefault', scope, 'getDefault'), 'getDefault'); - strictEqual(storage.getInteger('Monaco.IDE.Core.Storage.Test.getIntegerDefault', scope, 5), 5); + strictEqual(storage.getNumber('Monaco.IDE.Core.Storage.Test.getNumberDefault', scope, 5), 5); strictEqual(storage.getBoolean('Monaco.IDE.Core.Storage.Test.getBooleanDefault', scope, true), true); } @@ -111,7 +111,7 @@ suite('StorageService', () => { await storage.migrate({ id: String(Date.now() + 100) }); equal(storage.get('bar', StorageScope.WORKSPACE), 'foo'); - equal(storage.getInteger('barNumber', StorageScope.WORKSPACE), 55); + equal(storage.getNumber('barNumber', StorageScope.WORKSPACE), 55); equal(storage.getBoolean('barBoolean', StorageScope.GLOBAL), true); await storage.close(); diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 819bb315340..e9711a46e71 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -103,13 +103,13 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr } private restorePreviousState(): void { - this._sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, this.storageService.getInteger(WorkbenchLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_SIDEBAR_PART_WIDTH)); + this._sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, this.storageService.getNumber(WorkbenchLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_SIDEBAR_PART_WIDTH)); - this._panelWidth = Math.max(this.partLayoutInfo.panel.minWidth, this.storageService.getInteger(WorkbenchLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); - this._panelHeight = Math.max(this.partLayoutInfo.panel.minHeight, this.storageService.getInteger(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); + this._panelWidth = Math.max(this.partLayoutInfo.panel.minWidth, this.storageService.getNumber(WorkbenchLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); + this._panelHeight = Math.max(this.partLayoutInfo.panel.minHeight, this.storageService.getNumber(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); this.panelMaximized = false; - this.panelSizeBeforeMaximized = this.storageService.getInteger(WorkbenchLayout.panelSizeBeforeMaximizedKey, StorageScope.GLOBAL, 0); + this.panelSizeBeforeMaximized = this.storageService.getNumber(WorkbenchLayout.panelSizeBeforeMaximizedKey, StorageScope.GLOBAL, 0); } private registerListeners(): void { diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 4a63b4a810b..55b19d00586 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -67,7 +67,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView this.viewletState = this.getMemento(StorageScope.WORKSPACE); this.visibleViewsStorageId = `${id}.numberOfVisibleViews`; - this.visibleViewsCountFromCache = this.storageService.getInteger(this.visibleViewsStorageId, StorageScope.WORKSPACE, 1); + this.visibleViewsCountFromCache = this.storageService.getNumber(this.visibleViewsStorageId, StorageScope.WORKSPACE, 1); this._register(toDisposable(() => this.viewDisposables = dispose(this.viewDisposables))); } diff --git a/src/vs/workbench/contrib/debug/browser/debugToolbar.ts b/src/vs/workbench/contrib/debug/browser/debugToolbar.ts index cd9233d3714..f28f1268117 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolbar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolbar.ts @@ -228,7 +228,7 @@ export class DebugToolbar extends Themable implements IWorkbenchContribution { this.$el.style.left = `${x}px`; if (y === undefined) { - y = this.storageService.getInteger(DEBUG_TOOLBAR_Y_KEY, StorageScope.GLOBAL, 0); + y = this.storageService.getNumber(DEBUG_TOOLBAR_Y_KEY, StorageScope.GLOBAL, 0); } const titleAreaHeight = 35; if ((y < titleAreaHeight / 2) || (y > titleAreaHeight + titleAreaHeight / 2)) { diff --git a/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts b/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts index 13019490a5b..0ebc16e91c7 100644 --- a/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts +++ b/src/vs/workbench/contrib/quickopen/browser/commandsHandler.ts @@ -111,7 +111,7 @@ class CommandsHistory extends Disposable { entries.forEach(entry => commandHistory.set(entry.key, entry.value)); } - commandCounter = this.storageService.getInteger(CommandsHistory.PREF_KEY_COUNTER, StorageScope.GLOBAL, commandCounter); + commandCounter = this.storageService.getNumber(CommandsHistory.PREF_KEY_COUNTER, StorageScope.GLOBAL, commandCounter); } push(commandId: string): void { diff --git a/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts b/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts index 318047f643b..447a3565881 100644 --- a/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts +++ b/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts @@ -40,13 +40,13 @@ class LanguageSurvey { const date = new Date().toDateString(); - if (storageService.getInteger(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) < data.editCount) { + if (storageService.getNumber(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) < data.editCount) { textFileService.models.onModelsSaved(e => { e.forEach(event => { if (event.kind === StateChange.SAVED) { const model = modelService.getModel(event.resource); if (model && model.getModeId() === data.languageId && date !== storageService.get(EDITED_LANGUAGE_DATE_KEY, StorageScope.GLOBAL)) { - const editedCount = storageService.getInteger(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) + 1; + const editedCount = storageService.getNumber(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) + 1; storageService.store(EDITED_LANGUAGE_COUNT_KEY, editedCount, StorageScope.GLOBAL); storageService.store(EDITED_LANGUAGE_DATE_KEY, date, StorageScope.GLOBAL); } @@ -60,7 +60,7 @@ class LanguageSurvey { return; } - const sessionCount = storageService.getInteger(SESSION_COUNT_KEY, StorageScope.GLOBAL, 0) + 1; + const sessionCount = storageService.getNumber(SESSION_COUNT_KEY, StorageScope.GLOBAL, 0) + 1; storageService.store(LAST_SESSION_DATE_KEY, date, StorageScope.GLOBAL); storageService.store(SESSION_COUNT_KEY, sessionCount, StorageScope.GLOBAL); @@ -68,7 +68,7 @@ class LanguageSurvey { return; } - if (storageService.getInteger(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) < data.editCount) { + if (storageService.getNumber(EDITED_LANGUAGE_COUNT_KEY, StorageScope.GLOBAL, 0) < data.editCount) { return; } diff --git a/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts b/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts index 7253741210e..c11fd38db20 100644 --- a/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts +++ b/src/vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts @@ -39,7 +39,7 @@ class NPSContribution implements IWorkbenchContribution { return; } - const sessionCount = (storageService.getInteger(SESSION_COUNT_KEY, StorageScope.GLOBAL, 0) || 0) + 1; + const sessionCount = (storageService.getNumber(SESSION_COUNT_KEY, StorageScope.GLOBAL, 0) || 0) + 1; storageService.store(LAST_SESSION_DATE_KEY, date, StorageScope.GLOBAL); storageService.store(SESSION_COUNT_KEY, sessionCount, StorageScope.GLOBAL); diff --git a/src/vs/workbench/contrib/update/electron-browser/update.ts b/src/vs/workbench/contrib/update/electron-browser/update.ts index 02eae23b8f0..8faae3e5068 100644 --- a/src/vs/workbench/contrib/update/electron-browser/update.ts +++ b/src/vs/workbench/contrib/update/electron-browser/update.ts @@ -512,7 +512,7 @@ export class UpdateContribution implements IGlobalActivity { this.storageService.store('update/updateNotificationTime', currentMillis, StorageScope.GLOBAL); } - const updateNotificationMillis = this.storageService.getInteger('update/updateNotificationTime', StorageScope.GLOBAL, currentMillis); + const updateNotificationMillis = this.storageService.getNumber('update/updateNotificationTime', StorageScope.GLOBAL, currentMillis); const diffDays = (currentMillis - updateNotificationMillis) / (1000 * 60 * 60 * 24); return diffDays > 5; diff --git a/src/vs/workbench/services/textfile/node/textResourcePropertiesService.ts b/src/vs/workbench/services/textfile/node/textResourcePropertiesService.ts index 86503bc02d5..2d54b0c9e43 100644 --- a/src/vs/workbench/services/textfile/node/textResourcePropertiesService.ts +++ b/src/vs/workbench/services/textfile/node/textResourcePropertiesService.ts @@ -45,7 +45,7 @@ export class TextResourcePropertiesService implements ITextResourcePropertiesSer if (remoteAuthority) { if (resource.scheme !== Schemas.file) { const osCacheKey = `resource.authority.os.${remoteAuthority}`; - os = this.remoteEnvironment ? this.remoteEnvironment.os : /* Get it from cache */ this.storageService.getInteger(osCacheKey, StorageScope.WORKSPACE, OS); + os = this.remoteEnvironment ? this.remoteEnvironment.os : /* Get it from cache */ this.storageService.getNumber(osCacheKey, StorageScope.WORKSPACE, OS); this.storageService.store(osCacheKey, os, StorageScope.WORKSPACE); } } From 5f54123a0c82044bcb90e7591db4fa292892885b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 10:48:42 +0100 Subject: [PATCH 101/290] make IPreferenceService use sync descriptor, #69226 --- src/vs/workbench/electron-browser/workbench.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 77d601e49b3..49cae59eb3f 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -575,7 +575,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IQuickInputService, this.quickInput); // PreferencesService - serviceCollection.set(IPreferencesService, this.instantiationService.createInstance(PreferencesService)); + serviceCollection.set(IPreferencesService, new SyncDescriptor(PreferencesService)); // Contributed services const contributedServices = getServices(); @@ -1852,4 +1852,4 @@ export class Workbench extends Disposable implements IPartService { } //#endregion -} \ No newline at end of file +} From 2469f39a58d457f6f206a4f5c0e7be28446f9af2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 10:49:25 +0100 Subject: [PATCH 102/290] :lipstick: --- .../workbench/electron-browser/workbench.ts | 228 +++++++++--------- 1 file changed, 112 insertions(+), 116 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 49cae59eb3f..849aec0a71d 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -353,7 +353,7 @@ export class Workbench extends Disposable implements IPartService { this.lifecycleService.when(LifecyclePhase.Restored).then(() => clearTimeout(timeoutHandle)); // Restore Parts - return this.restoreParts(); + return this.restoreParts().then(() => this.whenStarted(), error => this.whenStarted(error)); } private createWorkbench(): void { @@ -663,121 +663,6 @@ export class Workbench extends Disposable implements IPartService { //#endregion - private restoreParts(): Promise { - const restorePromises: Promise[] = []; - - // Restore Editorpart - mark('willRestoreEditors'); - restorePromises.push(this.editorPart.whenRestored.then(() => { - - function openEditors(editors: IResourceEditor[], editorService: IEditorService) { - if (editors.length) { - return editorService.openEditors(editors); - } - - return Promise.resolve(undefined); - } - - if (Array.isArray(this.state.editor.editorsToOpen)) { - return openEditors(this.state.editor.editorsToOpen, this.editorService); - } - - return this.state.editor.editorsToOpen.then(editors => openEditors(editors, this.editorService)); - }).then(() => mark('didRestoreEditors'))); - - // Restore Sidebar - if (this.state.sideBar.viewletToRestore) { - mark('willRestoreViewlet'); - restorePromises.push(this.sidebarPart.openViewlet(this.state.sideBar.viewletToRestore) - .then(viewlet => viewlet || this.sidebarPart.openViewlet(this.sidebarPart.getDefaultViewletId())) - .then(() => mark('didRestoreViewlet'))); - } - - // Restore Panel - if (this.state.panel.panelToRestore) { - mark('willRestorePanel'); - this.panelPart.openPanel(this.state.panel.panelToRestore, false); - mark('didRestorePanel'); - } - - // Restore Zen Mode - if (this.state.zenMode.restore) { - this.toggleZenMode(true, true); - } - - // Restore Editor Center Mode - if (this.state.editor.restoreCentered) { - this.centerEditorLayout(true); - } - - return Promise.all(restorePromises).then(() => this.whenRestored(), error => this.whenRestored(error)); - } - - private whenRestored(error?: Error): void { - this.restored = true; - - // Set lifecycle phase to `Restored` - this.lifecycleService.phase = LifecyclePhase.Restored; - - // Set lifecycle phase to `Eventually` after a short delay and when - // idle (min 2.5sec, max 5sec) - setTimeout(() => { - this._register(runWhenIdle(() => { - this.lifecycleService.phase = LifecyclePhase.Eventually; - }, 2500)); - }, 2500); - - if (error) { - onUnexpectedError(error); - } - - this.logStartupTelemetry(); - } - - private logStartupTelemetry(): void { - const { filesToOpen, filesToCreate, filesToDiff } = this.configuration; - - /* __GDPR__ - "workspaceLoad" : { - "userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" }, - "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - this.telemetryService.publicLog('workspaceLoad', { - userAgent: navigator.userAgent, - windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }, - emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY, - 'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0, - 'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0, - 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, - customKeybindingsCount: this.keybindingService.customKeybindingsCount(), - theme: this.themeService.getColorTheme().id, - language, - pinnedViewlets: this.activitybarPart.getPinnedViewletIds(), - restoredViewlet: this.state.sideBar.viewletToRestore, - restoredEditors: this.editorService.visibleEditors.length, - startupKind: this.lifecycleService.startupKind - }); - - // Telemetry: startup metrics - mark('didStartWorkbench'); - } - private renderWorkbench(): void { // Apply sidebar state as CSS class @@ -912,6 +797,117 @@ export class Workbench extends Disposable implements IPartService { registerNotificationCommands(this.notificationsCenter, this.notificationsToasts); } + private restoreParts(): Promise { + const restorePromises: Promise[] = []; + + // Restore editors + mark('willRestoreEditors'); + restorePromises.push(this.editorPart.whenRestored.then(() => { + + function openEditors(editors: IResourceEditor[], editorService: IEditorService) { + if (editors.length) { + return editorService.openEditors(editors); + } + + return Promise.resolve(undefined); + } + + if (Array.isArray(this.state.editor.editorsToOpen)) { + return openEditors(this.state.editor.editorsToOpen, this.editorService); + } + + return this.state.editor.editorsToOpen.then(editors => openEditors(editors, this.editorService)); + }).then(() => mark('didRestoreEditors'))); + + // Restore Sidebar + if (this.state.sideBar.viewletToRestore) { + mark('willRestoreViewlet'); + restorePromises.push(this.sidebarPart.openViewlet(this.state.sideBar.viewletToRestore) + .then(viewlet => viewlet || this.sidebarPart.openViewlet(this.sidebarPart.getDefaultViewletId())) + .then(() => mark('didRestoreViewlet'))); + } + + // Restore Panel + if (this.state.panel.panelToRestore) { + mark('willRestorePanel'); + this.panelPart.openPanel(this.state.panel.panelToRestore, false); + mark('didRestorePanel'); + } + + // Restore Zen Mode + if (this.state.zenMode.restore) { + this.toggleZenMode(true, true); + } + + // Restore Editor Center Mode + if (this.state.editor.restoreCentered) { + this.centerEditorLayout(true); + } + + return Promise.all(restorePromises); + } + + private whenStarted(error?: Error): void { + this.restored = true; + + // Set lifecycle phase to `Restored` + this.lifecycleService.phase = LifecyclePhase.Restored; + + // Set lifecycle phase to `Eventually` after a short delay and when + // idle (min 2.5sec, max 5sec) + setTimeout(() => { + this._register(runWhenIdle(() => { + this.lifecycleService.phase = LifecyclePhase.Eventually; + }, 2500)); + }, 2500); + + if (error) { + onUnexpectedError(error); + } + + const { filesToOpen, filesToCreate, filesToDiff } = this.configuration; + + /* __GDPR__ + "workspaceLoad" : { + "userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" }, + "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + } + */ + this.telemetryService.publicLog('workspaceLoad', { + userAgent: navigator.userAgent, + windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }, + emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY, + 'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0, + 'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0, + 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, + customKeybindingsCount: this.keybindingService.customKeybindingsCount(), + theme: this.themeService.getColorTheme().id, + language, + pinnedViewlets: this.activitybarPart.getPinnedViewletIds(), + restoredViewlet: this.state.sideBar.viewletToRestore, + restoredEditors: this.editorService.visibleEditors.length, + startupKind: this.lifecycleService.startupKind + }); + + // Telemetry: startup metrics + mark('didStartWorkbench'); + } + private saveState(e: IWillSaveStateEvent): void { // Zen Mode From baf256a71b26cf7811aa0e27a797e47ab1c05124 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 11:00:49 +0100 Subject: [PATCH 103/290] debt - move editor layout event out of workbench --- src/vs/workbench/browser/parts/panel/panelActions.ts | 9 ++++++--- .../splash/electron-browser/partsSplash.contribution.ts | 4 +++- .../contrib/watermark/electron-browser/watermark.ts | 6 ++++-- src/vs/workbench/electron-browser/workbench.ts | 4 +--- .../services/editor/common/editorGroupsService.ts | 6 ++++++ src/vs/workbench/services/part/common/partService.ts | 5 ----- src/vs/workbench/test/workbenchTestServices.ts | 6 +----- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index e5f639f4449..0ec0fe83d72 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -15,6 +15,7 @@ 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/compositeBarActions'; import { IActivity } from 'vs/workbench/common/activity'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; export class ClosePanelAction extends Action { @@ -100,6 +101,7 @@ export class TogglePanelPositionAction extends Action { id: string, label: string, @IPartService private readonly partService: IPartService, + @IEditorGroupsService editorGroupsService: IEditorGroupsService ) { super(id, label, partService.getPanelPosition() === Position.RIGHT ? 'move-panel-to-bottom' : 'move-panel-to-right'); @@ -111,7 +113,7 @@ export class TogglePanelPositionAction extends Action { this.label = positionRight ? TogglePanelPositionAction.MOVE_TO_BOTTOM_LABEL : TogglePanelPositionAction.MOVE_TO_RIGHT_LABEL; }; - this.toDispose.push(partService.onEditorLayout(() => setClassAndLabel())); + this.toDispose.push(editorGroupsService.onDidLayout(() => setClassAndLabel())); setClassAndLabel(); } @@ -143,13 +145,14 @@ export class ToggleMaximizedPanelAction extends Action { constructor( id: string, label: string, - @IPartService private readonly partService: IPartService + @IPartService private readonly partService: IPartService, + @IEditorGroupsService editorGroupsService: IEditorGroupsService ) { super(id, label, partService.isPanelMaximized() ? 'minimize-panel-action' : 'maximize-panel-action'); this.toDispose = []; - this.toDispose.push(partService.onEditorLayout(() => { + this.toDispose.push(editorGroupsService.onDidLayout(() => { const maximized = this.partService.isPanelMaximized(); this.class = maximized ? 'minimize-panel-action' : 'maximize-panel-action'; this.label = maximized ? ToggleMaximizedPanelAction.RESTORE_LABEL : ToggleMaximizedPanelAction.MAXIMIZE_LABEL; diff --git a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts index b03134e1686..b8f8fbbf0a5 100644 --- a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts @@ -21,6 +21,7 @@ import { IPartService, Parts, Position } from 'vs/workbench/services/part/common import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; class PartsSplash { @@ -38,11 +39,12 @@ class PartsSplash { @IEnvironmentService private readonly _envService: IEnvironmentService, @IBroadcastService private readonly _broadcastService: IBroadcastService, @ILifecycleService lifecycleService: ILifecycleService, + @IEditorGroupsService editorGroupsService: IEditorGroupsService ) { lifecycleService.when(LifecyclePhase.Restored).then(_ => this._removePartsSplash()); Event.debounce(Event.any( onDidChangeFullscreen, - _partService.onEditorLayout + editorGroupsService.onDidLayout ), () => { }, 800)(this._savePartsSplash, this, this._disposables); } diff --git a/src/vs/workbench/contrib/watermark/electron-browser/watermark.ts b/src/vs/workbench/contrib/watermark/electron-browser/watermark.ts index 150f230c22c..6e7a0f9f557 100644 --- a/src/vs/workbench/contrib/watermark/electron-browser/watermark.ts +++ b/src/vs/workbench/contrib/watermark/electron-browser/watermark.ts @@ -26,6 +26,7 @@ import { QUICKOPEN_ACTION_ID } from 'vs/workbench/browser/parts/quickopen/quicko import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import * as dom from 'vs/base/browser/dom'; import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; +import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; const $ = dom.$; @@ -112,7 +113,8 @@ export class WatermarkContribution implements IWorkbenchContribution { @IPartService private readonly partService: IPartService, @IKeybindingService private readonly keybindingService: IKeybindingService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @IConfigurationService private readonly configurationService: IConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService, + @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService ) { this.workbenchState = contextService.getWorkbenchState(); @@ -171,7 +173,7 @@ export class WatermarkContribution implements IWorkbenchContribution { update(); dom.prepend(container.firstElementChild as HTMLElement, this.watermark); this.toDispose.push(this.keybindingService.onDidUpdateKeybindings(update)); - this.toDispose.push(this.partService.onEditorLayout(({ height }: IDimension) => { + this.toDispose.push(this.editorGroupsService.onDidLayout(({ height }: IDimension) => { container.classList[height <= 478 ? 'add' : 'remove']('max-height-478px'); })); } diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 849aec0a71d..7aaab4a467a 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -33,7 +33,7 @@ import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickO import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { QuickInputService } from 'vs/workbench/browser/parts/quickinput/quickInput'; import { getServices } from 'vs/platform/instantiation/common/extensions'; -import { Position, Parts, IPartService, IDimension, PositionToString, ILayoutOptions } from 'vs/workbench/services/part/common/partService'; +import { Position, Parts, IPartService, PositionToString, ILayoutOptions } from 'vs/workbench/services/part/common/partService'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { ContextMenuService as HTMLContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; @@ -941,8 +941,6 @@ export class Workbench extends Disposable implements IPartService { private readonly _onZenMode: Emitter = this._register(new Emitter()); get onZenModeChange(): Event { return this._onZenMode.event; } - get onEditorLayout(): Event { return this.editorPart.onDidLayout; } - private workbenchGrid: Grid | WorkbenchLayout; private titleBarPartView: View; diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index 882c487b795..948c1ec185c 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -9,6 +9,7 @@ import { IEditorInput, IEditor, GroupIdentifier, IEditorInputWithOptions, CloseD import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IActiveEditor } from 'vs/workbench/services/editor/common/editorService'; +import { IDimension } from 'vs/editor/common/editorCommon'; export const IEditorGroupsService = createDecorator('editorGroupsService'); @@ -164,6 +165,11 @@ export interface IEditorGroupsService { */ readonly onDidMoveGroup: Event; + /** + * An event for when the group container is layed out. + */ + readonly onDidLayout: Event; + /** * An active group is the default location for new editors to open. */ diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index 07c381500f6..269ce816af3 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -54,11 +54,6 @@ export interface IPartService { */ onZenModeChange: Event; - /** - * Emits when the editor part's layout changes. - */ - onEditorLayout: Event; - /** * Asks the part service if all parts have been fully restored. For editor part * this means that the contents of editors have loaded. diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index a3ff5279c3c..6f31697329d 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -448,7 +448,6 @@ export class TestPartService implements IPartService { private _onTitleBarVisibilityChange = new Emitter(); private _onMenubarVisibilityChange = new Emitter(); - private _onEditorLayout = new Emitter(); public get onTitleBarVisibilityChange(): Event { return this._onTitleBarVisibilityChange.event; @@ -458,10 +457,6 @@ export class TestPartService implements IPartService { return this._onMenubarVisibilityChange.event; } - public get onEditorLayout(): Event { - return this._onEditorLayout.event; - } - public isRestored(): boolean { return true; } @@ -556,6 +551,7 @@ export class TestEditorGroupsService implements EditorGroupsServiceImpl { onDidAddGroup: Event = Event.None; onDidRemoveGroup: Event = Event.None; onDidMoveGroup: Event = Event.None; + onDidLayout: Event = Event.None; orientation: any; whenRestored: Promise = Promise.resolve(undefined); From 5893ace5c199d7fa3d8ae94b6aae1e4d3ae0da98 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 4 Mar 2019 11:14:58 +0100 Subject: [PATCH 104/290] fixes #69755 --- .../files/browser/views/explorerView.ts | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index eafa721b5bd..98fcd9cdb45 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -61,7 +61,6 @@ export class ExplorerView extends ViewletPanel { // Refresh is needed on the initial explorer open private shouldRefresh = true; - private setTreeInputPromise = Promise.resolve(); private dragHandler: DelayedDragHandler; private decorationProvider: ExplorerDecorationsProvider; private autoReveal = false; @@ -166,7 +165,7 @@ export class ExplorerView extends ViewletPanel { this.refresh(); })); - this.disposables.push(this.explorerService.onDidChangeRoots(() => this.setTreeInputPromise = this.setTreeInput())); + this.disposables.push(this.explorerService.onDidChangeRoots(() => this.setTreeInput())); this.disposables.push(this.explorerService.onDidChangeItem(e => this.refresh(e))); this.disposables.push(this.explorerService.onDidChangeEditable(async e => { const isEditing = !!this.explorerService.getEditableData(e); @@ -206,8 +205,7 @@ export class ExplorerView extends ViewletPanel { // If a refresh was requested and we are now visible, run it if (this.shouldRefresh) { this.shouldRefresh = false; - this.setTreeInputPromise = this.setTreeInput(); - await this.setTreeInputPromise; + await this.setTreeInput(); } // Find resource to focus from active editor input if set this.selectActiveFile(false, true); @@ -231,22 +229,21 @@ export class ExplorerView extends ViewletPanel { } focus(): void { - this.setTreeInputPromise.then(() => { - this.tree.domFocus(); - const focused = this.tree.getFocus(); - if (focused.length === 1) { - if (this.autoReveal) { - this.tree.reveal(focused[0], 0.5); - } + this.tree.domFocus(); - const activeFile = this.getActiveFile(); - if (!activeFile && !focused[0].isDirectory) { - // Open the focused element in the editor if there is currently no file opened #67708 - this.editorService.openEditor({ resource: focused[0].resource, options: { preserveFocus: true, revealIfVisible: true } }) - .then(undefined, onUnexpectedError); - } + const focused = this.tree.getFocus(); + if (focused.length === 1) { + if (this.autoReveal) { + this.tree.reveal(focused[0], 0.5); } - }); + + const activeFile = this.getActiveFile(); + if (!activeFile && !focused[0].isDirectory) { + // Open the focused element in the editor if there is currently no file opened #67708 + this.editorService.openEditor({ resource: focused[0].resource, options: { preserveFocus: true, revealIfVisible: true } }) + .then(undefined, onUnexpectedError); + } + } } private selectActiveFile(deselect?: boolean, reveal = this.autoReveal): void { From a1481e3e2e51f833ce5001500f4b4559c5777cb7 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 4 Mar 2019 11:15:47 +0100 Subject: [PATCH 105/290] Switch cpp and c grammar to jeff-hykin/cpp-textmate-grammar --- extensions/cpp/build/update-grammars.js | 4 +- extensions/cpp/cgmanifest.json | 10 +- extensions/cpp/syntaxes/c.tmLanguage.json | 306 +- extensions/cpp/syntaxes/cpp.tmLanguage.json | 2510 ++++++++++++++++- .../test/colorize-results/test-23630_cpp.json | 22 +- .../test/colorize-results/test-23850_cpp.json | 20 +- .../cpp/test/colorize-results/test_c.json | 418 +-- .../cpp/test/colorize-results/test_cc.json | 884 +++--- .../cpp/test/colorize-results/test_cpp.json | 774 ++--- .../test/colorize-results/test_m.json | 396 +-- 10 files changed, 4055 insertions(+), 1289 deletions(-) diff --git a/extensions/cpp/build/update-grammars.js b/extensions/cpp/build/update-grammars.js index f02f51ca2cc..406b326156c 100644 --- a/extensions/cpp/build/update-grammars.js +++ b/extensions/cpp/build/update-grammars.js @@ -6,8 +6,8 @@ var updateGrammar = require('../../../build/npm/update-grammar'); -updateGrammar.update('atom/language-c', 'grammars/c.cson', './syntaxes/c.tmLanguage.json'); -updateGrammar.update('atom/language-c', 'grammars/c%2B%2B.cson', './syntaxes/cpp.tmLanguage.json'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/c.tmLanguage.json', './syntaxes/c.tmLanguage.json'); +updateGrammar.update('jeff-hykin/cpp-textmate-grammar', '/syntaxes/cpp.tmLanguage.json', './syntaxes/cpp.tmLanguage.json'); // `source.c.platform` which is still included by other grammars updateGrammar.update('textmate/c.tmbundle', 'Syntaxes/Platform.tmLanguage', './syntaxes/platform.tmLanguage.json'); diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index e6666933f61..08cd245eac1 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -4,14 +4,14 @@ "component": { "type": "git", "git": { - "name": "atom/language-c", - "repositoryUrl": "https://github.com/atom/language-c", - "commitHash": "9c0c5f202741a5647025db8d5df5fefba47b036c" + "name": "jeff-hykin/cpp-textmate-grammar", + "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", + "commitHash": "d57808aa3db2242f1f2be1aec19649a852aaa52e" } }, "license": "MIT", - "version": "0.58.1", - "description": "The files syntaxes/c.json and syntaxes/c++.json were derived from the Atom package https://atom.io/packages/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." + "version": "1.4.5", + "description": "The files syntaxes/c.json and syntaxes/c++.json were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { "component": { diff --git a/extensions/cpp/syntaxes/c.tmLanguage.json b/extensions/cpp/syntaxes/c.tmLanguage.json index bcd5470a64c..efb692081eb 100644 --- a/extensions/cpp/syntaxes/c.tmLanguage.json +++ b/extensions/cpp/syntaxes/c.tmLanguage.json @@ -1,10 +1,10 @@ { "information_for_contributors": [ - "This file has been converted from https://github.com/atom/language-c/blob/master/grammars/c.cson", + "This file has been converted from https://github.com/jeff-hykin/cpp-textmate-grammar/blob/master//syntaxes/c.tmLanguage.json", "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-c/commit/9c0c5f202741a5647025db8d5df5fefba47b036c", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/9de911d74546b9ae74c57e404515935a0405e696", "name": "C", "scopeName": "source.c", "patterns": [ @@ -50,6 +50,9 @@ { "include": "#operators" }, + { + "include": "#operator_overload" + }, { "include": "#numbers" }, @@ -57,7 +60,7 @@ "include": "#strings" }, { - "begin": "(?x)\n^\\s* ((\\#)\\s*define) \\s+ # define\n((?[a-zA-Z_$][\\w$]*)) # macro name\n(?:\n (\\()\n (\n \\s* \\g \\s* # first argument\n ((,) \\s* \\g \\s*)* # additional arguments\n (?:\\.\\.\\.)? # varargs ellipsis?\n )\n (\\))\n)?", + "begin": "(?x)\n^\\s* ((\\#)\\s*define) \\s+\t# define\n((?[a-zA-Z_$][\\w$]*))\t # macro name\n(?:\n (\\()\n\t(\n\t \\s* \\g \\s*\t\t # first argument\n\t ((,) \\s* \\g \\s*)* # additional arguments\n\t (?:\\.\\.\\.)?\t\t\t# varargs ellipsis?\n\t)\n (\\))\n)?", "beginCaptures": { "1": { "name": "keyword.control.directive.define.c" @@ -90,8 +93,8 @@ ] }, { - "begin": "^\\s*((#)\\s*(error|warning))\\b", - "captures": { + "begin": "^\\s*((#)\\s*(error|warning))\\b\\s*", + "beginCaptures": { "1": { "name": "keyword.control.directive.diagnostic.$3.c" }, @@ -99,17 +102,61 @@ "name": "punctuation.definition.directive.c" } }, - "end": "(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", - "end": "(?<=\\))(?!\\w)", + "begin": "(?!(?:not|compl|sizeof|new|delete|not_eq|bitand|xor|bitor|and|or|throw|and_eq|xor_eq|or_eq|alignof|alignas|typeid|noexcept|static_cast|dynamic_cast|const_cast|reinterpret_cast|while|for|do|if|else|goto|switch|try|catch|return|break|case|continue|default|auto|void|char|short|int|signed|unsigned|long|float|double|bool|wchar_t|u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t|const|static|volatile|register|restrict|constexpr|extern|inline|mutable|friend|NULL|true|false|TRUE|FALSE|nullptr|class|struct|union|enum|explicit|virtual|mutable|constexpr|consteval|private|protected|public|if|elif|else|endif|ifdef|ifndef|define|undef|include|line|error|warning|pragma|_Pragma|defined|__has_include|__has_cpp_attribute|this|template|namespace|using|operator|typedef|decltype|typename|asm|__asm__|atomic_cancel|atomic_commit|atomic_noexcept|concept|co_await|co_return|co_yield|export|import|module|reflexpr|requires|synchronized|thread_local|audit|axiom|transaction_safe|transaction_safe_dynamic)\\s*\\()(?=[a-zA-Z_][a-zA-Z0-9_]*\\s*\\()", + "end": "(?<=\\))", "name": "meta.function.c", "patterns": [ { @@ -282,15 +329,31 @@ "include": "#line_continuation_character" }, { - "match": "(\\[)|(\\])", - "captures": { + "name": "meta.bracket.square.access.c", + "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))?(\\[)(?!\\])", + "beginCaptures": { "1": { - "name": "punctuation.definition.begin.bracket.square.c" + "name": "variable.object.c" }, "2": { + "name": "punctuation.definition.begin.bracket.square.c" + } + }, + "end": "\\]", + "endCaptures": { + "0": { "name": "punctuation.definition.end.bracket.square.c" } - } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + { + "name": "storage.modifier.array.bracket.square.c", + "match": "\\[\\s*\\]" }, { "match": ";", @@ -302,8 +365,56 @@ } ], "repository": { - "access": { + "probably_a_parameter": { + "match": "(?:([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?==)|(?<=(?:[a-zA-Z0-9_]\\s|[&*>\\]\\)]))\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?=(?:\\[\\]\\s*)?(?:,|\\))))", "captures": { + "1": { + "name": "variable.parameter.probably.defaulted.c" + }, + "2": { + "name": "variable.parameter.probably.c" + } + } + }, + "operator_overload": { + "begin": "((?:[a-zA-Z_][a-zA-Z0-9_]*\\s*(?:<(?:[\\s<>,\\w])*>\\s*)?::)*)(operator)((?:\\s*(?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,)|\\s+(?:(?:new|new\\[\\]|delete|delete\\[\\])|[a-zA-Z_][a-zA-Z0-9_]*)))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.scope.c" + }, + "2": { + "name": "entity.name.operator.overload.c" + }, + "3": { + "name": "entity.name.operator.overloadee.c" + }, + "4": { + "name": "punctuation.section.parameters.begin.bracket.round.c" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parameters.end.bracket.round.c" + } + }, + "name": "meta.function.definition.parameters.operator-overload.c", + "patterns": [ + { + "include": "#probably_a_parameter" + }, + { + "include": "#function-innards" + } + ] + }, + "access-method": { + "name": "meta.function-call.member.c", + "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))\\s*(?:(\\.)|(->))((?:(?:[a-zA-Z_][a-zA-Z_0-9]*)\\s*(?:(?:\\.)|(?:->)))*)\\s*([a-zA-Z_][a-zA-Z_0-9]*)(\\()", + "beginCaptures": { + "1": { + "name": "variable.object.c" + }, "2": { "name": "punctuation.separator.dot-access.c" }, @@ -311,10 +422,81 @@ "name": "punctuation.separator.pointer-access.c" }, "4": { - "name": "variable.other.member.c" + "patterns": [ + { + "match": "\\.", + "name": "punctuation.separator.dot-access.c" + }, + { + "match": "->", + "name": "punctuation.separator.pointer-access.c" + }, + { + "match": "[a-zA-Z_][a-zA-Z_0-9]*", + "name": "variable.object.c" + }, + { + "name": "everything.else", + "match": ".+" + } + ] + }, + "5": { + "name": "entity.name.function.member.c" + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.function.member.c" } }, - "match": "((\\.)|(->))\\s*(([a-zA-Z_][a-zA-Z_0-9]*)\\b(?!\\s*\\())?" + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.arguments.end.bracket.round.function.member.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] + }, + "access-member": { + "name": "variable.object.access.c", + "match": "(?:([a-zA-Z_][a-zA-Z0-9_]*)|(?<=\\]|\\)))\\s*(?:((?:\\.|\\.\\*))|((?:->|->\\*)))\\s*((?:[a-zA-Z_][a-zA-Z0-9_]*\\s*(?:\\.|->)\\s*)*)\\b(?!(?:auto|void|char|short|int|signed|unsigned|long|float|double|bool|wchar_t|u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t))([a-zA-Z_][a-zA-Z0-9_]*)\\b(?!\\()", + "captures": { + "1": { + "name": "variable.object.c" + }, + "2": { + "name": "punctuation.separator.dot-access.c" + }, + "3": { + "name": "punctuation.separator.pointer-access.c" + }, + "4": { + "patterns": [ + { + "match": "\\.", + "name": "punctuation.separator.dot-access.c" + }, + { + "match": "->", + "name": "punctuation.separator.pointer-access.c" + }, + { + "match": "[a-zA-Z_][a-zA-Z0-9_]*", + "name": "variable.object.c" + }, + { + "match": ".+", + "name": "everything.else" + } + ] + }, + "5": { + "name": "variable.other.member.c" + } + } }, "block": { "patterns": [ @@ -352,25 +534,36 @@ "include": "#preprocessor-rule-conditional-block" }, { - "include": "#access" + "include": "#access-method" }, { - "include": "#libc" + "include": "#access-member" }, { "include": "#c_function_call" }, { - "captures": { + "name": "meta.initialization.c", + "begin": "(?x)\n(?:\n (?:\n\t(?=\\s)(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", + "beginCaptures": { "1": { "name": "variable.other.c" }, "2": { - "name": "punctuation.definition.parameters.c" + "name": "punctuation.section.parens.begin.bracket.round.initialization.c" } }, - "match": "(?x)\n(?:\n (?:\n (?=\\s)(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", - "name": "meta.initialization.c" + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.initialization.c" + } + }, + "patterns": [ + { + "include": "#function-call-innards" + } + ] }, { "begin": "{", @@ -400,7 +593,7 @@ ] }, "c_function_call": { - "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate)\\s*\\()\n(?=\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(?=\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", "end": "(?<=\\))(?!\\w)", "name": "meta.function-call.c", "patterns": [ @@ -488,17 +681,6 @@ } ] }, - "libc": { - "captures": { - "1": { - "name": "punctuation.whitespace.support.function.leading.c" - }, - "2": { - "name": "support.function.C99.c" - } - }, - "match": "(?x) (\\s*) \\b\n(_Exit|(?:nearbyint|nextafter|nexttoward|netoward|nan)[fl]?|a(?:cos|sin)h?[fl]?|abort|abs|asctime|assert\n|atan(?:[h2]?[fl]?)?|atexit|ato[ifl]|atoll|bsearch|btowc|cabs[fl]?|cacos|cacos[fl]|cacosh[fl]?\n|calloc|carg[fl]?|casinh?[fl]?|catanh?[fl]?|cbrt[fl]?|ccosh?[fl]?|ceil[fl]?|cexp[fl]?|cimag[fl]?\n|clearerr|clock|clog[fl]?|conj[fl]?|copysign[fl]?|cosh?[fl]?|cpow[fl]?|cproj[fl]?|creal[fl]?\n|csinh?[fl]?|csqrt[fl]?|ctanh?[fl]?|ctime|difftime|div|erfc?[fl]?|exit|fabs[fl]?\n|exp(?:2[fl]?|[fl]|m1[fl]?)?|fclose|fdim[fl]?|fe[gs]et(?:env|exceptflag|round)|feclearexcept\n|feholdexcept|feof|feraiseexcept|ferror|fetestexcept|feupdateenv|fflush|fgetpos|fgetw?[sc]\n|floor[fl]?|fmax?[fl]?|fmin[fl]?|fmod[fl]?|fopen|fpclassify|fprintf|fputw?[sc]|fread|free|freopen\n|frexp[fl]?|fscanf|fseek|fsetpos|ftell|fwide|fwprintf|fwrite|fwscanf|genv|get[sc]|getchar|gmtime\n|gwc|gwchar|hypot[fl]?|ilogb[fl]?|imaxabs|imaxdiv|isalnum|isalpha|isblank|iscntrl|isdigit|isfinite\n|isgraph|isgreater|isgreaterequal|isinf|isless(?:equal|greater)?|isw?lower|isnan|isnormal|isw?print\n|isw?punct|isw?space|isunordered|isw?upper|iswalnum|iswalpha|iswblank|iswcntrl|iswctype|iswdigit|iswgraph\n|isw?xdigit|labs|ldexp[fl]?|ldiv|lgamma[fl]?|llabs|lldiv|llrint[fl]?|llround[fl]?|localeconv|localtime\n|log[2b]?[fl]?|log1[p0][fl]?|longjmp|lrint[fl]?|lround[fl]?|malloc|mbr?len|mbr?towc|mbsinit|mbsrtowcs\n|mbstowcs|memchr|memcmp|memcpy|memmove|memset|mktime|modf[fl]?|perror|pow[fl]?|printf|puts|putw?c(?:har)?\n|qsort|raise|rand|remainder[fl]?|realloc|remove|remquo[fl]?|rename|rewind|rint[fl]?|round[fl]?|scalbl?n[fl]?\n|scanf|setbuf|setjmp|setlocale|setvbuf|signal|signbit|sinh?[fl]?|snprintf|sprintf|sqrt[fl]?|srand|sscanf\n|strcat|strchr|strcmp|strcoll|strcpy|strcspn|strerror|strftime|strlen|strncat|strncmp|strncpy|strpbrk\n|strrchr|strspn|strstr|strto[kdf]|strtoimax|strtol[dl]?|strtoull?|strtoumax|strxfrm|swprintf|swscanf\n|system|tan|tan[fl]|tanh[fl]?|tgamma[fl]?|time|tmpfile|tmpnam|tolower|toupper|trunc[fl]?|ungetw?c|va_arg\n|va_copy|va_end|va_start|vfw?printf|vfw?scanf|vprintf|vscanf|vsnprintf|vsprintf|vsscanf|vswprintf|vswscanf\n|vwprintf|vwscanf|wcrtomb|wcscat|wcschr|wcscmp|wcscoll|wcscpy|wcscspn|wcsftime|wcslen|wcsncat|wcsncmp|wcsncpy\n|wcspbrk|wcsrchr|wcsrtombs|wcsspn|wcsstr|wcsto[dkf]|wcstoimax|wcstol[dl]?|wcstombs|wcstoull?|wcstoumax|wcsxfrm\n|wctom?b|wmem(?:set|chr|cpy|cmp|move)|wprintf|wscanf)\\b" - }, "line_continuation_character": { "patterns": [ { @@ -520,6 +702,7 @@ ] }, "parens": { + "name": "punctuation.section.parens", "begin": "\\(", "beginCaptures": { "0": { @@ -539,6 +722,7 @@ ] }, "parens-block": { + "name": "punctuation.section.parens.block", "begin": "\\(", "beginCaptures": { "0": { @@ -554,6 +738,10 @@ "patterns": [ { "include": "#block_innards" + }, + { + "match": "(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas|asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void)\\s*\\()\n(?=\n (?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name\n |\n (?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", "end": "(?<=\\))(?!\\w)|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "entity.name.function.c" @@ -1846,7 +2045,8 @@ "include": "#vararg_ellipses" }, { - "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "name": "meta.function.definition.parameters", + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "entity.name.function.c" @@ -1862,6 +2062,9 @@ } }, "patterns": [ + { + "include": "#probably_a_parameter" + }, { "include": "#function-innards" } @@ -1900,13 +2103,16 @@ "include": "#storage_types" }, { - "include": "#access" + "include": "#access-method" + }, + { + "include": "#access-member" }, { "include": "#operators" }, { - "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|enumerate|return|typeid|alignof|alignas|sizeof|[cr]?iterate|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++ # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", "beginCaptures": { "1": { "name": "entity.name.function.c" diff --git a/extensions/cpp/syntaxes/cpp.tmLanguage.json b/extensions/cpp/syntaxes/cpp.tmLanguage.json index f29bc255ba8..c3c6d813d97 100644 --- a/extensions/cpp/syntaxes/cpp.tmLanguage.json +++ b/extensions/cpp/syntaxes/cpp.tmLanguage.json @@ -1,46 +1,83 @@ { "information_for_contributors": [ - "This file has been converted from https://github.com/atom/language-c/blob/master/grammars/c%2B%2B.cson", + "This file has been converted from https://github.com/jeff-hykin/cpp-textmate-grammar/blob/master//syntaxes/cpp.tmLanguage.json", "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-c/commit/3a269f88b12e512fb9495dc006a1dabf325d3d7f", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/d57808aa3db2242f1f2be1aec19649a852aaa52e", "name": "C++", "scopeName": "source.cpp", "patterns": [ { "include": "#special_block" }, + { + "match": "(?-mix:##[a-zA-Z_]\\w*(?!\\w))", + "name": "variable.other.macro.argument.cpp" + }, { "include": "#strings" }, { - "match": "\\b(friend|explicit|virtual|override|final|noexcept)\\b", - "name": "storage.modifier.cpp" + "match": "(?[a-zA-Z_$][\\w$]*))\t # macro name\n(?:\n (\\()\n\t(\n\t \\s* \\g \\s*\t\t # first argument\n\t ((,) \\s* \\g \\s*)* # additional arguments\n\t (?:\\.\\.\\.)?\t\t\t# varargs ellipsis?\n\t)\n (\\))\n)?", + "beginCaptures": { + "1": { + "name": "keyword.control.directive.define.cpp" + }, + "2": { + "name": "punctuation.definition.directive.cpp" + }, + "3": { + "name": "entity.name.function.preprocessor.cpp" + }, + "5": { + "name": "punctuation.definition.parameters.begin.cpp" + }, + "6": { + "name": "variable.parameter.preprocessor.cpp" + }, + "8": { + "name": "punctuation.separator.parameters.cpp" + }, + "9": { + "name": "punctuation.definition.parameters.end.cpp" + } + }, + "end": "(?=(?://|/\\*))|(?", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.cpp" + } + }, + "name": "string.quoted.other.lt-gt.include.cpp" + } + ] + }, + { + "include": "#pragma-mark" + }, + { + "begin": "^\\s*((#)\\s*line)\\b", + "beginCaptures": { + "1": { + "name": "keyword.control.directive.line.cpp" + }, + "2": { + "name": "punctuation.definition.directive.cpp" + } + }, + "end": "(?=(?://|/\\*))|(?,\\w])*>\\s*", + "captures": { + "0": { + "patterns": [ + { + "include": "#storage_types-c" + }, + { + "include": "#constants" + }, + { + "include": "#scope_resolution" + }, + { + "match": "(?,\\w])*>\\s*)?::)*)\\s*([a-zA-Z_]\\w*)\\s*(?:(<(?:[\\s<>,\\w])*>\\s*))?(::)", + "captures": { + "1": { + "name": "entity.scope.cpp", + "patterns": [ + { + "include": "#scope_resolution" + } + ] + }, + "2": { + "name": "entity.scope.name.cpp" + }, + "3": { + "patterns": [ + { + "include": "#template-call-innards" + } + ] + }, + "4": { + "name": "punctuation.separator.namespace.access.cpp" + } + } + }, + "template_definition": { + "begin": "(?-mix:(?", + "endCaptures": { + "0": { + "name": "punctuation.section.angle-brackets.end.template.definition.cpp" + } + }, + "name": "template.definition.cpp", + "patterns": [ + { + "include": "#scope_resolution" + }, + { + "include": "#template_definition_argument" + }, + { + "include": "#template-call-innards" + } + ] + }, + "template_definition_argument": { + "match": "\\s*(?:(?:(?:([a-zA-Z_]\\w*)|((?:[a-zA-Z_]\\w*\\s+)+)([a-zA-Z_]\\w*))|([a-zA-Z_]\\w*)\\s*(\\.\\.\\.)\\s*([a-zA-Z_]\\w*))|((?:[a-zA-Z_][a-zA-Z_0-9]*\\s+)*)([a-zA-Z_][a-zA-Z_0-9]*)\\s*(=)\\s*(\\w+))\\s*(?:(,)|(?=>))", + "captures": { + "1": { + "name": "storage.type.template.argument.$1.cpp" + }, + "2": { + "name": "storage.type.template.argument.$2.cpp" + }, + "3": { + "name": "entity.name.type.template.cpp" + }, + "4": { + "name": "storage.type.template.cpp" + }, + "5": { + "name": "keyword.operator.ellipsis.template.definition.cpp" + }, + "6": { + "name": "entity.name.type.template.cpp" + }, + "7": { + "name": "storage.type.template.cpp" + }, + "8": { + "name": "entity.name.type.template.cpp" + }, + "9": { + "name": "keyword.operator.assignment.cpp" + }, + "10": { + "name": "keyword.operator.assignment.cpp" + }, + "11": { + "name": "storage.type.template.argument.$10.cpp" + }, + "12": { + "name": "constant.language.cpp" + }, + "13": { + "name": "punctuation.separator.comma.template.argument.cpp" + } + } + }, "angle_brackets": { "begin": "<", "end": ">", @@ -134,13 +638,13 @@ "begin": "\\{", "beginCaptures": { "0": { - "name": "punctuation.section.block.begin.bracket.curly.c" + "name": "punctuation.section.block.begin.bracket.curly.cpp" } }, "end": "\\}", "endCaptures": { "0": { - "name": "punctuation.section.block.end.bracket.curly.c" + "name": "punctuation.section.block.end.bracket.curly.cpp" } }, "name": "meta.block.cpp", @@ -148,14 +652,14 @@ { "captures": { "1": { - "name": "support.function.any-method.c" + "name": "support.function.any-method.cpp" }, "2": { - "name": "punctuation.definition.parameters.c" + "name": "punctuation.definition.parameters.cpp" } }, - "match": "(?x)\n(\n (?!while|for|do|if|else|switch|catch|enumerate|return|r?iterate)\n (?:\\b[A-Za-z_][A-Za-z0-9_]*+\\b|::)*+ # actual name\n)\n\\s*(\\() # opening bracket", - "name": "meta.function-call.c" + "match": "(?x)\n(\n (?!while|for|do|if|else|switch|catch|return)\n (?:\\b[A-Za-z_][A-Za-z0-9_]*+\\b|::)*+ # actual name\n)\n\\s*(\\() # opening bracket", + "name": "meta.function-call.cpp" }, { "include": "$base" @@ -165,25 +669,28 @@ "constructor": { "patterns": [ { - "begin": "(?x)\n(?:^\\s*) # beginning of line\n((?!while|for|do|if|else|switch|catch|enumerate|r?iterate)[A-Za-z_][A-Za-z0-9_:]*) # actual name\n\\s*(\\() # opening bracket", + "begin": "(?x)\n(?:^\\s*) # beginning of line\n((?!while|for|do|if|else|switch|catch)[A-Za-z_][A-Za-z0-9_:]*) # actual name\n\\s*(\\() # opening bracket", "beginCaptures": { "1": { - "name": "entity.name.function.cpp" + "name": "entity.name.function.constructor.cpp" }, "2": { - "name": "punctuation.definition.parameters.begin.c" + "name": "punctuation.definition.parameters.begin.constructor.cpp" } }, "end": "\\)", "endCaptures": { "0": { - "name": "punctuation.definition.parameters.end.c" + "name": "punctuation.definition.parameters.end.constructor.cpp" } }, "name": "meta.function.constructor.cpp", "patterns": [ { - "include": "$base" + "include": "#probably_a_parameter" + }, + { + "include": "#function-innards-c" } ] }, @@ -191,7 +698,7 @@ "begin": "(?x)\n(:)\n(\n (?=\n \\s*[A-Za-z_][A-Za-z0-9_:]* # actual name\n \\s* (\\() # opening bracket\n )\n)", "beginCaptures": { "1": { - "name": "punctuation.definition.parameters.c" + "name": "punctuation.definition.initializer-list.parameters.cpp" } }, "end": "(?=\\{)", @@ -207,34 +714,51 @@ "special_block": { "patterns": [ { - "begin": "\\b(using)\\b\\s*(namespace)\\b\\s*((?:[_A-Za-z][_A-Za-z0-9]*\\b(::)?)*)", + "comment": "https://en.cppreference.com/w/cpp/language/namespace", + "begin": "\\b(using)\\s+(namespace)\\s+(?:((?:[a-zA-Z_]\\w*\\s*(?:<(?:[\\s<>,\\w])*>\\s*)?::)*)\\s*)?((?,\\w])*>\\s*)?::)*[a-zA-Z_]\\w*)|(?={))", "beginCaptures": { "1": { - "name": "storage.type.cpp" + "name": "keyword.other.namespace.definition.cpp" }, "2": { - "name": "entity.name.type.cpp" - } - }, - "captures": { - "1": { - "name": "keyword.control.namespace.$2" + "patterns": [ + { + "match": "(?-mix:(?|\\[|\\]|=))", @@ -271,25 +795,28 @@ ] }, { - "begin": "\\b(class|struct)\\b\\s*([_A-Za-z][_A-Za-z0-9]*\\b)?+(\\s*:\\s*(public|protected|private)\\s*([_A-Za-z][_A-Za-z0-9]*\\b)((\\s*,\\s*(public|protected|private)\\s*[_A-Za-z][_A-Za-z0-9]*\\b)*))?", + "begin": "\\b(?:(class)|(struct))\\b\\s*([_A-Za-z][_A-Za-z0-9]*\\b)?+(\\s*:\\s*(public|protected|private)\\s*([_A-Za-z][_A-Za-z0-9]*\\b)((\\s*,\\s*(public|protected|private)\\s*[_A-Za-z][_A-Za-z0-9]*\\b)*))?", "beginCaptures": { "1": { - "name": "storage.type.cpp" + "name": "storage.type.class.cpp" }, "2": { + "name": "storage.type.struct.cpp" + }, + "3": { "name": "entity.name.type.cpp" }, - "4": { - "name": "storage.type.modifier.cpp" - }, "5": { - "name": "entity.name.type.inherited.cpp" + "name": "storage.type.modifier.access.cpp" }, "6": { + "name": "entity.name.type.inherited.cpp" + }, + "7": { "patterns": [ { "match": "(public|protected|private)", - "name": "storage.type.modifier.cpp" + "name": "storage.type.modifier.access.cpp" }, { "match": "[_A-Za-z][_A-Za-z0-9]*", @@ -298,7 +825,12 @@ ] } }, - "end": "(?<=\\})|(?=(;|\\(|\\)|>|\\[|\\]|=))", + "end": "(?<=\\})|(;)|(?=(\\(|\\)|>|\\[|\\]|=))", + "endCaptures": { + "1": { + "name": "punctuation.terminator.statement.cpp" + } + }, "name": "meta.class-struct-block.cpp", "patterns": [ { @@ -351,13 +883,13 @@ "begin": "\\{", "beginCaptures": { "0": { - "name": "punctuation.section.block.begin.bracket.curly.c" + "name": "punctuation.section.block.begin.bracket.curly.cpp" } }, "end": "\\}|(?=\\s*#\\s*endif\\b)", "endCaptures": { "0": { - "name": "punctuation.section.block.end.bracket.curly.c" + "name": "punctuation.section.block.end.bracket.curly.cpp" } }, "patterns": [ @@ -413,7 +945,7 @@ "name": "constant.character.escape.cpp" }, { - "include": "source.c#string_placeholder" + "include": "#string_placeholder-c" } ] }, @@ -442,6 +974,1858 @@ "name": "string.quoted.double.raw.cpp" } ] + }, + "probably_a_parameter": { + "match": "(?:([a-zA-Z_]\\w*)\\s*(?==)|(?<=(?:\\w\\s|[&*>\\]\\)]))\\s*([a-zA-Z_]\\w*)\\s*(?=(?:\\[\\]\\s*)?(?:,|\\))))", + "captures": { + "1": { + "name": "variable.parameter.probably.defaulted.cpp" + }, + "2": { + "name": "variable.parameter.probably.cpp" + } + } + }, + "operator_overload": { + "begin": "((?:[a-zA-Z_]\\w*\\s*(?:<(?:[\\s<>,\\w])*>\\s*)?::)*)\\s*(operator)((?:\\s*(?:\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|\\-\\-|\\+|\\-|!|~|\\*|&|\\->\\*|\\*|\\/|%|\\+|\\-|<<|>>|<=>|<|<=|>|>=|==|!=|&|\\^|\\||&&|\\|\\||=|\\+=|\\-=|\\*=|\\/=|%=|<<=|>>=|&=|\\^=|\\|=|,)|\\s+(?:(?:new|new\\[\\]|delete|delete\\[\\])|(?:[a-zA-Z_]\\w*\\s*(?:<(?:[\\s<>,\\w])*>\\s*)?::)*[a-zA-Z_]\\w*\\s*(?:&)?)))\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.scope.cpp" + }, + "2": { + "name": "entity.name.operator.overload.cpp" + }, + "3": { + "name": "entity.name.operator.overloadee.cpp" + }, + "4": { + "name": "punctuation.section.parameters.begin.bracket.round.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parameters.end.bracket.round.cpp" + } + }, + "name": "meta.function.definition.parameters.operator-overload.cpp", + "patterns": [ + { + "include": "#probably_a_parameter" + }, + { + "include": "#function-innards-c" + } + ] + }, + "access-method": { + "name": "meta.function-call.member.cpp", + "begin": "([a-zA-Z_][a-zA-Z_0-9]*|(?<=[\\]\\)]))\\s*(?:(\\.)|(->))((?:(?:[a-zA-Z_][a-zA-Z_0-9]*)\\s*(?:(?:\\.)|(?:->)))*)\\s*([a-zA-Z_][a-zA-Z_0-9]*)(\\()", + "beginCaptures": { + "1": { + "name": "variable.object.cpp" + }, + "2": { + "name": "punctuation.separator.dot-access.cpp" + }, + "3": { + "name": "punctuation.separator.pointer-access.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\.", + "name": "punctuation.separator.dot-access.cpp" + }, + { + "match": "->", + "name": "punctuation.separator.pointer-access.cpp" + }, + { + "match": "[a-zA-Z_][a-zA-Z_0-9]*", + "name": "variable.object.cpp" + }, + { + "name": "everything.else.cpp", + "match": ".+" + } + ] + }, + "5": { + "name": "entity.name.function.member.cpp" + }, + "6": { + "name": "punctuation.section.arguments.begin.bracket.round.function.member.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.arguments.end.bracket.round.function.member.cpp" + } + }, + "patterns": [ + { + "include": "#function-call-innards-c" + } + ] + }, + "access-member": { + "name": "variable.object.access.cpp", + "match": "(?:([a-zA-Z_]\\w*)|(?<=\\]|\\)))\\s*(?:((?:\\.|\\.\\*))|((?:->|->\\*)))\\s*((?:[a-zA-Z_]\\w*\\s*(?:\\.|->)\\s*)*)\\b(?!(?:auto|void|char|short|int|signed|unsigned|long|float|double|bool|wchar_t|u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t|pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t|int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t|uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t|uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t|uintmax_t|uintmax_t))([a-zA-Z_]\\w*)\\b(?!\\()", + "captures": { + "1": { + "name": "variable.object.cpp" + }, + "2": { + "name": "punctuation.separator.dot-access.cpp" + }, + "3": { + "name": "punctuation.separator.pointer-access.cpp" + }, + "4": { + "patterns": [ + { + "match": "\\.", + "name": "punctuation.separator.dot-access.cpp" + }, + { + "match": "->", + "name": "punctuation.separator.pointer-access.cpp" + }, + { + "match": "[a-zA-Z_]\\w*", + "name": "variable.object.cpp" + }, + { + "match": ".+", + "name": "everything.else.cpp" + } + ] + }, + "5": { + "name": "variable.other.member.cpp" + } + } + }, + "block-c": { + "patterns": [ + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.block.begin.bracket.curly.cpp" + } + }, + "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", + "endCaptures": { + "0": { + "name": "punctuation.section.block.end.bracket.curly.cpp" + } + }, + "name": "meta.block.cpp", + "patterns": [ + { + "include": "#block_innards-c" + } + ] + } + ] + }, + "block_innards-c": { + "patterns": [ + { + "include": "#preprocessor-rule-enabled-block" + }, + { + "include": "#preprocessor-rule-disabled-block" + }, + { + "include": "#preprocessor-rule-conditional-block" + }, + { + "include": "#access-method" + }, + { + "include": "#access-member" + }, + { + "include": "#c_function_call" + }, + { + "name": "meta.initialization.cpp", + "begin": "(?x)\n(?:\n (?:\n\t(?=\\s)(?=+!]+ | \\(\\) | \\[\\]))\n)\n\\s*(\\() # opening bracket", + "beginCaptures": { + "1": { + "name": "variable.other.cpp" + }, + "2": { + "name": "punctuation.section.parens.begin.bracket.round.initialization.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.initialization.cpp" + } + }, + "patterns": [ + { + "include": "#function-call-innards-c" + } + ] + }, + { + "begin": "{", + "beginCaptures": { + "0": { + "name": "punctuation.section.block.begin.bracket.curly.cpp" + } + }, + "end": "}|(?=\\s*#\\s*(?:elif|else|endif)\\b)", + "endCaptures": { + "0": { + "name": "punctuation.section.block.end.bracket.curly.cpp" + } + }, + "patterns": [ + { + "include": "#block_innards-c" + } + ] + }, + { + "include": "#parens-block-c" + }, + { + "include": "$base" + } + ] + }, + "c_function_call": { + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|return|typeid|alignof|alignas|sizeof|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(?=\n(?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*(?:<(?:[\\s<>,\\w])*>\\s*)?\\( # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "end": "(?<=\\))(?!\\w)", + "name": "meta.function-call.cpp", + "patterns": [ + { + "include": "#function-call-innards-c" + } + ] + }, + "comments-c": { + "patterns": [ + { + "captures": { + "1": { + "name": "meta.toc-list.banner.block.cpp" + } + }, + "match": "^/\\* =(\\s*.*?)\\s*= \\*/$\\n?", + "name": "comment.block.cpp" + }, + { + "begin": "/\\*", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.begin.cpp" + } + }, + "end": "\\*/", + "endCaptures": { + "0": { + "name": "punctuation.definition.comment.end.cpp" + } + }, + "name": "comment.block.cpp" + }, + { + "match": "\\*/.*\\n", + "name": "invalid.illegal.stray-comment-end.cpp" + }, + { + "captures": { + "1": { + "name": "meta.toc-list.banner.line.cpp" + } + }, + "match": "^// =(\\s*.*?)\\s*=\\s*$\\n?", + "name": "comment.line.banner.cpp" + }, + { + "begin": "(^[ \\t]+)?(?=//)", + "beginCaptures": { + "1": { + "name": "punctuation.whitespace.comment.leading.cpp" + } + }, + "end": "(?!\\G)", + "patterns": [ + { + "begin": "//", + "beginCaptures": { + "0": { + "name": "punctuation.definition.comment.cpp" + } + }, + "end": "(?=\\n)", + "name": "comment.line.double-slash.cpp", + "patterns": [ + { + "include": "#line_continuation_character" + } + ] + } + ] + } + ] + }, + "disabled": { + "begin": "^\\s*#\\s*if(n?def)?\\b.*$", + "end": "^\\s*#\\s*endif\\b", + "patterns": [ + { + "include": "#disabled" + }, + { + "include": "#pragma-mark" + } + ] + }, + "line_continuation_character": { + "patterns": [ + { + "match": "(\\\\)\\n", + "captures": { + "1": { + "name": "constant.character.escape.line-continuation.cpp" + } + } + } + ] + }, + "numbers-c": { + "patterns": [ + { + "match": "\\b((?:0(?:x|X)[0-9a-fA-F](?:[0-9a-fA-F']*[0-9a-fA-F'])?|0(?:b|B)[01](?:[01']*[01'])?)(?:\\.[\\d+a-fA-F']+p[\\d']+)?|(([0-9](?:[0-9']*[0-9'])*(?:\\.[0-9](?:[0-9']*[0-9'])*)?)|(\\.[0-9](?:[0-9']*[0-9'])*))((e|E)(\\+|-)?[0-9](?:[0-9']*[0-9'])*)?)(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\w*", + "name": "constant.numeric.cpp", + "captures": { + "0": { + "patterns": [ + { + "match": "(?-mix:(?>=|\\|=", + "name": "keyword.operator.assignment.compound.bitwise.cpp" + }, + { + "match": "<<|>>", + "name": "keyword.operator.bitwise.shift.cpp" + }, + { + "match": "!=|<=|>=|==|<|>", + "name": "keyword.operator.comparison.cpp" + }, + { + "match": "&&|!|\\|\\|", + "name": "keyword.operator.logical.cpp" + }, + { + "match": "&|\\||\\^|~", + "name": "keyword.operator.cpp" + }, + { + "match": "=", + "name": "keyword.operator.assignment.cpp" + }, + { + "match": "%|\\*|/|-|\\+", + "name": "keyword.operator.cpp" + }, + { + "begin": "\\?", + "beginCaptures": { + "0": { + "name": "keyword.operator.ternary.cpp" + } + }, + "end": ":", + "applyEndPatternLast": true, + "endCaptures": { + "0": { + "name": "keyword.operator.ternary.cpp" + } + }, + "patterns": [ + { + "include": "#access-method" + }, + { + "include": "#access-member" + }, + { + "include": "#c_function_call" + }, + { + "include": "$base" + } + ] + } + ] + }, + "strings-c": { + "patterns": [ + { + "begin": "\"", + "beginCaptures": { + "0": { + "name": "punctuation.definition.string.begin.cpp" + } + }, + "end": "\"", + "endCaptures": { + "0": { + "name": "punctuation.definition.string.end.cpp" + } + }, + "name": "string.quoted.double.cpp", + "patterns": [ + { + "include": "#string_escaped_char-c" + }, + { + "include": "#string_placeholder-c" + }, + { + "include": "#line_continuation_character" + } + ] + }, + { + "begin": "(?-mix:(?=+!]+|\\(\\)|\\[\\]))\\s*\\(\n)", + "end": "(?<=\\))(?!\\w)|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.name.function.cpp" + }, + "2": { + "name": "punctuation.section.arguments.begin.bracket.round.cpp" + } + }, + "end": "(\\))|(?=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "beginCaptures": { + "1": { + "name": "entity.name.function.cpp" + }, + "2": { + "name": "punctuation.section.parameters.begin.bracket.round.cpp" + } + }, + "end": "\\)|:", + "endCaptures": { + "0": { + "name": "punctuation.section.parameters.end.bracket.round.cpp" + } + }, + "patterns": [ + { + "include": "#probably_a_parameter" + }, + { + "include": "#function-innards-c" + } + ] + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.parens.begin.bracket.round.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.cpp" + } + }, + "patterns": [ + { + "include": "#function-innards-c" + } + ] + }, + { + "include": "$base" + } + ] + }, + "function-call-innards-c": { + "patterns": [ + { + "include": "#comments-c" + }, + { + "include": "#storage_types-c" + }, + { + "include": "#access-method" + }, + { + "include": "#access-member" + }, + { + "include": "#operators" + }, + { + "begin": "(?x)\n(?!(?:while|for|do|if|else|switch|catch|return|typeid|alignof|alignas|sizeof|and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\s*\\()\n(\n(?:new)\\s*((?:<(?:[\\s<>,\\w])*>\\s*)?) # actual name\n|\n(?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\n)\n\\s*(\\()", + "beginCaptures": { + "1": { + "name": "keyword.operator.memory.new.cpp" + }, + "2": { + "patterns": [ + { + "include": "#template-call-innards" + } + ] + }, + "3": { + "name": "punctuation.section.arguments.begin.bracket.round.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.arguments.end.bracket.round.cpp" + } + }, + "patterns": [ + { + "include": "#function-call-innards-c" + } + ] + }, + { + "begin": "(?,\\w])*>\\s*)?::)*)\\s*([a-zA-Z_]\\w*)\\s*(?:(<(?:[\\s<>,\\w])*>\\s*))?(\\()", + "beginCaptures": { + "1": { + "patterns": [ + { + "include": "#scope_resolution" + } + ] + }, + "2": { + "name": "entity.name.function.call.cpp" + }, + "3": { + "patterns": [ + { + "include": "#template-call-innards" + } + ] + }, + "4": { + "name": "punctuation.section.arguments.begin.bracket.round.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.arguments.end.bracket.round.cpp" + } + }, + "patterns": [ + { + "include": "#function-call-innards-c" + } + ] + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.section.parens.begin.bracket.round.cpp" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.section.parens.end.bracket.round.cpp" + } + }, + "patterns": [ + { + "include": "#function-call-innards-c" + } + ] + }, + { + "include": "#block_innards-c" + } + ] } } } \ No newline at end of file diff --git a/extensions/cpp/test/colorize-results/test-23630_cpp.json b/extensions/cpp/test/colorize-results/test-23630_cpp.json index f22786a105f..a58961ae945 100644 --- a/extensions/cpp/test/colorize-results/test-23630_cpp.json +++ b/extensions/cpp/test/colorize-results/test-23630_cpp.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "ifndef", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.c", + "t": "source.cpp meta.preprocessor.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -34,7 +34,7 @@ }, { "c": "_UCRT", - "t": "source.cpp meta.preprocessor.c entity.name.function.preprocessor.c", + "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -45,7 +45,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.macro.c", + "t": "source.cpp meta.preprocessor.macro.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -56,7 +56,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.macro.c keyword.control.directive.define.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -67,7 +67,7 @@ }, { "c": "define", - "t": "source.cpp meta.preprocessor.macro.c keyword.control.directive.define.c", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -78,7 +78,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.macro.c", + "t": "source.cpp meta.preprocessor.macro.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -89,7 +89,7 @@ }, { "c": "_UCRT", - "t": "source.cpp meta.preprocessor.macro.c entity.name.function.preprocessor.c", + "t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -100,7 +100,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -111,7 +111,7 @@ }, { "c": "endif", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", diff --git a/extensions/cpp/test/colorize-results/test-23850_cpp.json b/extensions/cpp/test/colorize-results/test-23850_cpp.json index bbb5237498f..924bbc78243 100644 --- a/extensions/cpp/test/colorize-results/test-23850_cpp.json +++ b/extensions/cpp/test/colorize-results/test-23850_cpp.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "ifndef", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.c", + "t": "source.cpp meta.preprocessor.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -34,7 +34,7 @@ }, { "c": "_UCRT", - "t": "source.cpp meta.preprocessor.c entity.name.function.preprocessor.c", + "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -45,7 +45,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.macro.c keyword.control.directive.define.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -56,7 +56,7 @@ }, { "c": "define", - "t": "source.cpp meta.preprocessor.macro.c keyword.control.directive.define.c", + "t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -67,7 +67,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.macro.c", + "t": "source.cpp meta.preprocessor.macro.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -78,7 +78,7 @@ }, { "c": "_UCRT", - "t": "source.cpp meta.preprocessor.macro.c entity.name.function.preprocessor.c", + "t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -89,7 +89,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -100,7 +100,7 @@ }, { "c": "endif", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", diff --git a/extensions/cpp/test/colorize-results/test_c.json b/extensions/cpp/test/colorize-results/test_c.json index 0725010d8c2..79a3c093e65 100644 --- a/extensions/cpp/test/colorize-results/test_c.json +++ b/extensions/cpp/test/colorize-results/test_c.json @@ -243,7 +243,7 @@ }, { "c": "int", - "t": "source.c storage.type.c", + "t": "source.c storage.type.built-in.primitive.c", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -265,7 +265,7 @@ }, { "c": "main", - "t": "source.c meta.function.c entity.name.function.c", + "t": "source.c meta.function.c meta.function.definition.parameters entity.name.function.c", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -276,7 +276,7 @@ }, { "c": "(", - "t": "source.c meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.c meta.function.c meta.function.definition.parameters punctuation.section.parameters.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -287,7 +287,7 @@ }, { "c": ")", - "t": "source.c meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.c meta.function.c meta.function.definition.parameters punctuation.section.parameters.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -320,7 +320,7 @@ }, { "c": "float", - "t": "source.c meta.block.c storage.type.c", + "t": "source.c meta.block.c storage.type.built-in.primitive.c", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -507,7 +507,7 @@ }, { "c": " ", - "t": "source.c meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.c meta.block.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -518,18 +518,18 @@ }, { "c": "printf", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -540,7 +540,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.begin.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.begin.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -551,7 +551,7 @@ }, { "c": "Enter coefficients a, b and c: ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -562,7 +562,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.end.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.end.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -573,7 +573,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -595,7 +595,7 @@ }, { "c": " ", - "t": "source.c meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.c meta.block.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -606,18 +606,18 @@ }, { "c": "scanf", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -628,7 +628,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.begin.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.begin.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -639,7 +639,7 @@ }, { "c": "%f%f%f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -650,7 +650,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.end.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.end.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -661,7 +661,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -672,7 +672,7 @@ }, { "c": "&", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c meta.function-call.c keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -683,7 +683,7 @@ }, { "c": "a", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -694,7 +694,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -705,7 +705,7 @@ }, { "c": "&", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c meta.function-call.c keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -716,7 +716,7 @@ }, { "c": "b", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -727,7 +727,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -738,7 +738,7 @@ }, { "c": "&", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c meta.function-call.c keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -749,7 +749,7 @@ }, { "c": "c", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -760,7 +760,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -947,7 +947,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -958,7 +958,7 @@ }, { "c": "determinant", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -969,7 +969,7 @@ }, { "c": ">", - "t": "source.c meta.block.c keyword.operator.comparison.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.comparison.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -980,7 +980,7 @@ }, { "c": "0", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -991,7 +991,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1057,7 +1057,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1068,7 +1068,7 @@ }, { "c": "-", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1079,7 +1079,7 @@ }, { "c": "b", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1090,7 +1090,7 @@ }, { "c": "+", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1101,18 +1101,18 @@ }, { "c": "sqrt", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1123,7 +1123,7 @@ }, { "c": "determinant", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1133,8 +1133,19 @@ } }, { - "c": "))", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "c": ")", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c punctuation.section.arguments.end.bracket.round.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ")", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1156,7 +1167,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1167,7 +1178,7 @@ }, { "c": "2", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1178,7 +1189,7 @@ }, { "c": "*", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1189,7 +1200,7 @@ }, { "c": "a", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1200,7 +1211,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1255,7 +1266,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1266,7 +1277,7 @@ }, { "c": "-", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1277,7 +1288,7 @@ }, { "c": "b", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1288,7 +1299,7 @@ }, { "c": "-", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1299,18 +1310,18 @@ }, { "c": "sqrt", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1321,7 +1332,7 @@ }, { "c": "determinant", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1331,8 +1342,19 @@ } }, { - "c": "))", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "c": ")", + "t": "source.c meta.block.c punctuation.section.parens.block meta.function-call.c punctuation.section.arguments.end.bracket.round.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ")", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1354,7 +1376,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1365,7 +1387,7 @@ }, { "c": "2", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1376,7 +1398,7 @@ }, { "c": "*", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1387,7 +1409,7 @@ }, { "c": "a", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1398,7 +1420,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1420,7 +1442,7 @@ }, { "c": " ", - "t": "source.c meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.c meta.block.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1431,18 +1453,18 @@ }, { "c": "printf", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1453,7 +1475,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.begin.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.begin.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1464,7 +1486,7 @@ }, { "c": "Roots are: ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1475,7 +1497,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1486,7 +1508,7 @@ }, { "c": " and ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1497,7 +1519,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1508,7 +1530,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.end.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.end.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1519,7 +1541,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1530,7 +1552,7 @@ }, { "c": "r1 ", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1541,7 +1563,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1552,7 +1574,7 @@ }, { "c": " r2", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1563,7 +1585,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1662,7 +1684,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1673,7 +1695,7 @@ }, { "c": "determinant", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1684,7 +1706,7 @@ }, { "c": "==", - "t": "source.c meta.block.c keyword.operator.comparison.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.comparison.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1695,7 +1717,7 @@ }, { "c": "0", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1706,7 +1728,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1827,7 +1849,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1838,7 +1860,7 @@ }, { "c": "2", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1849,7 +1871,7 @@ }, { "c": "*", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1860,7 +1882,7 @@ }, { "c": "a", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1871,7 +1893,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1893,7 +1915,7 @@ }, { "c": " ", - "t": "source.c meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.c meta.block.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1904,18 +1926,18 @@ }, { "c": "printf", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1926,7 +1948,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.begin.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.begin.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1937,7 +1959,7 @@ }, { "c": "Roots are: ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1948,7 +1970,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1959,7 +1981,7 @@ }, { "c": " and ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1970,7 +1992,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1981,7 +2003,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.end.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.end.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1992,7 +2014,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2003,7 +2025,7 @@ }, { "c": " r1", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2014,7 +2036,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2025,7 +2047,7 @@ }, { "c": " r2", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2036,7 +2058,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2190,7 +2212,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2201,7 +2223,7 @@ }, { "c": "2", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -2212,7 +2234,7 @@ }, { "c": "*", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -2223,7 +2245,7 @@ }, { "c": "a", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2234,7 +2256,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2278,50 +2300,6 @@ }, { "c": " ", - "t": "source.c meta.block.c punctuation.whitespace.support.function.leading.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "sqrt", - "t": "source.c meta.block.c support.function.C99.c", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" - } - }, - { - "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "-", - "t": "source.c meta.block.c keyword.operator.c", - "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4" - } - }, - { - "c": "determinant", "t": "source.c meta.block.c", "r": { "dark_plus": "default: #D4D4D4", @@ -2331,9 +2309,53 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "sqrt", + "t": "source.c meta.block.c meta.function-call.c entity.name.function.c", + "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.c meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "-", + "t": "source.c meta.block.c meta.function-call.c keyword.operator.c", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": "determinant", + "t": "source.c meta.block.c meta.function-call.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2355,7 +2377,7 @@ }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2366,7 +2388,7 @@ }, { "c": "2", - "t": "source.c meta.block.c constant.numeric.c", + "t": "source.c meta.block.c punctuation.section.parens.block constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -2377,7 +2399,7 @@ }, { "c": "*", - "t": "source.c meta.block.c keyword.operator.c", + "t": "source.c meta.block.c punctuation.section.parens.block keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -2388,7 +2410,7 @@ }, { "c": "a", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2399,7 +2421,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2421,7 +2443,7 @@ }, { "c": " ", - "t": "source.c meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.c meta.block.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2432,18 +2454,18 @@ }, { "c": "printf", - "t": "source.c meta.block.c support.function.C99.c", + "t": "source.c meta.block.c meta.function-call.c entity.name.function.c", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.c meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2454,7 +2476,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.begin.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.begin.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2465,7 +2487,7 @@ }, { "c": "Roots are: ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2476,7 +2498,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2487,7 +2509,7 @@ }, { "c": "+", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2498,7 +2520,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2509,7 +2531,7 @@ }, { "c": "i and ", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2520,7 +2542,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2531,7 +2553,7 @@ }, { "c": "-", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2542,7 +2564,7 @@ }, { "c": "%.2f", - "t": "source.c meta.block.c string.quoted.double.c constant.other.placeholder.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c constant.other.placeholder.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2553,7 +2575,7 @@ }, { "c": "i", - "t": "source.c meta.block.c string.quoted.double.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2564,7 +2586,7 @@ }, { "c": "\"", - "t": "source.c meta.block.c string.quoted.double.c punctuation.definition.string.end.c", + "t": "source.c meta.block.c meta.function-call.c string.quoted.double.c punctuation.definition.string.end.c", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -2575,7 +2597,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2586,7 +2608,7 @@ }, { "c": " real", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2597,7 +2619,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2608,7 +2630,7 @@ }, { "c": " imag", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2619,7 +2641,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2630,7 +2652,7 @@ }, { "c": " real", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2641,7 +2663,7 @@ }, { "c": ",", - "t": "source.c meta.block.c punctuation.separator.delimiter.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2652,7 +2674,7 @@ }, { "c": " imag", - "t": "source.c meta.block.c", + "t": "source.c meta.block.c meta.function-call.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2663,7 +2685,7 @@ }, { "c": ")", - "t": "source.c meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.c meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/cpp/test/colorize-results/test_cc.json b/extensions/cpp/test/colorize-results/test_cc.json index f3f72320fb5..96e8792159f 100644 --- a/extensions/cpp/test/colorize-results/test_cc.json +++ b/extensions/cpp/test/colorize-results/test_cc.json @@ -1,7 +1,7 @@ [ { "c": "#", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -12,7 +12,7 @@ }, { "c": "if", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -23,7 +23,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.c", + "t": "source.cpp meta.preprocessor.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -34,7 +34,7 @@ }, { "c": "B4G_DEBUG_CHECK", - "t": "source.cpp meta.preprocessor.c entity.name.function.preprocessor.c", + "t": "source.cpp meta.preprocessor.cpp entity.name.function.preprocessor.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -56,7 +56,7 @@ }, { "c": "fprintf", - "t": "source.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -67,7 +67,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -78,7 +78,7 @@ }, { "c": "stderr", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -89,7 +89,7 @@ }, { "c": ",", - "t": "source.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -100,7 +100,7 @@ }, { "c": "\"", - "t": "source.cpp meta.function.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -111,7 +111,7 @@ }, { "c": "num_candidate_ret=", - "t": "source.cpp meta.function.c string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -122,7 +122,7 @@ }, { "c": "%d", - "t": "source.cpp meta.function.c string.quoted.double.cpp constant.other.placeholder.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -133,7 +133,7 @@ }, { "c": ":", - "t": "source.cpp meta.function.c string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -144,7 +144,7 @@ }, { "c": "\"", - "t": "source.cpp meta.function.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -155,7 +155,7 @@ }, { "c": ",", - "t": "source.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -166,7 +166,7 @@ }, { "c": " num_candidate", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -177,7 +177,7 @@ }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -188,7 +188,7 @@ }, { "c": ";", - "t": "source.cpp punctuation.terminator.statement.c", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -210,7 +210,7 @@ }, { "c": "for", - "t": "source.cpp keyword.control.c", + "t": "source.cpp keyword.control.for.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -221,7 +221,7 @@ }, { "c": "(", - "t": "source.cpp punctuation.section.parens.begin.bracket.round.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp punctuation.section.parens.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -232,7 +232,7 @@ }, { "c": "int", - "t": "source.cpp storage.type.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -243,7 +243,7 @@ }, { "c": " i", - "t": "source.cpp", + "t": "source.cpp punctuation.section.parens-c\b.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -254,7 +254,7 @@ }, { "c": "=", - "t": "source.cpp keyword.operator.assignment.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp keyword.operator.assignment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -265,7 +265,7 @@ }, { "c": "0", - "t": "source.cpp constant.numeric.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp constant.numeric.cpp", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -276,7 +276,7 @@ }, { "c": ";", - "t": "source.cpp punctuation.terminator.statement.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -287,7 +287,7 @@ }, { "c": "i", - "t": "source.cpp", + "t": "source.cpp punctuation.section.parens-c\b.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -298,7 +298,7 @@ }, { "c": "<", - "t": "source.cpp keyword.operator.comparison.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp keyword.operator.comparison.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -309,7 +309,7 @@ }, { "c": "num_candidate", - "t": "source.cpp", + "t": "source.cpp punctuation.section.parens-c\b.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -320,7 +320,7 @@ }, { "c": ";", - "t": "source.cpp punctuation.terminator.statement.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -331,7 +331,7 @@ }, { "c": "++", - "t": "source.cpp keyword.operator.increment.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp keyword.operator.increment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -342,7 +342,7 @@ }, { "c": "i", - "t": "source.cpp", + "t": "source.cpp punctuation.section.parens-c\b.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -353,7 +353,7 @@ }, { "c": ")", - "t": "source.cpp punctuation.section.parens.end.bracket.round.c", + "t": "source.cpp punctuation.section.parens-c\b.cpp punctuation.section.parens.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -375,7 +375,7 @@ }, { "c": "fprintf", - "t": "source.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -386,7 +386,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -397,7 +397,7 @@ }, { "c": "stderr", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -408,7 +408,7 @@ }, { "c": ",", - "t": "source.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -419,7 +419,7 @@ }, { "c": "\"", - "t": "source.cpp meta.function.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -430,7 +430,7 @@ }, { "c": "%d", - "t": "source.cpp meta.function.c string.quoted.double.cpp constant.other.placeholder.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -441,7 +441,7 @@ }, { "c": ",", - "t": "source.cpp meta.function.c string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -452,7 +452,7 @@ }, { "c": "\"", - "t": "source.cpp meta.function.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -463,7 +463,7 @@ }, { "c": ",", - "t": "source.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -474,18 +474,18 @@ }, { "c": "user_candidate", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp meta.bracket.square.access.cpp variable.object.cpp", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": "[", - "t": "source.cpp meta.function.c punctuation.definition.begin.bracket.square.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp meta.bracket.square.access.cpp punctuation.definition.begin.bracket.square.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -496,7 +496,7 @@ }, { "c": "i", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp meta.bracket.square.access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -507,7 +507,7 @@ }, { "c": "]", - "t": "source.cpp meta.function.c punctuation.definition.end.bracket.square.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp meta.bracket.square.access.cpp punctuation.definition.end.bracket.square.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -518,7 +518,7 @@ }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -529,7 +529,7 @@ }, { "c": ";", - "t": "source.cpp punctuation.terminator.statement.c", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -551,7 +551,7 @@ }, { "c": "fprintf", - "t": "source.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -562,7 +562,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -573,7 +573,7 @@ }, { "c": "stderr", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -584,7 +584,7 @@ }, { "c": ",", - "t": "source.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -595,7 +595,7 @@ }, { "c": "\"", - "t": "source.cpp meta.function.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -606,7 +606,7 @@ }, { "c": ";", - "t": "source.cpp meta.function.c string.quoted.double.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -617,7 +617,7 @@ }, { "c": "\"", - "t": "source.cpp meta.function.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -628,7 +628,7 @@ }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -639,7 +639,7 @@ }, { "c": ";", - "t": "source.cpp punctuation.terminator.statement.c", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -650,7 +650,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -661,7 +661,7 @@ }, { "c": "endif", - "t": "source.cpp meta.preprocessor.c keyword.control.directive.conditional.c", + "t": "source.cpp meta.preprocessor.cpp keyword.control.directive.conditional.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -683,7 +683,7 @@ }, { "c": "void", - "t": "source.cpp storage.type.c", + "t": "source.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -705,7 +705,7 @@ }, { "c": "main", - "t": "source.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -716,7 +716,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -726,8 +726,8 @@ } }, { - "c": "O obj", - "t": "source.cpp meta.function.c", + "c": "O ", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -736,9 +736,20 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "obj", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp variable.parameter.probably.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -760,7 +771,7 @@ }, { "c": "{", - "t": "source.cpp meta.block.c punctuation.section.block.begin.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.begin.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -771,7 +782,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -782,7 +793,7 @@ }, { "c": "LOG_INFO", - "t": "source.cpp meta.block.c meta.function-call.c entity.name.function.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -793,7 +804,7 @@ }, { "c": "(", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -804,7 +815,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -815,7 +826,7 @@ }, { "c": "not hilighted as string", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -826,7 +837,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -837,7 +848,7 @@ }, { "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -848,7 +859,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -859,7 +870,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -870,7 +881,7 @@ }, { "c": "LOG_INFO", - "t": "source.cpp meta.block.c meta.function-call.c entity.name.function.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -881,7 +892,7 @@ }, { "c": "(", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -892,7 +903,7 @@ }, { "c": "obj ", - "t": "source.cpp meta.block.c meta.function-call.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -903,7 +914,7 @@ }, { "c": "<<", - "t": "source.cpp meta.block.c meta.function-call.c keyword.operator.bitwise.shift.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -914,7 +925,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c meta.function-call.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -925,7 +936,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -936,7 +947,7 @@ }, { "c": ", even worse; ", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -947,7 +958,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -958,7 +969,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c meta.function-call.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -969,7 +980,7 @@ }, { "c": "<<", - "t": "source.cpp meta.block.c meta.function-call.c keyword.operator.bitwise.shift.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -979,8 +990,8 @@ } }, { - "c": " obj", - "t": "source.cpp meta.block.c meta.function-call.c", + "c": " ", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -989,20 +1000,31 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "obj", + "t": "source.cpp meta.block.cpp meta.function-call.cpp variable.object.access.cpp variable.object.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, { "c": ".", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.separator.dot-access.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp variable.object.access.cpp punctuation.separator.dot-access.cpp", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": "x", - "t": "source.cpp meta.block.c meta.function-call.c variable.other.member.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp variable.object.access.cpp variable.other.member.cpp", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1013,7 +1035,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c meta.function-call.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1024,7 +1046,7 @@ }, { "c": "<<", - "t": "source.cpp meta.block.c meta.function-call.c keyword.operator.bitwise.shift.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp keyword.operator.bitwise.shift.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1035,7 +1057,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c meta.function-call.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1046,7 +1068,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1057,7 +1079,7 @@ }, { "c": " check this out.", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1068,7 +1090,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1079,7 +1101,7 @@ }, { "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1090,7 +1112,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1101,7 +1123,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.block.cpp punctuation.whitespace.comment.leading.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1112,7 +1134,7 @@ }, { "c": "//", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1123,7 +1145,7 @@ }, { "c": " everything from this point on is interpeted as a string literal...", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1134,7 +1156,7 @@ }, { "c": " O x", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1145,7 +1167,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1155,8 +1177,19 @@ } }, { - "c": " std", - "t": "source.cpp meta.block.c", + "c": " ", + "t": "source.cpp meta.block.cpp punctuation.separator.namespace.access.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "std", + "t": "source.cpp meta.block.cpp punctuation.separator.namespace.access.cpp entity.scope.name.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1167,7 +1200,7 @@ }, { "c": "::", - "t": "source.cpp meta.block.c punctuation.separator.namespace.access.cpp", + "t": "source.cpp meta.block.cpp punctuation.separator.namespace.access.cpp punctuation.separator.namespace.access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1178,7 +1211,7 @@ }, { "c": "unique_ptr", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1189,7 +1222,7 @@ }, { "c": "<", - "t": "source.cpp meta.block.c keyword.operator.comparison.c", + "t": "source.cpp meta.block.cpp keyword.operator.comparison.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1200,7 +1233,7 @@ }, { "c": "O", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1211,7 +1244,7 @@ }, { "c": ">", - "t": "source.cpp meta.block.c keyword.operator.comparison.c", + "t": "source.cpp meta.block.cpp keyword.operator.comparison.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1222,7 +1255,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1233,7 +1266,7 @@ }, { "c": "o", - "t": "source.cpp meta.block.c meta.function-call.c entity.name.function.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1244,7 +1277,7 @@ }, { "c": "(", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1255,18 +1288,18 @@ }, { "c": "new", - "t": "source.cpp meta.block.c meta.function-call.c keyword.control.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp keyword.operator.new.cpp", "r": { - "dark_plus": "keyword.control: #C586C0", - "light_plus": "keyword.control: #AF00DB", - "dark_vs": "keyword.control: #569CD6", - "light_vs": "keyword.control: #0000FF", - "hc_black": "keyword.control: #C586C0" + "dark_plus": "keyword.operator.new: #569CD6", + "light_plus": "keyword.operator.new: #0000FF", + "dark_vs": "keyword.operator.new: #569CD6", + "light_vs": "keyword.operator.new: #0000FF", + "hc_black": "keyword.operator.new: #569CD6" } }, { "c": " O", - "t": "source.cpp meta.block.c meta.function-call.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1277,7 +1310,7 @@ }, { "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1288,7 +1321,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1299,7 +1332,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.block.cpp punctuation.whitespace.comment.leading.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1310,7 +1343,7 @@ }, { "c": "//", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1321,7 +1354,7 @@ }, { "c": " sadness.", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1332,7 +1365,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1343,18 +1376,18 @@ }, { "c": "sprintf", - "t": "source.cpp meta.block.c support.function.C99.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp entity.name.function.call.cpp", "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", + "dark_plus": "entity.name.function: #DCDCAA", + "light_plus": "entity.name.function: #795E26", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" + "hc_black": "entity.name.function: #DCDCAA" } }, { "c": "(", - "t": "source.cpp meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1365,7 +1398,7 @@ }, { "c": "options", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1376,7 +1409,7 @@ }, { "c": ",", - "t": "source.cpp meta.block.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1387,7 +1420,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1398,7 +1431,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1409,7 +1442,7 @@ }, { "c": "STYLE=Keramik;TITLE=", - "t": "source.cpp meta.block.c string.quoted.double.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1420,7 +1453,7 @@ }, { "c": "%s", - "t": "source.cpp meta.block.c string.quoted.double.cpp constant.other.placeholder.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1431,7 +1464,7 @@ }, { "c": ";THEME=", - "t": "source.cpp meta.block.c string.quoted.double.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1442,7 +1475,7 @@ }, { "c": "%s", - "t": "source.cpp meta.block.c string.quoted.double.cpp constant.other.placeholder.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp constant.other.placeholder.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1453,7 +1486,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1464,7 +1497,7 @@ }, { "c": ",", - "t": "source.cpp meta.block.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1474,19 +1507,8 @@ } }, { - "c": " ", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "...", - "t": "source.cpp meta.block.c punctuation.separator.dot-access.c", + "c": " ...", + "t": "source.cpp meta.block.cpp meta.function-call.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1497,7 +1519,7 @@ }, { "c": ")", - "t": "source.cpp meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1508,7 +1530,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1519,7 +1541,7 @@ }, { "c": "}", - "t": "source.cpp meta.block.c punctuation.section.block.end.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.end.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1530,7 +1552,7 @@ }, { "c": "int", - "t": "source.cpp storage.type.c", + "t": "source.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -1552,7 +1574,7 @@ }, { "c": "main2", - "t": "source.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1563,7 +1585,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1574,7 +1596,7 @@ }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1596,7 +1618,7 @@ }, { "c": "{", - "t": "source.cpp meta.block.c punctuation.section.block.begin.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.begin.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1607,7 +1629,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c punctuation.whitespace.support.function.leading.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1618,260 +1640,7 @@ }, { "c": "printf", - "t": "source.cpp meta.block.c support.function.C99.c", - "r": { - "dark_plus": "support.function: #DCDCAA", - "light_plus": "support.function: #795E26", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "support.function: #DCDCAA" - } - }, - { - "c": "(", - "t": "source.cpp meta.block.c punctuation.section.parens.begin.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "\"", - "t": "source.cpp meta.block.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": ";", - "t": "source.cpp meta.block.c string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "\"", - "t": "source.cpp meta.block.c string.quoted.double.cpp punctuation.definition.string.end.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": ")", - "t": "source.cpp meta.block.c punctuation.section.parens.end.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": " ", - "t": "source.cpp meta.block.c punctuation.whitespace.comment.leading.cpp", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "//", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", - "r": { - "dark_plus": "comment: #6A9955", - "light_plus": "comment: #008000", - "dark_vs": "comment: #6A9955", - "light_vs": "comment: #008000", - "hc_black": "comment: #7CA668" - } - }, - { - "c": " the rest of", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp", - "r": { - "dark_plus": "comment: #6A9955", - "light_plus": "comment: #008000", - "dark_vs": "comment: #6A9955", - "light_vs": "comment: #008000", - "hc_black": "comment: #7CA668" - } - }, - { - "c": " ", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "asm", - "t": "source.cpp meta.block.c meta.function-call.c storage.type.c", - "r": { - "dark_plus": "storage.type: #569CD6", - "light_plus": "storage.type: #0000FF", - "dark_vs": "storage.type: #569CD6", - "light_vs": "storage.type: #0000FF", - "hc_black": "storage.type: #569CD6" - } - }, - { - "c": "(", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.parens.begin.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "movw $0x38, ", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "%a", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp constant.other.placeholder.c", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "x; ltr ", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "%a", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp constant.other.placeholder.c", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "x", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.end.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.parens.end.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": " ", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "fn", - "t": "source.cpp meta.block.c meta.function-call.c entity.name.function.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp entity.name.function.call.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -1882,7 +1651,7 @@ }, { "c": "(", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1893,7 +1662,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1903,8 +1672,8 @@ } }, { - "c": "{};", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp", + "c": ";", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1915,7 +1684,7 @@ }, { "c": "\"", - "t": "source.cpp meta.block.c meta.function-call.c string.quoted.double.cpp punctuation.definition.string.end.cpp", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1926,7 +1695,7 @@ }, { "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1937,7 +1706,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1948,7 +1717,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c punctuation.whitespace.comment.leading.cpp", + "t": "source.cpp meta.block.cpp punctuation.whitespace.comment.leading.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1959,7 +1728,7 @@ }, { "c": "//", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1970,7 +1739,260 @@ }, { "c": " the rest of", - "t": "source.cpp meta.block.c comment.line.double-slash.cpp", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "asm", + "t": "source.cpp meta.block.cpp meta.function-call.cpp storage.type.asm.cpp", + "r": { + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" + } + }, + { + "c": "(", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.parens.begin.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "\"", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "movw $0x38, ", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "%a", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp constant.other.placeholder.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "x; ltr ", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "%a", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp constant.other.placeholder.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "x", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "\"", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": ")", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.parens.end.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "fn", + "t": "source.cpp meta.block.cpp meta.function-call.cpp entity.name.function.call.cpp", + "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.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.begin.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "\"", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "{};", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "\"", + "t": "source.cpp meta.block.cpp meta.function-call.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": ")", + "t": "source.cpp meta.block.cpp meta.function-call.cpp punctuation.section.arguments.end.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp punctuation.whitespace.comment.leading.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "//", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp", + "r": { + "dark_plus": "comment: #6A9955", + "light_plus": "comment: #008000", + "dark_vs": "comment: #6A9955", + "light_vs": "comment: #008000", + "hc_black": "comment: #7CA668" + } + }, + { + "c": " the rest of", + "t": "source.cpp meta.block.cpp comment.line.double-slash.cpp", "r": { "dark_plus": "comment: #6A9955", "light_plus": "comment: #008000", @@ -1981,7 +2003,7 @@ }, { "c": "}", - "t": "source.cpp meta.block.c punctuation.section.block.end.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.end.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/cpp/test/colorize-results/test_cpp.json b/extensions/cpp/test/colorize-results/test_cpp.json index b3c9a841cc4..134c8274ca7 100644 --- a/extensions/cpp/test/colorize-results/test_cpp.json +++ b/extensions/cpp/test/colorize-results/test_cpp.json @@ -23,7 +23,7 @@ }, { "c": "#", - "t": "source.cpp meta.preprocessor.include.c keyword.control.directive.include.c punctuation.definition.directive.c", + "t": "source.cpp meta.preprocessor.include.cpp keyword.control.directive.include.cpp punctuation.definition.directive.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -34,7 +34,7 @@ }, { "c": "include", - "t": "source.cpp meta.preprocessor.include.c keyword.control.directive.include.c", + "t": "source.cpp meta.preprocessor.include.cpp keyword.control.directive.include.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -45,7 +45,7 @@ }, { "c": " ", - "t": "source.cpp meta.preprocessor.include.c", + "t": "source.cpp meta.preprocessor.include.cpp", "r": { "dark_plus": "meta.preprocessor: #569CD6", "light_plus": "meta.preprocessor: #0000FF", @@ -56,7 +56,7 @@ }, { "c": "<", - "t": "source.cpp meta.preprocessor.include.c string.quoted.other.lt-gt.include.c punctuation.definition.string.begin.c", + "t": "source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp punctuation.definition.string.begin.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -67,7 +67,7 @@ }, { "c": "iostream", - "t": "source.cpp meta.preprocessor.include.c string.quoted.other.lt-gt.include.c", + "t": "source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -78,7 +78,7 @@ }, { "c": ">", - "t": "source.cpp meta.preprocessor.include.c string.quoted.other.lt-gt.include.c punctuation.definition.string.end.c", + "t": "source.cpp meta.preprocessor.include.cpp string.quoted.other.lt-gt.include.cpp punctuation.definition.string.end.cpp", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -89,13 +89,13 @@ }, { "c": "using", - "t": "source.cpp meta.using-namespace-declaration.cpp keyword.control.cpp", + "t": "source.cpp meta.using-namespace-declaration.cpp keyword.other.using.directive.cpp", "r": { - "dark_plus": "keyword.control: #C586C0", - "light_plus": "keyword.control: #AF00DB", - "dark_vs": "keyword.control: #569CD6", - "light_vs": "keyword.control: #0000FF", - "hc_black": "keyword.control: #C586C0" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -111,13 +111,13 @@ }, { "c": "namespace", - "t": "source.cpp meta.using-namespace-declaration.cpp storage.type.cpp", + "t": "source.cpp meta.using-namespace-declaration.cpp keyword.other.namespace.directive.cpp", "r": { - "dark_plus": "storage.type: #569CD6", - "light_plus": "storage.type: #0000FF", - "dark_vs": "storage.type: #569CD6", - "light_vs": "storage.type: #0000FF", - "hc_black": "storage.type: #569CD6" + "dark_plus": "keyword: #569CD6", + "light_plus": "keyword: #0000FF", + "dark_vs": "keyword: #569CD6", + "light_vs": "keyword: #0000FF", + "hc_black": "keyword: #569CD6" } }, { @@ -133,7 +133,7 @@ }, { "c": "std", - "t": "source.cpp meta.using-namespace-declaration.cpp entity.name.type.cpp", + "t": "source.cpp meta.using-namespace-declaration.cpp entity.name.type.namespace.cpp", "r": { "dark_plus": "entity.name.type: #4EC9B0", "light_plus": "entity.name.type: #267F99", @@ -144,7 +144,7 @@ }, { "c": ";", - "t": "source.cpp meta.using-namespace-declaration.cpp", + "t": "source.cpp meta.using-namespace-declaration.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -155,7 +155,7 @@ }, { "c": "class", - "t": "source.cpp meta.class-struct-block.cpp storage.type.cpp", + "t": "source.cpp meta.class-struct-block.cpp storage.type.class.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -221,7 +221,7 @@ }, { "c": "int", - "t": "source.cpp meta.class-struct-block.cpp storage.type.c", + "t": "source.cpp meta.class-struct-block.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -243,7 +243,7 @@ }, { "c": ",", - "t": "source.cpp meta.class-struct-block.cpp punctuation.separator.delimiter.c", + "t": "source.cpp meta.class-struct-block.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -265,7 +265,7 @@ }, { "c": ";", - "t": "source.cpp meta.class-struct-block.cpp punctuation.terminator.statement.c", + "t": "source.cpp meta.class-struct-block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -287,13 +287,13 @@ }, { "c": "public:", - "t": "source.cpp meta.class-struct-block.cpp storage.modifier.cpp", + "t": "source.cpp meta.class-struct-block.cpp storage.type.modifier.access.control.public.cpp", "r": { - "dark_plus": "storage.modifier: #569CD6", - "light_plus": "storage.modifier: #0000FF", - "dark_vs": "storage.modifier: #569CD6", - "light_vs": "storage.modifier: #0000FF", - "hc_black": "storage.modifier: #569CD6" + "dark_plus": "storage.type: #569CD6", + "light_plus": "storage.type: #0000FF", + "dark_vs": "storage.type: #569CD6", + "light_vs": "storage.type: #0000FF", + "hc_black": "storage.type: #569CD6" } }, { @@ -309,7 +309,7 @@ }, { "c": "void", - "t": "source.cpp meta.class-struct-block.cpp storage.type.c", + "t": "source.cpp meta.class-struct-block.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -331,7 +331,7 @@ }, { "c": "set_values", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -342,7 +342,7 @@ }, { "c": " ", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -353,7 +353,7 @@ }, { "c": "(", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -364,7 +364,7 @@ }, { "c": "int", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c storage.type.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -375,7 +375,7 @@ }, { "c": ",", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -386,7 +386,7 @@ }, { "c": "int", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c storage.type.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -397,7 +397,7 @@ }, { "c": ")", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -408,7 +408,7 @@ }, { "c": ";", - "t": "source.cpp meta.class-struct-block.cpp punctuation.terminator.statement.c", + "t": "source.cpp meta.class-struct-block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -430,7 +430,7 @@ }, { "c": "int", - "t": "source.cpp meta.class-struct-block.cpp storage.type.c", + "t": "source.cpp meta.class-struct-block.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -452,7 +452,7 @@ }, { "c": "area", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -463,7 +463,7 @@ }, { "c": "(", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -474,7 +474,7 @@ }, { "c": ")", - "t": "source.cpp meta.class-struct-block.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.class-struct-block.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -496,7 +496,7 @@ }, { "c": "{", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c punctuation.section.block.begin.bracket.curly.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp punctuation.section.block.begin.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -507,7 +507,7 @@ }, { "c": "return", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c keyword.control.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp keyword.control.return.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -518,7 +518,7 @@ }, { "c": " width", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -529,7 +529,7 @@ }, { "c": "*", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c keyword.operator.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp keyword.operator.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -540,7 +540,7 @@ }, { "c": "height", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -551,7 +551,7 @@ }, { "c": ";", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -562,7 +562,7 @@ }, { "c": "}", - "t": "source.cpp meta.class-struct-block.cpp meta.block.c punctuation.section.block.end.bracket.curly.c", + "t": "source.cpp meta.class-struct-block.cpp meta.block.cpp punctuation.section.block.end.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -584,7 +584,7 @@ }, { "c": ";", - "t": "source.cpp punctuation.terminator.statement.c", + "t": "source.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -595,7 +595,7 @@ }, { "c": "void", - "t": "source.cpp storage.type.c", + "t": "source.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -606,7 +606,7 @@ }, { "c": " ", - "t": "source.cpp", + "t": "source.cpp punctuation.separator.namespace.access.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -616,8 +616,30 @@ } }, { - "c": "Rectangle::set_values", - "t": "source.cpp meta.function.c entity.name.function.c", + "c": "Rectangle", + "t": "source.cpp punctuation.separator.namespace.access.cpp entity.scope.name.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "::", + "t": "source.cpp punctuation.separator.namespace.access.cpp punctuation.separator.namespace.access.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "set_values", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -628,7 +650,7 @@ }, { "c": " ", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -639,7 +661,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -650,7 +672,7 @@ }, { "c": "int", - "t": "source.cpp meta.function.c storage.type.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -660,8 +682,8 @@ } }, { - "c": " x", - "t": "source.cpp meta.function.c", + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -670,9 +692,20 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "x", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp variable.parameter.probably.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, { "c": ",", - "t": "source.cpp meta.function.c punctuation.separator.delimiter.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.separator.delimiter.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -683,7 +716,7 @@ }, { "c": " ", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -694,7 +727,7 @@ }, { "c": "int", - "t": "source.cpp meta.function.c storage.type.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -704,8 +737,8 @@ } }, { - "c": " y", - "t": "source.cpp meta.function.c", + "c": " ", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -714,9 +747,20 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "y", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp variable.parameter.probably.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -738,7 +782,7 @@ }, { "c": "{", - "t": "source.cpp meta.block.c punctuation.section.block.begin.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.begin.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -749,7 +793,7 @@ }, { "c": " width ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -760,7 +804,7 @@ }, { "c": "=", - "t": "source.cpp meta.block.c keyword.operator.assignment.c", + "t": "source.cpp meta.block.cpp keyword.operator.assignment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -771,7 +815,7 @@ }, { "c": " x", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -782,7 +826,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -793,7 +837,7 @@ }, { "c": " height ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -804,7 +848,7 @@ }, { "c": "=", - "t": "source.cpp meta.block.c keyword.operator.assignment.c", + "t": "source.cpp meta.block.cpp keyword.operator.assignment.cpp", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -815,7 +859,7 @@ }, { "c": " y", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -826,7 +870,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -837,7 +881,7 @@ }, { "c": "}", - "t": "source.cpp meta.block.c punctuation.section.block.end.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.end.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -848,7 +892,7 @@ }, { "c": "int", - "t": "source.cpp storage.type.c", + "t": "source.cpp storage.type.language.primitive.cpp", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -870,7 +914,7 @@ }, { "c": "main", - "t": "source.cpp meta.function.c entity.name.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp entity.name.function.cpp", "r": { "dark_plus": "entity.name.function: #DCDCAA", "light_plus": "entity.name.function: #795E26", @@ -881,7 +925,7 @@ }, { "c": " ", - "t": "source.cpp meta.function.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -892,7 +936,7 @@ }, { "c": "(", - "t": "source.cpp meta.function.c punctuation.section.parameters.begin.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.begin.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -903,7 +947,7 @@ }, { "c": ")", - "t": "source.cpp meta.function.c punctuation.section.parameters.end.bracket.round.c", + "t": "source.cpp meta.function.definition.cpp meta.function.definition.parameters.cpp punctuation.section.parameters.end.bracket.round.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -925,7 +969,7 @@ }, { "c": "{", - "t": "source.cpp meta.block.c punctuation.section.block.begin.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.begin.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -936,7 +980,7 @@ }, { "c": " Rectangle rect", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -947,271 +991,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": " rect", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ".", - "t": "source.cpp meta.block.c punctuation.separator.dot-access.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "set_values", - "t": "source.cpp meta.block.c meta.function-call.c entity.name.function.c", - "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.cpp meta.block.c meta.function-call.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "(", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "3", - "t": "source.cpp meta.block.c meta.function-call.c constant.numeric.c", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #09885A", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #09885A", - "hc_black": "constant.numeric: #B5CEA8" - } - }, - { - "c": ",", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.separator.delimiter.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "4", - "t": "source.cpp meta.block.c meta.function-call.c constant.numeric.c", - "r": { - "dark_plus": "constant.numeric: #B5CEA8", - "light_plus": "constant.numeric: #09885A", - "dark_vs": "constant.numeric: #B5CEA8", - "light_vs": "constant.numeric: #09885A", - "hc_black": "constant.numeric: #B5CEA8" - } - }, - { - "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": " cout ", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "<<", - "t": "source.cpp meta.block.c keyword.operator.bitwise.shift.c", - "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4" - } - }, - { - "c": " ", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "\"", - "t": "source.cpp meta.block.c string.quoted.double.cpp punctuation.definition.string.begin.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "area: ", - "t": "source.cpp meta.block.c string.quoted.double.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": "\"", - "t": "source.cpp meta.block.c string.quoted.double.cpp punctuation.definition.string.end.cpp", - "r": { - "dark_plus": "string: #CE9178", - "light_plus": "string: #A31515", - "dark_vs": "string: #CE9178", - "light_vs": "string: #A31515", - "hc_black": "string: #CE9178" - } - }, - { - "c": " ", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "<<", - "t": "source.cpp meta.block.c keyword.operator.bitwise.shift.c", - "r": { - "dark_plus": "keyword.operator: #D4D4D4", - "light_plus": "keyword.operator: #000000", - "dark_vs": "keyword.operator: #D4D4D4", - "light_vs": "keyword.operator: #000000", - "hc_black": "keyword.operator: #D4D4D4" - } - }, - { - "c": " rect", - "t": "source.cpp meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ".", - "t": "source.cpp meta.block.c punctuation.separator.dot-access.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "area", - "t": "source.cpp meta.block.c meta.function-call.c entity.name.function.c", - "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.cpp meta.block.c meta.function-call.c punctuation.section.arguments.begin.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ")", - "t": "source.cpp meta.block.c meta.function-call.c punctuation.section.arguments.end.bracket.round.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1222,7 +1002,293 @@ }, { "c": " ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "rect", + "t": "source.cpp meta.block.cpp variable.object.access.cpp variable.object.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.cpp meta.block.cpp variable.object.access.cpp punctuation.separator.dot-access.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": "set_values", + "t": "source.cpp meta.block.cpp variable.object.access.cpp variable.other.member.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "(", + "t": "source.cpp meta.block.cpp meta.block.parens.cpp punctuation.section.parens.begin.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "3", + "t": "source.cpp meta.block.cpp meta.block.parens.cpp constant.numeric.cpp", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": ",", + "t": "source.cpp meta.block.cpp meta.block.parens.cpp punctuation.separator.delimiter.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "4", + "t": "source.cpp meta.block.cpp meta.block.parens.cpp constant.numeric.cpp", + "r": { + "dark_plus": "constant.numeric: #B5CEA8", + "light_plus": "constant.numeric: #09885A", + "dark_vs": "constant.numeric: #B5CEA8", + "light_vs": "constant.numeric: #09885A", + "hc_black": "constant.numeric: #B5CEA8" + } + }, + { + "c": ")", + "t": "source.cpp meta.block.cpp meta.block.parens.cpp punctuation.section.parens.end.bracket.round.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " cout ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "<<", + "t": "source.cpp meta.block.cpp keyword.operator.bitwise.shift.cpp", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "\"", + "t": "source.cpp meta.block.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "area: ", + "t": "source.cpp meta.block.cpp string.quoted.double.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": "\"", + "t": "source.cpp meta.block.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp", + "r": { + "dark_plus": "string: #CE9178", + "light_plus": "string: #A31515", + "dark_vs": "string: #CE9178", + "light_vs": "string: #A31515", + "hc_black": "string: #CE9178" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "<<", + "t": "source.cpp meta.block.cpp keyword.operator.bitwise.shift.cpp", + "r": { + "dark_plus": "keyword.operator: #D4D4D4", + "light_plus": "keyword.operator: #000000", + "dark_vs": "keyword.operator: #D4D4D4", + "light_vs": "keyword.operator: #000000", + "hc_black": "keyword.operator: #D4D4D4" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "rect", + "t": "source.cpp meta.block.cpp meta.function-call.member.cpp variable.object.cpp", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.cpp meta.block.cpp meta.function-call.member.cpp punctuation.separator.dot-access.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "area", + "t": "source.cpp meta.block.cpp meta.function-call.member.cpp entity.name.function.member.cpp", + "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.cpp meta.block.cpp meta.function-call.member.cpp punctuation.section.arguments.begin.bracket.round.function.member.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ")", + "t": "source.cpp meta.block.cpp meta.function-call.member.cpp punctuation.section.arguments.end.bracket.round.function.member.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1233,7 +1299,7 @@ }, { "c": "return", - "t": "source.cpp meta.block.c keyword.control.c", + "t": "source.cpp meta.block.cpp keyword.control.return.cpp", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -1244,7 +1310,7 @@ }, { "c": " ", - "t": "source.cpp meta.block.c", + "t": "source.cpp meta.block.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1255,7 +1321,7 @@ }, { "c": "0", - "t": "source.cpp meta.block.c constant.numeric.c", + "t": "source.cpp meta.block.cpp constant.numeric.cpp", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -1266,7 +1332,7 @@ }, { "c": ";", - "t": "source.cpp meta.block.c punctuation.terminator.statement.c", + "t": "source.cpp meta.block.cpp punctuation.terminator.statement.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1277,7 +1343,7 @@ }, { "c": "}", - "t": "source.cpp meta.block.c punctuation.section.block.end.bracket.curly.c", + "t": "source.cpp meta.block.cpp punctuation.section.block.end.bracket.curly.cpp", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", diff --git a/extensions/objective-c/test/colorize-results/test_m.json b/extensions/objective-c/test/colorize-results/test_m.json index 9a4926acad5..dc53e9cd713 100644 --- a/extensions/objective-c/test/colorize-results/test_m.json +++ b/extensions/objective-c/test/colorize-results/test_m.json @@ -298,7 +298,7 @@ }, { "c": "void", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.function.objc meta.return-type.objc storage.type.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.function.objc meta.return-type.objc storage.type.built-in.primitive.c", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -639,7 +639,7 @@ }, { "c": "(", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -650,7 +650,7 @@ }, { "c": "NSDocumentDirectory", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.constant.cocoa", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block support.constant.cocoa", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -661,7 +661,7 @@ }, { "c": ",", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.delimiter.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -672,7 +672,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -683,7 +683,7 @@ }, { "c": "NSUserDomainMask", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.constant.cocoa", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block support.constant.cocoa", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -694,7 +694,7 @@ }, { "c": ",", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.delimiter.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -705,7 +705,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -716,7 +716,7 @@ }, { "c": "true", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c constant.language.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block constant.language.c", "r": { "dark_plus": "constant.language: #569CD6", "light_plus": "constant.language: #0000FF", @@ -727,7 +727,7 @@ }, { "c": ")", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -738,7 +738,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -749,7 +749,7 @@ }, { "c": "0", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c constant.numeric.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c constant.numeric.c", "r": { "dark_plus": "constant.numeric: #B5CEA8", "light_plus": "constant.numeric: #09885A", @@ -760,7 +760,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -848,7 +848,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -859,7 +859,7 @@ }, { "c": "NSOpenPanel", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.class.cocoa", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c support.class.cocoa", "r": { "dark_plus": "support.class: #4EC9B0", "light_plus": "support.class: #267F99", @@ -870,7 +870,7 @@ }, { "c": " openPanel", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -881,7 +881,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -914,7 +914,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -925,7 +925,7 @@ }, { "c": "panel setAllowedFileTypes:", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -935,8 +935,19 @@ } }, { - "c": "[[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "c": "[", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "[", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -947,7 +958,7 @@ }, { "c": "NSArray", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.class.cocoa", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c support.class.cocoa", "r": { "dark_plus": "support.class: #4EC9B0", "light_plus": "support.class: #267F99", @@ -958,7 +969,7 @@ }, { "c": " alloc", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -969,7 +980,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -980,7 +991,7 @@ }, { "c": " initWithObjects:", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -991,7 +1002,7 @@ }, { "c": "@\"", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc punctuation.definition.string.begin.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc punctuation.definition.string.begin.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1002,7 +1013,7 @@ }, { "c": "ipa", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1013,7 +1024,7 @@ }, { "c": "\"", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc punctuation.definition.string.end.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc punctuation.definition.string.end.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1024,7 +1035,7 @@ }, { "c": ",", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.delimiter.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1035,7 +1046,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1046,7 +1057,7 @@ }, { "c": "@\"", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc punctuation.definition.string.begin.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc punctuation.definition.string.begin.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1057,7 +1068,7 @@ }, { "c": "xcarchive", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1068,7 +1079,7 @@ }, { "c": "\"", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc punctuation.definition.string.end.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc punctuation.definition.string.end.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1079,7 +1090,7 @@ }, { "c": ",", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.delimiter.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1090,7 +1101,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1101,7 +1112,7 @@ }, { "c": "@\"", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc punctuation.definition.string.begin.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc punctuation.definition.string.begin.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1112,7 +1123,7 @@ }, { "c": "app", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1123,7 +1134,7 @@ }, { "c": "\"", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c string.quoted.double.objc punctuation.definition.string.end.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c string.quoted.double.objc punctuation.definition.string.end.objc", "r": { "dark_plus": "string: #CE9178", "light_plus": "string: #A31515", @@ -1134,7 +1145,7 @@ }, { "c": ",", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.delimiter.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.separator.delimiter.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1145,7 +1156,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1156,7 +1167,7 @@ }, { "c": "nil", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c constant.language.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c constant.language.objc", "r": { "dark_plus": "constant.language: #569CD6", "light_plus": "constant.language: #0000FF", @@ -1166,8 +1177,19 @@ } }, { - "c": "]]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "c": "]", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "]", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1200,7 +1222,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1211,7 +1233,7 @@ }, { "c": "panel beginWithCompletionHandler:", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1222,7 +1244,7 @@ }, { "c": "^", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c keyword.operator.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c keyword.operator.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1233,7 +1255,7 @@ }, { "c": "(", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1244,7 +1266,7 @@ }, { "c": "NSInteger", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.type.cocoa.leopard", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c support.type.cocoa.leopard", "r": { "dark_plus": "support.type: #4EC9B0", "light_plus": "support.type: #267F99", @@ -1255,7 +1277,7 @@ }, { "c": " result", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1266,7 +1288,7 @@ }, { "c": ")", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1277,7 +1299,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1288,7 +1310,7 @@ }, { "c": "{", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.block.begin.bracket.curly.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.block.begin.bracket.curly.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1299,7 +1321,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1310,7 +1332,7 @@ }, { "c": "if", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c keyword.control.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c keyword.control.c", "r": { "dark_plus": "keyword.control: #C586C0", "light_plus": "keyword.control: #AF00DB", @@ -1321,7 +1343,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1332,7 +1354,7 @@ }, { "c": "(", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.begin.bracket.round.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.block punctuation.section.parens.begin.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1343,7 +1365,7 @@ }, { "c": "result ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1354,7 +1376,7 @@ }, { "c": "==", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c keyword.operator.comparison.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.block keyword.operator.comparison.c", "r": { "dark_plus": "keyword.operator: #D4D4D4", "light_plus": "keyword.operator: #000000", @@ -1365,7 +1387,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.block", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1376,7 +1398,7 @@ }, { "c": "NSFileHandlingPanelOKButton", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.constant.cocoa", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.block support.constant.cocoa", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1387,7 +1409,7 @@ }, { "c": ")", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.parens.end.bracket.round.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.parens.block punctuation.section.parens.end.bracket.round.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1398,7 +1420,7 @@ }, { "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1409,7 +1431,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1420,29 +1442,29 @@ }, { "c": "self", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c variable.object.access.c variable.object.c", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": ".", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.dot-access.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c variable.object.access.c punctuation.separator.dot-access.c", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": "inputTextField", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.other.member.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c variable.object.access.c variable.other.member.c", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1453,7 +1475,7 @@ }, { "c": " setStringValue:", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1464,7 +1486,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1475,29 +1497,29 @@ }, { "c": "panel", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c variable.object.access.c variable.object.c", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": ".", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.dot-access.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c variable.object.access.c punctuation.separator.dot-access.c", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": "URL", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.other.member.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c variable.object.access.c variable.other.member.c", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -1508,51 +1530,7 @@ }, { "c": " path", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "]]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": ";", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.terminator.statement.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": " ", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", - "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", - "dark_vs": "default: #D4D4D4", - "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" - } - }, - { - "c": "}", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.section.block.end.bracket.curly.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1563,7 +1541,62 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "]", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": ";", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.terminator.statement.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": " ", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "}", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.section.block.end.bracket.curly.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "]", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -1651,7 +1684,7 @@ }, { "c": "int", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c storage.type.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c storage.type.built-in.primitive.c", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -1728,7 +1761,7 @@ }, { "c": "float", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c storage.type.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c storage.type.built-in.primitive.c", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -2299,8 +2332,19 @@ } }, { - "c": "[[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "c": "[", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", + "r": { + "dark_plus": "default: #D4D4D4", + "light_plus": "default: #000000", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "default: #FFFFFF" + } + }, + { + "c": "[", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2311,7 +2355,7 @@ }, { "c": "UITapGestureRecognizer alloc", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2322,7 +2366,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2333,7 +2377,7 @@ }, { "c": " initWithTarget:self action:", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2344,7 +2388,7 @@ }, { "c": "@", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.selector.objc storage.type.objc punctuation.definition.storage.type.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.selector.objc storage.type.objc punctuation.definition.storage.type.objc", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -2355,7 +2399,7 @@ }, { "c": "selector", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.selector.objc storage.type.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.selector.objc storage.type.objc", "r": { "dark_plus": "storage.type: #569CD6", "light_plus": "storage.type: #0000FF", @@ -2366,7 +2410,7 @@ }, { "c": "(", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.selector.objc punctuation.definition.storage.type.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.selector.objc punctuation.definition.storage.type.objc", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2377,7 +2421,7 @@ }, { "c": "handleTap:", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.selector.objc meta.selector.method-name.objc support.function.any-method.name-of-parameter.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.selector.objc meta.selector.method-name.objc support.function.any-method.name-of-parameter.objc", "r": { "dark_plus": "support.function: #DCDCAA", "light_plus": "support.function: #795E26", @@ -2388,7 +2432,7 @@ }, { "c": ")", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.selector.objc punctuation.definition.storage.type.objc", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c meta.selector.objc punctuation.definition.storage.type.objc", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2399,7 +2443,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2498,7 +2542,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2509,7 +2553,7 @@ }, { "c": "NSMutableArray", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c support.class.cocoa", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c support.class.cocoa", "r": { "dark_plus": "support.class: #4EC9B0", "light_plus": "support.class: #267F99", @@ -2520,7 +2564,7 @@ }, { "c": " array", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2531,7 +2575,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2564,7 +2608,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2575,7 +2619,7 @@ }, { "c": "gestureRecognizers addObject:tapGesture", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2586,7 +2630,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2619,7 +2663,7 @@ }, { "c": "[", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.begin.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.begin.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2629,8 +2673,8 @@ } }, { - "c": "gestureRecognizers addObjectsFromArray:scnView", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", + "c": "gestureRecognizers addObjectsFromArray:", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2639,20 +2683,31 @@ "hc_black": "default: #FFFFFF" } }, + { + "c": "scnView", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c variable.object.access.c variable.object.c", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" + } + }, { "c": ".", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.dot-access.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c variable.object.access.c punctuation.separator.dot-access.c", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" } }, { "c": "gestureRecognizers", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.other.member.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c variable.object.access.c variable.other.member.c", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", @@ -2663,7 +2718,7 @@ }, { "c": "]", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.definition.end.bracket.square.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c meta.bracket.square.access.c punctuation.definition.end.bracket.square.c", "r": { "dark_plus": "default: #D4D4D4", "light_plus": "default: #000000", @@ -2684,7 +2739,7 @@ } }, { - "c": " scnView", + "c": " ", "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c", "r": { "dark_plus": "default: #D4D4D4", @@ -2695,19 +2750,30 @@ } }, { - "c": ".", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c punctuation.separator.dot-access.c", + "c": "scnView", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.object.access.c variable.object.c", "r": { - "dark_plus": "default: #D4D4D4", - "light_plus": "default: #000000", + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", "dark_vs": "default: #D4D4D4", "light_vs": "default: #000000", - "hc_black": "default: #FFFFFF" + "hc_black": "variable: #9CDCFE" + } + }, + { + "c": ".", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.object.access.c punctuation.separator.dot-access.c", + "r": { + "dark_plus": "variable: #9CDCFE", + "light_plus": "variable: #001080", + "dark_vs": "default: #D4D4D4", + "light_vs": "default: #000000", + "hc_black": "variable: #9CDCFE" } }, { "c": "gestureRecognizers", - "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.other.member.c", + "t": "source.objc meta.implementation.objc meta.scope.implementation.objc meta.function-with-body.objc meta.block.c variable.object.access.c variable.other.member.c", "r": { "dark_plus": "variable: #9CDCFE", "light_plus": "variable: #001080", From 489dfec1e94fcce83f165351f1b0f840d8b60104 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 11:18:23 +0100 Subject: [PATCH 106/290] fix #69141 --- src/vs/code/electron-main/main.ts | 2 +- .../common/instantiationService.ts | 29 +++++++++++++- .../node/instantiationService.ts | 39 ------------------- src/vs/workbench/electron-browser/main.ts | 2 +- 4 files changed, 29 insertions(+), 43 deletions(-) delete mode 100644 src/vs/platform/instantiation/node/instantiationService.ts diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 49668099824..f89af11d2aa 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -16,7 +16,7 @@ import { LifecycleService, ILifecycleService } from 'vs/platform/lifecycle/elect import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net'; import { LaunchChannelClient } from 'vs/platform/launch/electron-main/launchService'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { InstantiationService } from 'vs/platform/instantiation/node/instantiationService'; +import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ILogService, ConsoleLogMainService, MultiplexLogService, getLogLevel } from 'vs/platform/log/common/log'; diff --git a/src/vs/platform/instantiation/common/instantiationService.ts b/src/vs/platform/instantiation/common/instantiationService.ts index 231666949c4..a0141e4853f 100644 --- a/src/vs/platform/instantiation/common/instantiationService.ts +++ b/src/vs/platform/instantiation/common/instantiationService.ts @@ -9,10 +9,17 @@ import { Graph } from 'vs/platform/instantiation/common/graph'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ServiceIdentifier, IInstantiationService, ServicesAccessor, _util, optional } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { IdleValue } from 'vs/base/common/async'; // TRACING const _enableTracing = false; +// PROXY +// Ghetto-declare of the global Proxy object. This isn't the proper way +// but allows us to run this code in the browser without IE11. +declare var Proxy: any; +const _canUseProxy = typeof Proxy === 'function'; + export class InstantiationService implements IInstantiationService { _serviceBrand: any; @@ -205,8 +212,26 @@ export class InstantiationService implements IInstantiationService { } } - protected _createServiceInstance(ctor: any, args: any[] = [], _supportsDelayedInstantiation: boolean, _trace: Trace): T { - return this._createInstance(ctor, args, _trace); + private _createServiceInstance(ctor: any, args: any[] = [], _supportsDelayedInstantiation: boolean, _trace: Trace): T { + if (!_supportsDelayedInstantiation || !_canUseProxy) { + // eager instantiation or no support JS proxies (e.g. IE11) + return this._createInstance(ctor, args, _trace); + + } else { + // Return a proxy object that's backed by an idle value. That + // strategy is to instantiate services in our idle time or when actually + // needed but not when injected into a consumer + const idle = new IdleValue(() => this._createInstance(ctor, args, _trace)); + return new Proxy(Object.create(null), { + get(_target: T, prop: PropertyKey): any { + return idle.getValue()[prop]; + }, + set(_target: T, p: PropertyKey, value: any): boolean { + idle.getValue()[p] = value; + return true; + } + }); + } } } diff --git a/src/vs/platform/instantiation/node/instantiationService.ts b/src/vs/platform/instantiation/node/instantiationService.ts deleted file mode 100644 index c888491b365..00000000000 --- a/src/vs/platform/instantiation/node/instantiationService.ts +++ /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. - *--------------------------------------------------------------------------------------------*/ -import { IdleValue } from 'vs/base/common/async'; -import { InstantiationService as BaseInstantiationService } from 'vs/platform/instantiation/common/instantiationService'; -import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; - -// this is in the /node/-layer because it depends on Proxy which isn't available -// in IE11 and therefore not in the /common/-layer - -export class InstantiationService extends BaseInstantiationService { - - createChild(services: ServiceCollection): IInstantiationService { - return new InstantiationService(services, this._strict, this); - } - - protected _createServiceInstance(ctor: any, args: any[] = [], supportsDelayedInstantiation: boolean, _trace): T { - if (supportsDelayedInstantiation) { - return InstantiationService._newIdleProxyService(() => super._createServiceInstance(ctor, args, supportsDelayedInstantiation, _trace)); - } else { - return super._createServiceInstance(ctor, args, supportsDelayedInstantiation, _trace); - } - } - - private static _newIdleProxyService(executor: () => T): T { - const idle = new IdleValue(executor); - return new Proxy(Object.create(null), { - get(_target: T, prop: PropertyKey): any { - return idle.getValue()[prop]; - }, - set(_target: T, p: PropertyKey, value: any): boolean { - idle.getValue()[p] = value; - return true; - } - }); - } -} diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 518080ab90d..258e2733a3f 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -47,7 +47,7 @@ import { GlobalStorageDatabaseChannelClient } from 'vs/platform/storage/node/sto import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { InstantiationService } from 'vs/platform/instantiation/node/instantiationService'; +import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { Disposable } from 'vs/base/common/lifecycle'; import { registerWindowDriver } from 'vs/platform/driver/electron-browser/driver'; From a731d2e28887c3df4763510400dcd6c2952dcb0e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 11:31:50 +0100 Subject: [PATCH 107/290] debt - move more services to use registerSingleton() --- .../workbench/electron-browser/workbench.ts | 31 +------------------ .../configuration/node/jsonEditingService.ts | 3 ++ .../dialogs/electron-browser/dialogService.ts | 6 +++- .../preferences/browser/preferencesService.ts | 3 ++ .../textfile/common/textFileService.ts | 3 ++ .../common/textModelResolverService.ts | 3 ++ src/vs/workbench/workbench.main.ts | 5 +++ 7 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 7aaab4a467a..4267b0ceed9 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -38,7 +38,6 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { ContextMenuService as HTMLContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -51,10 +50,6 @@ import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; -import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; -import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; -import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { LifecyclePhase, StartupKind, ILifecycleService, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle'; import { IWindowService, IWindowConfiguration, IPath, MenuBarVisibility, getTitleBarStyle, IWindowsService } from 'vs/platform/windows/common/windows'; @@ -71,14 +66,11 @@ 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 { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; -import { PreferencesService } from 'vs/workbench/services/preferences/browser/preferencesService'; import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { EditorService } from 'vs/workbench/services/editor/browser/editorService'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; -import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { Sizing, Direction, Grid, View } from 'vs/base/browser/ui/grid/grid'; import { IEditor } from 'vs/editor/common/editorCommon'; import { WorkbenchLayout } from 'vs/workbench/browser/layout'; @@ -116,7 +108,6 @@ import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; // import@node import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; -import { JSONEditingService } from 'vs/workbench/services/configuration/node/jsonEditingService'; import { getDelayedChannel } from 'vs/base/parts/ipc/node/ipc'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc'; @@ -140,7 +131,6 @@ import { RemoteFileService } from 'vs/workbench/services/files/node/remoteFileSe import { ContextMenuService as NativeContextMenuService } from 'vs/workbench/services/contextmenu/electron-browser/contextmenuService'; import { WorkbenchKeybindingService } from 'vs/workbench/services/keybinding/electron-browser/keybindingService'; import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; -import { DialogService, FileDialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService'; import { WindowService } from 'vs/platform/windows/electron-browser/windowService'; import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; @@ -412,13 +402,9 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(ITelemetryService, this.telemetryService); this._register(configurationTelemetry(this.telemetryService, this.configurationService)); - // Dialogs - serviceCollection.set(IDialogService, new SyncDescriptor(DialogService, undefined, true)); - // Lifecycle this.lifecycleService = this.instantiationService.createInstance(LifecycleService); serviceCollection.set(ILifecycleService, this.lifecycleService); - this._register(this.lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event))); this._register(this.lifecycleService.onShutdown(() => { this._onShutdown.fire(); @@ -456,7 +442,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IExtensionEnablementService, new SyncDescriptor(ExtensionEnablementService, undefined, true)); // Extensions - serviceCollection.set(IExtensionService, this.instantiationService.createInstance(ExtensionService)); + serviceCollection.set(IExtensionService, new SyncDescriptor(ExtensionService)); // Theming this.themeService = this.instantiationService.createInstance(WorkbenchThemeService, document.body); @@ -546,9 +532,6 @@ export class Workbench extends Disposable implements IPartService { // History serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService)); - // File Dialogs - serviceCollection.set(IFileDialogService, new SyncDescriptor(FileDialogService, undefined, true)); - // Backup File Service if (this.configuration.backupPath) { this.backupFileService = this.instantiationService.createInstance(BackupFileService, this.configuration.backupPath); @@ -557,15 +540,6 @@ export class Workbench extends Disposable implements IPartService { } serviceCollection.set(IBackupFileService, this.backupFileService); - // Text File Service - serviceCollection.set(ITextFileService, new SyncDescriptor(TextFileService)); - - // Text Model Resolver Service - serviceCollection.set(ITextModelService, new SyncDescriptor(TextModelResolverService, undefined, true)); - - // JSON Editing - serviceCollection.set(IJSONEditingService, new SyncDescriptor(JSONEditingService, undefined, true)); - // Quick open service (quick open controller) this.quickOpen = this.instantiationService.createInstance(QuickOpenController); serviceCollection.set(IQuickOpenService, this.quickOpen); @@ -574,9 +548,6 @@ export class Workbench extends Disposable implements IPartService { this.quickInput = this.instantiationService.createInstance(QuickInputService); serviceCollection.set(IQuickInputService, this.quickInput); - // PreferencesService - serviceCollection.set(IPreferencesService, new SyncDescriptor(PreferencesService)); - // Contributed services const contributedServices = getServices(); for (let contributedService of contributedServices) { diff --git a/src/vs/workbench/services/configuration/node/jsonEditingService.ts b/src/vs/workbench/services/configuration/node/jsonEditingService.ts index c02b276b524..838bd333dd0 100644 --- a/src/vs/workbench/services/configuration/node/jsonEditingService.ts +++ b/src/vs/workbench/services/configuration/node/jsonEditingService.ts @@ -20,6 +20,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { IJSONEditingService, IJSONValue, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing'; import { ITextModel } from 'vs/editor/common/model'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class JSONEditingService implements IJSONEditingService { @@ -131,3 +132,5 @@ export class JSONEditingService implements IJSONEditingService { } } } + +registerSingleton(IJSONEditingService, JSONEditingService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts b/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts index cec0ec1ff07..bf501e161f9 100644 --- a/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts +++ b/src/vs/workbench/services/dialogs/electron-browser/dialogService.ts @@ -22,6 +22,7 @@ import { RemoteFileDialog } from 'vs/workbench/services/dialogs/electron-browser import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; interface IMassagedMessageBoxOptions { @@ -388,4 +389,7 @@ export class FileDialogService implements IFileDialogService { function isUntitledWorkspace(path: URI, environmentService: IEnvironmentService): boolean { return resources.isEqualOrParent(path, environmentService.untitledWorkspacesHome); -} \ No newline at end of file +} + +registerSingleton(IFileDialogService, FileDialogService, true); +registerSingleton(IDialogService, DialogService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 9646b53859d..e5cd0c64ab7 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -36,6 +36,7 @@ import { GroupDirection, IEditorGroup, IEditorGroupsService } from 'vs/workbench import { DEFAULT_SETTINGS_EDITOR_SETTING, FOLDER_SETTINGS_PATH, getSettingsTargetName, IPreferencesEditorModel, IPreferencesService, ISetting, ISettingsEditorOptions, SettingsEditorOptions, USE_SPLIT_JSON_SETTING } from 'vs/workbench/services/preferences/common/preferences'; import { DefaultPreferencesEditorInput, KeybindingsEditorInput, PreferencesEditorInput, SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { defaultKeybindingsContents, DefaultKeybindingsEditorModel, DefaultSettings, DefaultSettingsEditorModel, Settings2EditorModel, SettingsEditorModel, WorkspaceConfigurationEditorModel, DefaultRawSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; const emptyEditableSettingsContent = '{\n}'; @@ -590,3 +591,5 @@ export class PreferencesService extends Disposable implements IPreferencesServic super.dispose(); } } + +registerSingleton(IPreferencesService, PreferencesService); \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 5d98f0e093a..6504cd43b20 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -37,6 +37,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { coalesce } from 'vs/base/common/arrays'; import { trim } from 'vs/base/common/strings'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export interface IBackupResult { didBackup: boolean; @@ -978,3 +979,5 @@ export class TextFileService extends Disposable implements ITextFileService { super.dispose(); } } + +registerSingleton(ITextFileService, TextFileService); \ No newline at end of file diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index 3b011295c08..1c6388a5929 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -16,6 +16,7 @@ import { ITextModelService, ITextModelContentProvider, ITextEditorModel } from ' import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { IFileService } from 'vs/platform/files/common/files'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; class ResourceModelCollection extends ReferenceCollection> { @@ -171,3 +172,5 @@ export class TextModelResolverService implements ITextModelService { return this.resourceModelCollection.hasTextModelContentProvider(scheme); } } + +registerSingleton(ITextModelService, TextModelResolverService, true); \ No newline at end of file diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 178d700f976..3320291414a 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -68,6 +68,11 @@ import 'vs/workbench/services/search/node/searchService'; import 'vs/workbench/services/progress/browser/progressService2'; import 'vs/workbench/services/editor/browser/codeEditorService'; import 'vs/workbench/services/broadcast/electron-browser/broadcastService'; +import 'vs/workbench/services/preferences/browser/preferencesService'; +import 'vs/workbench/services/configuration/node/jsonEditingService'; +import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; +import 'vs/workbench/services/textfile/common/textFileService'; +import 'vs/workbench/services/dialogs/electron-browser/dialogService'; registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); From 5518580b308017d62f3e95a19a54edb53114eabb Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Mon, 4 Mar 2019 02:42:14 -0800 Subject: [PATCH 108/290] Make list.inactiveFocusBackground null by default (#69673) --- 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 0f0914915ba..6a74d3719ec 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -227,7 +227,7 @@ export const listActiveSelectionBackground = registerColor('list.activeSelection export const listActiveSelectionForeground = registerColor('list.activeSelectionForeground', { dark: Color.white, light: Color.white, hc: null }, nls.localize('listActiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is active. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionBackground = registerColor('list.inactiveSelectionBackground', { dark: '#37373D', light: '#E4E6F1', hc: null }, nls.localize('listInactiveSelectionBackground', "List/Tree background color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); export const listInactiveSelectionForeground = registerColor('list.inactiveSelectionForeground', { dark: null, light: null, hc: null }, nls.localize('listInactiveSelectionForeground', "List/Tree foreground color for the selected item when the list/tree is inactive. An active list/tree has keyboard focus, an inactive does not.")); -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 listInactiveFocusBackground = registerColor('list.inactiveFocusBackground', { dark: null, light: null, 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.")); export const listHoverForeground = registerColor('list.hoverForeground', { dark: null, light: null, hc: null }, nls.localize('listHoverForeground', "List/Tree foreground when hovering over items using the mouse.")); 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.")); From 265644d08a061e500fa7cfbb275b5673663277b8 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 11:45:19 +0100 Subject: [PATCH 109/290] debt - use our assert util --- src/vs/workbench/api/node/extHostDocumentsAndEditors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts index 0455b24ecbf..57868da0161 100644 --- a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as assert from 'assert'; +import * as assert from 'vs/base/common/assert'; import { Emitter, Event } from 'vs/base/common/event'; import { dispose } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; From ca0b1b38b020a63e2b6908da8a21814fe320edd7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 11:46:34 +0100 Subject: [PATCH 110/290] debt - make target location optional and let service decide --- src/vs/platform/download/common/download.ts | 4 ++-- src/vs/platform/download/node/downloadIpc.ts | 12 +++++++----- src/vs/platform/download/node/downloadService.ts | 11 +++++++---- src/vs/workbench/api/node/apiCommands.ts | 9 ++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vs/platform/download/common/download.ts b/src/vs/platform/download/common/download.ts index 9856da753ee..83bd30bdaa5 100644 --- a/src/vs/platform/download/common/download.ts +++ b/src/vs/platform/download/common/download.ts @@ -13,6 +13,6 @@ export interface IDownloadService { _serviceBrand: any; - download(uri: URI, to: string, cancellationToken?: CancellationToken): Promise; + download(uri: URI, to?: string, cancellationToken?: CancellationToken): Promise; -} \ No newline at end of file +} diff --git a/src/vs/platform/download/node/downloadIpc.ts b/src/vs/platform/download/node/downloadIpc.ts index 53144c3f1db..52ca30256fe 100644 --- a/src/vs/platform/download/node/downloadIpc.ts +++ b/src/vs/platform/download/node/downloadIpc.ts @@ -11,6 +11,8 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IDownloadService } from 'vs/platform/download/common/download'; import { mkdirp } from 'vs/base/node/pfs'; import { IURITransformer } from 'vs/base/common/uriIpc'; +import { tmpdir } from 'os'; +import { generateUuid } from 'vs/base/common/uuid'; export type UploadResponse = Buffer | string | undefined; @@ -46,21 +48,21 @@ export class DownloadServiceChannelClient implements IDownloadService { constructor(private channel: IChannel, private getUriTransformer: () => IURITransformer) { } - download(from: URI, to: string): Promise { + download(from: URI, to: string = path.join(tmpdir(), generateUuid())): Promise { from = this.getUriTransformer().transformOutgoingURI(from); const dirName = path.dirname(to); let out: fs.WriteStream; - return new Promise((c, e) => { + return new Promise((c, e) => { return mkdirp(dirName) .then(() => { out = fs.createWriteStream(to); - out.once('close', () => c()); + out.once('close', () => c(to)); out.once('error', e); const uploadStream = this.channel.listen('upload', from); const disposable = uploadStream(result => { if (result === undefined) { disposable.dispose(); - out.end(c); + out.end(() => c(to)); } else if (Buffer.isBuffer(result)) { out.write(result); } else if (typeof result === 'string') { @@ -71,4 +73,4 @@ export class DownloadServiceChannelClient implements IDownloadService { }); }); } -} \ No newline at end of file +} diff --git a/src/vs/platform/download/node/downloadService.ts b/src/vs/platform/download/node/downloadService.ts index c20cbd1a8d5..7822ed2253d 100644 --- a/src/vs/platform/download/node/downloadService.ts +++ b/src/vs/platform/download/node/downloadService.ts @@ -10,6 +10,9 @@ import { copy } from 'vs/base/node/pfs'; import { IRequestService } from 'vs/platform/request/node/request'; import { asText, download } from 'vs/base/node/request'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { join } from 'vs/base/common/path'; +import { tmpdir } from 'os'; +import { generateUuid } from 'vs/base/common/uuid'; export class DownloadService implements IDownloadService { @@ -19,18 +22,18 @@ export class DownloadService implements IDownloadService { @IRequestService private readonly requestService: IRequestService ) { } - download(uri: URI, target: string, cancellationToken: CancellationToken = CancellationToken.None): Promise { + download(uri: URI, target: string = join(tmpdir(), generateUuid()), cancellationToken: CancellationToken = CancellationToken.None): Promise { if (uri.scheme === Schemas.file) { - return copy(uri.fsPath, target); + return copy(uri.fsPath, target).then(() => target); } const options = { type: 'GET', url: uri.toString() }; return this.requestService.request(options, cancellationToken) .then(context => { if (context.res.statusCode === 200) { - return download(target, context); + return download(target, context).then(() => target); } return asText(context) .then(message => Promise.reject(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/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index f2cc8adc5a6..8f748f3efb6 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { tmpdir } from 'os'; -import { join } from 'vs/base/common/path'; import * as vscode from 'vscode'; import { URI } from 'vs/base/common/uri'; import { isMalformedFileUri } from 'vs/base/common/resources'; @@ -17,7 +15,6 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IDownloadService } from 'vs/platform/download/common/download'; -import { generateUuid } from 'vs/base/common/uuid'; // ----------------------------------------------------------------- // The following commands are registered on both sides separately. @@ -158,7 +155,5 @@ CommandsRegistry.registerCommand({ CommandsRegistry.registerCommand('_workbench.downloadResource', function (accessor: ServicesAccessor, resource: URI) { const downloadService = accessor.get(IDownloadService); - const location = join(tmpdir(), generateUuid()); - - return downloadService.download(resource, location).then(() => URI.file(location)); -}); \ No newline at end of file + return downloadService.download(resource).then(location => URI.file(location)); +}); From 472a1abbe22fc1895c200d3c55dd63c35ce3eb52 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 4 Mar 2019 12:06:55 +0100 Subject: [PATCH 111/290] fixes #69667 --- src/vs/workbench/contrib/outline/browser/outlinePanel.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index 0df0b100107..86d3df7c5ea 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -522,8 +522,6 @@ export class OutlinePanel extends ViewletPanel { await this._tree.setInput(newModel, state); } - this._tree.layout(); - // transfer focus from domNode to the tree if (this._domNode === document.activeElement) { this._tree.domFocus(); From 88c1f67f64d2a29dd323b172e0156c7bf813ad8b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 4 Mar 2019 11:09:52 +0000 Subject: [PATCH 112/290] Move watermark to 'browser' (fixes #69117) --- .../watermark/{electron-browser => browser}/watermark.css | 0 .../watermark/{electron-browser => browser}/watermark.ts | 7 ++++--- src/vs/workbench/workbench.main.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) rename src/vs/workbench/contrib/watermark/{electron-browser => browser}/watermark.css (100%) rename src/vs/workbench/contrib/watermark/{electron-browser => browser}/watermark.ts (97%) diff --git a/src/vs/workbench/contrib/watermark/electron-browser/watermark.css b/src/vs/workbench/contrib/watermark/browser/watermark.css similarity index 100% rename from src/vs/workbench/contrib/watermark/electron-browser/watermark.css rename to src/vs/workbench/contrib/watermark/browser/watermark.css diff --git a/src/vs/workbench/contrib/watermark/electron-browser/watermark.ts b/src/vs/workbench/contrib/watermark/browser/watermark.ts similarity index 97% rename from src/vs/workbench/contrib/watermark/electron-browser/watermark.ts rename to src/vs/workbench/contrib/watermark/browser/watermark.ts index 6e7a0f9f557..b82746b3d30 100644 --- a/src/vs/workbench/contrib/watermark/electron-browser/watermark.ts +++ b/src/vs/workbench/contrib/watermark/browser/watermark.ts @@ -15,7 +15,6 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { OpenRecentAction } from 'vs/workbench/electron-browser/actions/windowActions'; import { GlobalNewUntitledFileAction } from 'vs/workbench/contrib/files/browser/fileActions'; import { OpenFolderAction, OpenFileFolderAction, OpenFileAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ShowAllCommandsAction } from 'vs/workbench/contrib/quickopen/browser/commandsHandler'; @@ -27,6 +26,7 @@ import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/termin import * as dom from 'vs/base/browser/dom'; import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; const $ = dom.$; @@ -61,7 +61,7 @@ const openFileOrFolderMacOnly: WatermarkEntry = { }; const openRecent: WatermarkEntry = { text: nls.localize('watermark.openRecent', "Open Recent"), - id: OpenRecentAction.ID + id: 'workbench.action.openRecent' }; const newUntitledFile: WatermarkEntry = { text: nls.localize('watermark.newUntitledFile', "New Untitled File"), @@ -157,7 +157,8 @@ export class WatermarkContribution implements IWorkbenchContribution { const box = dom.append(this.watermark, $('.watermark-box')); const folder = this.workbenchState !== WorkbenchState.EMPTY; const selected = folder ? folderEntries : noFolderEntries - .filter(entry => !('mac' in entry) || entry.mac === isMacintosh); + .filter(entry => !('mac' in entry) || entry.mac === isMacintosh) + .filter(entry => !!CommandsRegistry.getCommand(entry.id)); const update = () => { dom.clearNode(box); selected.map(entry => { diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 3320291414a..0c3e4e534c6 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -204,7 +204,7 @@ import 'vs/workbench/contrib/themes/browser/themes.contribution'; import 'vs/workbench/contrib/themes/test/electron-browser/themes.test.contribution'; // Watermark -import 'vs/workbench/contrib/watermark/electron-browser/watermark'; +import 'vs/workbench/contrib/watermark/browser/watermark'; // Welcome import 'vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThrough.contribution'; From d2239c2473fda8ae7898f75a453f8a9eb0fdad1d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 12:21:17 +0100 Subject: [PATCH 113/290] uris without scheme and without strict-parse fallback to the file-scheme, #66802 --- src/vs/base/common/uri.ts | 17 ++++++++++++++++- src/vs/vscode.d.ts | 7 ++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 29524b9d7f0..80941c5c1d3 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -56,6 +56,21 @@ function _validateUri(ret: URI, _strict?: boolean): void { } } +// for a while we allowed uris *without* schemes and this is the migration +// for them, e.g. an uri without scheme and without strict-mode warns and falls +// back to the file-scheme. that should cause the least carnage and still be a +// clear warning +function _schemeFix(scheme: string, _strict: boolean): string { + if (_strict || _throwOnMissingSchema) { + return scheme || _empty; + } + if (!scheme) { + console.trace('BAD uri lacks scheme, falling back to file-scheme.'); + scheme = 'file'; + } + return scheme; +} + // implements a bit of https://tools.ietf.org/html/rfc3986#section-5 function _referenceResolution(scheme: string, path: string): string { @@ -166,7 +181,7 @@ export class URI implements UriComponents { // that creates uri components. // _validateUri(this); } else { - this.scheme = schemeOrData || _empty; + this.scheme = _schemeFix(schemeOrData, _strict); this.authority = authority || _empty; this.path = _referenceResolution(this.scheme, path || _empty); this.query = query || _empty; diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 9305f29a4c3..1b773f2da31 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -1235,11 +1235,16 @@ declare module 'vscode' { * Create an URI from a string, e.g. `http://www.msft.com/some/path`, * `file:///usr/home`, or `scheme:with/path`. * + * *Note* that for a while uris without a `scheme` were accepted. That is not correct + * as all uris should have a scheme. To avoid breakage of existing code the optional + * `strict`-argument has been added. We *strongly* advise to use it, e.g. `Uri.parse('my:uri', true)` + * * @see [Uri.toString](#Uri.toString) * @param value The string value of an Uri. + * @param strict Throw an error when `value` is empty or when no `scheme` can be parsed. * @return A new Uri instance. */ - static parse(value: string): Uri; + static parse(value: string, strict?: boolean): Uri; /** * Create an URI from a file system path. The [scheme](#Uri.scheme) From 64f715b1e9ff96ada348bfd3947231e0305be5cb Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 12:35:11 +0100 Subject: [PATCH 114/290] move registerActions to common/action.ts, #69036 --- src/vs/platform/actions/common/actions.ts | 64 ++++++++++++++++++- .../markers/browser/markers.contribution.ts | 63 +----------------- 2 files changed, 64 insertions(+), 63 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index ead87925df7..e615685b30b 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -6,9 +6,9 @@ import { Action } from 'vs/base/common/actions'; import { SyncDescriptor0, createSyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IConstructorSignature2, createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ICommandService, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IDisposable } from 'vs/base/common/lifecycle'; import { Event, Emitter } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; @@ -321,3 +321,63 @@ export class SyncActionDescriptor { return this._keybindingWeight; } } + + +export interface IActionDescriptor { + id: string; + handler: ICommandHandler; + + // ICommandUI + title?: ILocalizedString; + category?: string; + f1?: boolean; + + // + menu?: { + menuId: MenuId, + when?: ContextKeyExpr; + group?: string; + }; + + // + keybinding?: { + when?: ContextKeyExpr; + weight?: number; + keys: IKeybindings; + }; +} + + +export function registerAction(desc: IActionDescriptor) { + + const { id, handler, title, category, menu, keybinding } = desc; + + // 1) register as command + CommandsRegistry.registerCommand(id, handler); + + // 2) menus + if (menu && title) { + let command = { id, title, category }; + let { menuId, when, group } = menu; + MenuRegistry.appendMenuItem(menuId, { + command, + when, + group + }); + } + + // 3) keybindings + if (keybinding) { + let { when, weight, keys } = keybinding; + KeybindingsRegistry.registerKeybindingRule({ + id, + when, + weight: weight || 0, + primary: keys.primary, + secondary: keys.secondary, + linux: keys.linux, + mac: keys.mac, + win: keys.win + }); + } +} diff --git a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts index 2176ac7a9ef..5bd59feaed1 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts @@ -4,17 +4,16 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/workbench/contrib/markers/browser/markersFileDecorations'; -import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { KeybindingsRegistry, KeybindingWeight, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { localize } from 'vs/nls'; import { Marker, RelatedInformation } from 'vs/workbench/contrib/markers/browser/markersModel'; import { MarkersPanel } from 'vs/workbench/contrib/markers/browser/markersPanel'; -import { MenuId, MenuRegistry, SyncActionDescriptor, ILocalizedString } from 'vs/platform/actions/common/actions'; +import { MenuId, MenuRegistry, SyncActionDescriptor, registerAction } from 'vs/platform/actions/common/actions'; import { PanelRegistry, Extensions as PanelExtensions, PanelDescriptor } from 'vs/workbench/browser/panel'; import { Registry } from 'vs/platform/registry/common/platform'; import { ToggleMarkersPanelAction, ShowProblemsPanelAction } from 'vs/workbench/contrib/markers/browser/markersPanelActions'; @@ -246,64 +245,6 @@ function focusProblemsFilter(panelService: IPanelService) { } } -interface IActionDescriptor { - id: string; - handler: ICommandHandler; - - // ICommandUI - title?: ILocalizedString; - category?: string; - f1?: boolean; - - // - menu?: { - menuId: MenuId, - when?: ContextKeyExpr; - group?: string; - }; - - // - keybinding?: { - when?: ContextKeyExpr; - weight?: number; - keys: IKeybindings; - }; -} - -function registerAction(desc: IActionDescriptor) { - - const { id, handler, title, category, menu, keybinding } = desc; - - // 1) register as command - CommandsRegistry.registerCommand(id, handler); - - // 2) menus - let command = { id, title, category }; - if (menu) { - let { menuId, when, group } = menu; - MenuRegistry.appendMenuItem(menuId, { - command, - when, - group - }); - } - - // 3) keybindings - if (keybinding) { - let { when, weight, keys } = keybinding; - KeybindingsRegistry.registerKeybindingRule({ - id, - when, - weight, - primary: keys.primary, - secondary: keys.secondary, - linux: keys.linux, - mac: keys.mac, - win: keys.win - }); - } -} - MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { group: '4_panels', command: { From fc1c69ccafd62b3e88ec56d13c8815d80c8fb07b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 12:37:43 +0100 Subject: [PATCH 115/290] strict null trouble --- src/vs/base/common/uri.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 80941c5c1d3..8fbecabfd80 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -169,7 +169,7 @@ export class URI implements UriComponents { /** * @internal */ - protected constructor(schemeOrData: string | UriComponents, authority?: string, path?: string, query?: string, fragment?: string, _strict?: boolean) { + protected constructor(schemeOrData: string | UriComponents, authority?: string, path?: string, query?: string, fragment?: string, _strict: boolean = false) { if (typeof schemeOrData === 'object') { this.scheme = schemeOrData.scheme || _empty; From 61d7bc4b265e64d3b2129bc104d940df21f7b148 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 12:40:01 +0100 Subject: [PATCH 116/290] adopt shared registerAction-function, #69036 --- .../electron-browser/output.contribution.ts | 68 +------------------ 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts b/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts index d759e524208..e217ba7ab9e 100644 --- a/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts +++ b/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts @@ -7,16 +7,13 @@ import * as nls from 'vs/nls'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry'; import { Registry } from 'vs/platform/registry/common/platform'; -import { MenuId, MenuRegistry, SyncActionDescriptor, ILocalizedString } from 'vs/platform/actions/common/actions'; -import { KeybindingsRegistry, IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { MenuId, MenuRegistry, SyncActionDescriptor, registerAction } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { OutputService, LogContentProvider } from 'vs/workbench/contrib/output/electron-browser/outputServices'; import { ToggleOutputAction, ClearOutputAction, OpenLogOutputFile, ShowLogsOutputChannelAction, OpenOutputLogFileAction } from 'vs/workbench/contrib/output/browser/outputActions'; import { OUTPUT_MODE_ID, OUTPUT_MIME, OUTPUT_PANEL_ID, IOutputService, CONTEXT_IN_OUTPUT, LOG_SCHEME, LOG_MODE_ID, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT } from 'vs/workbench/contrib/output/common/output'; import { PanelRegistry, Extensions, PanelDescriptor } from 'vs/workbench/browser/panel'; -import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { OutputPanel } from 'vs/workbench/contrib/output/browser/outputPanel'; import { IEditorRegistry, Extensions as EditorExtensions, EditorDescriptor } from 'vs/workbench/browser/editor'; import { LogViewer, LogViewerInput } from 'vs/workbench/contrib/output/browser/logViewer'; @@ -93,69 +90,6 @@ const devCategory = nls.localize('developer', "Developer"); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ShowLogsOutputChannelAction, ShowLogsOutputChannelAction.ID, ShowLogsOutputChannelAction.LABEL), 'Developer: Show Logs...', devCategory); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenOutputLogFileAction, OpenOutputLogFileAction.ID, OpenOutputLogFileAction.LABEL), 'Developer: Open Log File...', devCategory); -interface IActionDescriptor { - id: string; - handler: ICommandHandler; - - // ICommandUI - title: ILocalizedString; - category?: string; - f1?: boolean; - - // menus - menu?: { - menuId: MenuId, - when?: ContextKeyExpr; - group?: string; - }; - - // keybindings - keybinding?: { - when?: ContextKeyExpr; - weight: number; - keys: IKeybindings; - }; -} - -function registerAction(desc: IActionDescriptor) { - - const { id, handler, title, category, f1, menu, keybinding } = desc; - - // 1) register as command - CommandsRegistry.registerCommand(id, handler); - - // 2) command palette - let command = { id, title, category }; - if (f1) { - MenuRegistry.addCommand(command); - } - - // 3) menus - if (menu) { - let { menuId, when, group } = menu; - MenuRegistry.appendMenuItem(menuId, { - command, - when, - group - }); - } - - // 4) keybindings - if (keybinding) { - let { when, weight, keys } = keybinding; - KeybindingsRegistry.registerKeybindingRule({ - id, - when, - weight, - primary: keys.primary, - secondary: keys.secondary, - linux: keys.linux, - mac: keys.mac, - win: keys.win - }); - } -} - // Define clear command, contribute to editor context menu registerAction({ id: 'editor.action.clearoutput', From ceb8d830f88e516ff7074127189ef01497b2feb2 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 4 Mar 2019 11:42:12 +0000 Subject: [PATCH 117/290] Move welcome page and walkthrough to 'common' and 'browser' (#69116) --- .../{electron-browser => common}/extensionsUtils.ts | 6 ------ .../electron-browser/extensionTipsService.ts | 4 ++-- .../electron-browser/extensions.contribution.ts | 2 +- .../extensions/electron-browser/extensionsViews.ts | 5 +++-- .../vs_code_welcome_page.ts | 0 .../welcomePage.contribution.ts | 2 +- .../page/{electron-browser => browser}/welcomePage.css | 0 .../page/{electron-browser => browser}/welcomePage.ts | 10 +++++----- .../editor/editorWalkThrough.ts | 2 +- .../editor/vs_code_editor_walkthrough.md | 0 .../walkThrough.contribution.ts | 10 +++++----- .../walkThroughActions.ts | 2 +- .../{electron-browser => browser}/walkThroughPart.css | 0 .../{electron-browser => browser}/walkThroughPart.ts | 4 ++-- .../{node => common}/walkThroughContentProvider.ts | 0 .../walkThrough/{node => common}/walkThroughInput.ts | 0 .../walkThrough/{node => common}/walkThroughUtils.ts | 0 .../test/electron-browser/colorRegistry.releaseTest.ts | 4 ++-- src/vs/workbench/workbench.main.ts | 4 ++-- 19 files changed, 25 insertions(+), 30 deletions(-) rename src/vs/workbench/contrib/extensions/{electron-browser => common}/extensionsUtils.ts (96%) rename src/vs/workbench/contrib/welcome/page/{electron-browser => browser}/vs_code_welcome_page.ts (100%) rename src/vs/workbench/contrib/welcome/page/{electron-browser => browser}/welcomePage.contribution.ts (97%) rename src/vs/workbench/contrib/welcome/page/{electron-browser => browser}/welcomePage.css (100%) rename src/vs/workbench/contrib/welcome/page/{electron-browser => browser}/welcomePage.ts (99%) rename src/vs/workbench/contrib/welcome/walkThrough/{electron-browser => browser}/editor/editorWalkThrough.ts (97%) rename src/vs/workbench/contrib/welcome/walkThrough/{electron-browser => browser}/editor/vs_code_editor_walkthrough.md (100%) rename src/vs/workbench/contrib/welcome/walkThrough/{electron-browser => browser}/walkThrough.contribution.ts (91%) rename src/vs/workbench/contrib/welcome/walkThrough/{electron-browser => browser}/walkThroughActions.ts (97%) rename src/vs/workbench/contrib/welcome/walkThrough/{electron-browser => browser}/walkThroughPart.css (100%) rename src/vs/workbench/contrib/welcome/walkThrough/{electron-browser => browser}/walkThroughPart.ts (99%) rename src/vs/workbench/contrib/welcome/walkThrough/{node => common}/walkThroughContentProvider.ts (100%) rename src/vs/workbench/contrib/welcome/walkThrough/{node => common}/walkThroughInput.ts (100%) rename src/vs/workbench/contrib/welcome/walkThrough/{node => common}/walkThroughUtils.ts (100%) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsUtils.ts b/src/vs/workbench/contrib/extensions/common/extensionsUtils.ts similarity index 96% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsUtils.ts rename to src/vs/workbench/contrib/extensions/common/extensionsUtils.ts index 0284d7fc7b7..91f521c2d94 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsUtils.ts +++ b/src/vs/workbench/contrib/extensions/common/extensionsUtils.ts @@ -15,7 +15,6 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { Severity, INotificationService } from 'vs/platform/notification/common/notification'; -import product from 'vs/platform/product/node/product'; export interface IExtensionStatus { identifier: IExtensionIdentifier; @@ -137,8 +136,3 @@ export function isKeymapExtension(tipsService: IExtensionTipsService, extension: const cats = extension.local.manifest.categories; return cats && cats.indexOf('Keymaps') !== -1 || tipsService.getKeymapRecommendations().some(({ extensionId }) => areSameExtensions({ id: extensionId }, extension.local.identifier)); } - -export function getKeywordsForExtension(extension: string): string[] { - const keywords = product.extensionKeywords || {}; - return keywords[extension] || []; -} \ No newline at end of file diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index 5b401acdbcd..df036e95dbc 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -43,7 +43,6 @@ import { URI } from 'vs/base/common/uri'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/node/experimentService'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { getKeywordsForExtension } from 'vs/workbench/contrib/extensions/electron-browser/extensionsUtils'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { extname } from 'vs/base/common/resources'; @@ -759,7 +758,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe return; } - const keywords = getKeywordsForExtension(fileExtension); + const lookup = product.extensionKeywords || {}; + const keywords = lookup[fileExtension] || []; this._galleryService.query({ text: `tag:"__ext_${fileExtension}" ${keywords.map(tag => `tag:"${tag}"`)}` }).then(pager => { if (!pager || !pager.firstPage || !pager.firstPage.length) { return; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts index fab31c3e8d7..9611f624c74 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts @@ -33,7 +33,7 @@ import * as jsonContributionRegistry from 'vs/platform/jsonschemas/common/jsonCo import { ExtensionsConfigurationSchema, ExtensionsConfigurationSchemaId } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { KeymapExtensions } from 'vs/workbench/contrib/extensions/electron-browser/extensionsUtils'; +import { KeymapExtensions } from 'vs/workbench/contrib/extensions/common/extensionsUtils'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { GalleryExtensionsHandler, ExtensionsHandler } from 'vs/workbench/contrib/extensions/browser/extensionsQuickOpen'; import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts index 4d6d70c410e..51177b7ca33 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts @@ -40,10 +40,10 @@ import { alert } from 'vs/base/browser/ui/aria/aria'; import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list'; import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { getKeywordsForExtension } from 'vs/workbench/contrib/extensions/electron-browser/extensionsUtils'; import { IAction } from 'vs/base/common/actions'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import product from 'vs/platform/product/node/product'; class ExtensionsViewState extends Disposable implements IExtensionsViewState { @@ -366,7 +366,8 @@ export class ExtensionsListView extends ViewletPanel { text = query.value.replace(extensionRegex, (m, ext) => { // Get curated keywords - const keywords = getKeywordsForExtension(ext); + const lookup = product.extensionKeywords || {}; + const keywords = lookup[ext] || []; // Get mode name const modeId = this.modeService.getModeIdByFilepathOrFirstLine(`.${ext}`); diff --git a/src/vs/workbench/contrib/welcome/page/electron-browser/vs_code_welcome_page.ts b/src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts similarity index 100% rename from src/vs/workbench/contrib/welcome/page/electron-browser/vs_code_welcome_page.ts rename to src/vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page.ts diff --git a/src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.contribution.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts similarity index 97% rename from src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.contribution.ts rename to src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts index 3346ebedbe3..0b8457849d8 100644 --- a/src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.contribution.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.contribution.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { Registry } from 'vs/platform/registry/common/platform'; -import { WelcomePageContribution, WelcomePageAction, WelcomeInputFactory } from 'vs/workbench/contrib/welcome/page/electron-browser/welcomePage'; +import { WelcomePageContribution, WelcomePageAction, WelcomeInputFactory } from 'vs/workbench/contrib/welcome/page/browser/welcomePage'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; diff --git a/src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.css b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.css similarity index 100% rename from src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.css rename to src/vs/workbench/contrib/welcome/page/browser/welcomePage.css diff --git a/src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts similarity index 99% rename from src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.ts rename to src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index cba26a0edd4..3564664a988 100644 --- a/src/vs/workbench/contrib/welcome/page/electron-browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -9,7 +9,7 @@ import * as strings from 'vs/base/common/strings'; import * as path from 'vs/base/common/path'; import { ICommandService } from 'vs/platform/commands/common/commands'; import * as arrays from 'vs/base/common/arrays'; -import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/node/walkThroughInput'; +import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -23,15 +23,15 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { Schemas } from 'vs/base/common/network'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; -import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapExtension } from 'vs/workbench/contrib/extensions/electron-browser/extensionsUtils'; +import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapExtension } from 'vs/workbench/contrib/extensions/common/extensionsUtils'; import { IExtensionEnablementService, IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, EnablementState, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { used } from 'vs/workbench/contrib/welcome/page/electron-browser/vs_code_welcome_page'; +import { used } from 'vs/workbench/contrib/welcome/page/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 } 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/contrib/welcome/walkThrough/node/walkThroughUtils'; +import { getExtraColor } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughUtils'; import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor'; @@ -274,7 +274,7 @@ class WelcomePage { const resource = URI.parse(require.toUrl('./vs_code_welcome_page')) .with({ scheme: Schemas.walkThrough, - query: JSON.stringify({ moduleId: 'vs/workbench/contrib/welcome/page/electron-browser/vs_code_welcome_page' }) + query: JSON.stringify({ moduleId: 'vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page' }) }); this.editorInput = this.instantiationService.createInstance(WalkThroughInput, { typeId: welcomeInputTypeId, diff --git a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/editor/editorWalkThrough.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts similarity index 97% rename from src/vs/workbench/contrib/welcome/walkThrough/electron-browser/editor/editorWalkThrough.ts rename to src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts index 3d69628cdbe..7a95ffda9e4 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/editor/editorWalkThrough.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts @@ -8,7 +8,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { Action } from 'vs/base/common/actions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; -import { WalkThroughInput, WalkThroughInputOptions } from 'vs/workbench/contrib/welcome/walkThrough/node/walkThroughInput'; +import { WalkThroughInput, WalkThroughInputOptions } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; import { Schemas } from 'vs/base/common/network'; import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor'; diff --git a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.md similarity index 100% rename from src/vs/workbench/contrib/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md rename to src/vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough.md diff --git a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThrough.contribution.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts similarity index 91% rename from src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThrough.contribution.ts rename to src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts index 8d508626bdb..9eed29a774f 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThrough.contribution.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/node/walkThroughInput'; -import { WalkThroughPart } from 'vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart'; -import { WalkThroughArrowUp, WalkThroughArrowDown, WalkThroughPageUp, WalkThroughPageDown } from 'vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughActions'; -import { WalkThroughContentProvider, WalkThroughSnippetContentProvider } from 'vs/workbench/contrib/welcome/walkThrough/node/walkThroughContentProvider'; -import { EditorWalkThroughAction, EditorWalkThroughInputFactory } from 'vs/workbench/contrib/welcome/walkThrough/electron-browser/editor/editorWalkThrough'; +import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; +import { WalkThroughPart } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart'; +import { WalkThroughArrowUp, WalkThroughArrowDown, WalkThroughPageUp, WalkThroughPageDown } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughActions'; +import { WalkThroughContentProvider, WalkThroughSnippetContentProvider } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider'; +import { EditorWalkThroughAction, EditorWalkThroughInputFactory } from 'vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough'; 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'; diff --git a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughActions.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughActions.ts similarity index 97% rename from src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughActions.ts rename to src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughActions.ts index 95ba85eb935..cd4caf83cb7 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughActions.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughActions.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { WalkThroughPart, WALK_THROUGH_FOCUS } from 'vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart'; +import { WalkThroughPart, WALK_THROUGH_FOCUS } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart'; import { ICommandAndKeybindingRule, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; diff --git a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart.css b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.css similarity index 100% rename from src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart.css rename to src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.css diff --git a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts similarity index 99% rename from src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart.ts rename to src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts index 4840870a992..a51b73abb56 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart.ts @@ -12,7 +12,7 @@ import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { EditorOptions, IEditorMemento } from 'vs/workbench/common/editor'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/node/walkThroughInput'; +import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import * as marked from 'vs/base/common/marked/marked'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -29,7 +29,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, textPreformatForeground, contrastBorder, textBlockQuoteBackground, textBlockQuoteBorder } from 'vs/platform/theme/common/colorRegistry'; -import { getExtraColor } from 'vs/workbench/contrib/welcome/walkThrough/node/walkThroughUtils'; +import { getExtraColor } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughUtils'; import { UILabelProvider } from 'vs/base/common/keybindingLabels'; import { OS, OperatingSystem } from 'vs/base/common/platform'; import { deepClone } from 'vs/base/common/objects'; diff --git a/src/vs/workbench/contrib/welcome/walkThrough/node/walkThroughContentProvider.ts b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider.ts similarity index 100% rename from src/vs/workbench/contrib/welcome/walkThrough/node/walkThroughContentProvider.ts rename to src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughContentProvider.ts diff --git a/src/vs/workbench/contrib/welcome/walkThrough/node/walkThroughInput.ts b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts similarity index 100% rename from src/vs/workbench/contrib/welcome/walkThrough/node/walkThroughInput.ts rename to src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput.ts diff --git a/src/vs/workbench/contrib/welcome/walkThrough/node/walkThroughUtils.ts b/src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughUtils.ts similarity index 100% rename from src/vs/workbench/contrib/welcome/walkThrough/node/walkThroughUtils.ts rename to src/vs/workbench/contrib/welcome/walkThrough/common/walkThroughUtils.ts diff --git a/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts b/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts index 32f092e1c11..096e70ce7d2 100644 --- a/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts +++ b/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts @@ -10,8 +10,8 @@ import { overviewRulerModifiedForeground } from 'vs/workbench/contrib/scm/electr import { STATUS_BAR_DEBUGGING_BACKGROUND } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider'; import { debugExceptionWidgetBackground } from 'vs/workbench/contrib/debug/browser/exceptionWidget'; import { debugToolBarBackground } from 'vs/workbench/contrib/debug/browser/debugToolbar'; -import { buttonBackground } from 'vs/workbench/contrib/welcome/page/electron-browser/welcomePage'; -import { embeddedEditorBackground } from 'vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThroughPart'; +import { buttonBackground } from 'vs/workbench/contrib/welcome/page/browser/welcomePage'; +import { embeddedEditorBackground } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughPart'; import { request, asText } from 'vs/base/node/request'; import * as pfs from 'vs/base/node/pfs'; import * as path from 'vs/base/common/path'; diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 0c3e4e534c6..7fc0c7748e1 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -207,10 +207,10 @@ import 'vs/workbench/contrib/themes/test/electron-browser/themes.test.contributi import 'vs/workbench/contrib/watermark/browser/watermark'; // Welcome -import 'vs/workbench/contrib/welcome/walkThrough/electron-browser/walkThrough.contribution'; +import 'vs/workbench/contrib/welcome/walkThrough/browser/walkThrough.contribution'; import 'vs/workbench/contrib/welcome/gettingStarted/electron-browser/gettingStarted.contribution'; import 'vs/workbench/contrib/welcome/overlay/browser/welcomeOverlay'; -import 'vs/workbench/contrib/welcome/page/electron-browser/welcomePage.contribution'; +import 'vs/workbench/contrib/welcome/page/browser/welcomePage.contribution'; // Outline import 'vs/workbench/contrib/outline/browser/outline.contribution'; From 4c593835a103ce0584e5d65738495a40059bcfd2 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 12:54:02 +0100 Subject: [PATCH 118/290] fix compile error --- extensions/git/src/decorationProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts index 0c27365bc51..97a6a41997f 100644 --- a/extensions/git/src/decorationProvider.ts +++ b/extensions/git/src/decorationProvider.ts @@ -119,7 +119,7 @@ class GitDecorationProvider implements DecorationProvider { const uris = new Set([...this.decorations.keys()].concat([...newDecorations.keys()])); this.decorations = newDecorations; - this._onDidChangeDecorations.fire([...uris.values()].map(Uri.parse)); + this._onDidChangeDecorations.fire([...uris.values()].map(value => Uri.parse(value, true))); } private collectDecorationData(group: GitResourceGroup, bucket: Map): void { From d30f41aa40fdaa71c8803864c537a6422c396617 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 4 Mar 2019 15:01:52 +0100 Subject: [PATCH 119/290] explorer: for collapsing directories react on keydown events --- src/vs/base/browser/ui/tree/asyncDataTree.ts | 1 + .../files/browser/views/explorerView.ts | 23 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index fe397e7240f..20e0bdf0bd4 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -287,6 +287,7 @@ export class AsyncDataTree implements IDisposable get onDidChangeSelection(): Event> { return Event.map(this.tree.onDidChangeSelection, asTreeEvent); } get onDidOpen(): Event> { return Event.map(this.tree.onDidOpen, asTreeEvent); } + get onKeyDown(): Event { return this.tree.onKeyDown; } get onMouseClick(): Event> { return Event.map(this.tree.onMouseClick, asTreeMouseEvent); } get onMouseDblClick(): Event> { return Event.map(this.tree.onMouseDblClick, asTreeMouseEvent); } get onContextMenu(): Event> { return Event.map(this.tree.onContextMenu, asTreeContextMenuEvent); } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 98fcd9cdb45..69a8b7bb575 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -46,6 +46,9 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IAsyncDataTreeViewState } from 'vs/base/browser/ui/tree/asyncDataTree'; import { FuzzyScore } from 'vs/base/common/filters'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { isMacintosh } from 'vs/base/common/platform'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; export class ExplorerView extends ViewletPanel { static readonly ID: string = 'workbench.explorer.fileView'; @@ -324,14 +327,9 @@ export class ExplorerView extends ViewletPanel { const shiftDown = e.browserEvent instanceof KeyboardEvent && e.browserEvent.shiftKey; if (selection.length === 1 && !shiftDown) { // Do not react if user is clicking on explorer items which are input placeholders - if (!selection[0].name) { + if (!selection[0].name || selection[0].isDirectory) { // Do not react if user is clicking on explorer items which are input placeholders - return; - } - if (selection[0].isDirectory) { - if (e.browserEvent instanceof KeyboardEvent) { - this.tree.toggleCollapsed(selection[0]); - } + // Do not react if clicking on directories return; } @@ -347,6 +345,17 @@ export class ExplorerView extends ViewletPanel { })); this.disposables.push(this.tree.onContextMenu(e => this.onContextMenu(e))); + this.disposables.push(this.tree.onKeyDown(e => { + const event = new StandardKeyboardEvent(e); + const toggleCollapsed = isMacintosh ? (event.keyCode === KeyCode.DownArrow && event.metaKey) : event.keyCode === KeyCode.Enter; + if (toggleCollapsed) { + const focus = this.tree.getFocus(); + if (focus.length === 1 && focus[0].isDirectory) { + this.tree.toggleCollapsed(focus[0]); + } + } + })); + // save view state on shutdown this.storageService.onWillSaveState(() => { From 9638b09920393ef0db203a674cb1cc8ee493cdcb Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 14:28:05 +0100 Subject: [PATCH 120/290] :lipstick: --- 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 2916167b057..8e2288c1e61 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -51,8 +51,6 @@ 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 }, output: { // all output goes into `dist`. From 6877b8095755f7baf0b6bbb3c8b1ebffca1aab85 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 15:12:09 +0100 Subject: [PATCH 121/290] update strict null file --- src/tsconfig.strictNullChecks.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 05f40f7f586..a77304a37b6 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -197,7 +197,7 @@ "./vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActivationProgress.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsList.ts", - "./vs/workbench/contrib/extensions/electron-browser/extensionsUtils.ts", + "./vs/workbench/contrib/extensions/common/extensionsUtils.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts", "./vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput.ts", "./vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts", @@ -440,4 +440,4 @@ "./typings/require-monaco.d.ts", "./vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts" ] -} \ No newline at end of file +} From 979273be9647b532e03e4d10ecd4c7f5a92cf8c6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Mar 2019 15:02:11 +0100 Subject: [PATCH 122/290] Fix #69689 --- .../mainThreadOutputService.ts | 9 +- .../contrib/output/browser/logViewer.ts | 4 +- .../contrib/output/browser/outputActions.ts | 101 ++++++++++-------- .../contrib/output/browser/outputPanel.ts | 15 +-- .../workbench/contrib/output/common/output.ts | 8 +- .../electron-browser/output.contribution.ts | 7 +- .../output/electron-browser/outputServices.ts | 77 +++++++------ 7 files changed, 128 insertions(+), 93 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts b/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts index 7f9f642dafd..9665fd33072 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts @@ -86,8 +86,11 @@ export class MainThreadOutputService extends Disposable implements MainThreadOut public $close(channelId: string): Promise | undefined { const panel = this._panelService.getActivePanel(); - if (panel && panel.getId() === OUTPUT_PANEL_ID && channelId === this._outputService.getActiveChannel().id) { - this._partService.setPanelHidden(true); + if (panel && panel.getId() === OUTPUT_PANEL_ID) { + const activeChannel = this._outputService.getActiveChannel(); + if (activeChannel && channelId === activeChannel.id) { + this._partService.setPanelHidden(true); + } } return undefined; @@ -101,7 +104,7 @@ export class MainThreadOutputService extends Disposable implements MainThreadOut return undefined; } - private _getChannel(channelId: string): IOutputChannel { + private _getChannel(channelId: string): IOutputChannel | null { return this._outputService.getChannel(channelId); } } diff --git a/src/vs/workbench/contrib/output/browser/logViewer.ts b/src/vs/workbench/contrib/output/browser/logViewer.ts index a09231f1d15..b9819992434 100644 --- a/src/vs/workbench/contrib/output/browser/logViewer.ts +++ b/src/vs/workbench/contrib/output/browser/logViewer.ts @@ -17,7 +17,7 @@ import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorIn import { URI } from 'vs/base/common/uri'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; -import { LOG_SCHEME, IOutputChannelDescriptor } from 'vs/workbench/contrib/output/common/output'; +import { LOG_SCHEME, IFileOutputChannelDescriptor } from 'vs/workbench/contrib/output/common/output'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IWindowService } from 'vs/platform/windows/common/windows'; @@ -26,7 +26,7 @@ export class LogViewerInput extends ResourceEditorInput { public static readonly ID = 'workbench.editorinputs.output'; - constructor(private outputChannelDescriptor: IOutputChannelDescriptor, + constructor(private outputChannelDescriptor: IFileOutputChannelDescriptor, @ITextModelService textModelResolverService: ITextModelService, @IHashService hashService: IHashService ) { diff --git a/src/vs/workbench/contrib/output/browser/outputActions.ts b/src/vs/workbench/contrib/output/browser/outputActions.ts index 934be8edfdd..28e23670269 100644 --- a/src/vs/workbench/contrib/output/browser/outputActions.ts +++ b/src/vs/workbench/contrib/output/browser/outputActions.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import * as aria from 'vs/base/browser/ui/aria/aria'; import { IAction, Action } from 'vs/base/common/actions'; -import { IOutputService, OUTPUT_PANEL_ID, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannelDescriptor } from 'vs/workbench/contrib/output/common/output'; +import { IOutputService, OUTPUT_PANEL_ID, IOutputChannelRegistry, Extensions as OutputExt, IOutputChannelDescriptor, IFileOutputChannelDescriptor } from 'vs/workbench/contrib/output/common/output'; import { SelectActionItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; @@ -50,9 +50,11 @@ export class ClearOutputAction extends Action { } public run(): Promise { - this.outputService.getActiveChannel().clear(); - aria.status(nls.localize('outputCleared', "Output was cleared")); - + const activeChannel = this.outputService.getActiveChannel(); + if (activeChannel) { + activeChannel.clear(); + aria.status(nls.localize('outputCleared', "Output was cleared")); + } return Promise.resolve(true); } } @@ -70,7 +72,12 @@ export class ToggleOrSetOutputScrollLockAction extends Action { constructor(id: string, label: string, @IOutputService private readonly outputService: IOutputService) { super(id, label, 'output-action output-scroll-unlock'); - this.toDispose.push(this.outputService.onActiveOutputChannel(channel => this.setClass(this.outputService.getActiveChannel().scrollLock))); + this.toDispose.push(this.outputService.onActiveOutputChannel(channel => { + const activeChannel = this.outputService.getActiveChannel(); + if (activeChannel) { + this.setClass(activeChannel.scrollLock); + } + })); } public run(newLockState?: boolean): Promise { @@ -113,7 +120,7 @@ export class SwitchOutputAction extends Action { this.class = 'output-action switch-to-output'; } - public run(channelId?: string): Promise { + public run(channelId: string): Promise { return this.outputService.showChannel(channelId); } } @@ -134,12 +141,12 @@ export class SwitchOutputActionItem extends SelectActionItem { super(null, action, [], 0, contextViewService, { ariaLabel: nls.localize('outputChannels', 'Output Channels.') }); let outputChannelRegistry = Registry.as(OutputExt.OutputChannels); - this.toDispose.push(outputChannelRegistry.onDidRegisterChannel(() => this.updateOtions(this.outputService.getActiveChannel().id))); - this.toDispose.push(outputChannelRegistry.onDidRemoveChannel(() => this.updateOtions(this.outputService.getActiveChannel().id))); - this.toDispose.push(this.outputService.onActiveOutputChannel(activeChannelId => this.updateOtions(activeChannelId))); + this.toDispose.push(outputChannelRegistry.onDidRegisterChannel(() => this.updateOtions())); + this.toDispose.push(outputChannelRegistry.onDidRemoveChannel(() => this.updateOtions())); + this.toDispose.push(this.outputService.onActiveOutputChannel(() => this.updateOtions())); this.toDispose.push(attachSelectBoxStyler(this.selectBox, themeService)); - this.updateOtions(this.outputService.getActiveChannel().id); + this.updateOtions(); } protected getActionContext(option: string, index: number): string { @@ -147,30 +154,34 @@ export class SwitchOutputActionItem extends SelectActionItem { return channel ? channel.id : option; } - private updateOtions(selectedChannel: string): void { - const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => { - if (!c1.log && c2.log) { - return -1; - } - if (c1.log && !c2.log) { - return 1; - } - return 0; - }); - this.outputChannels = groups[0] || []; - this.logChannels = groups[1] || []; - const showSeparator = this.outputChannels.length && this.logChannels.length; - const separatorIndex = showSeparator ? this.outputChannels.length : -1; - const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))]; - let selected = 0; - if (selectedChannel) { - selected = this.outputChannels.map(c => c.id).indexOf(selectedChannel); - if (selected === -1) { - const logChannelIndex = this.logChannels.map(c => c.id).indexOf(selectedChannel); - selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0; + private updateOtions(): void { + const activeChannel = this.outputService.getActiveChannel(); + if (activeChannel) { + const selectedChannel = activeChannel.id; + const groups = groupBy(this.outputService.getChannelDescriptors(), (c1: IOutputChannelDescriptor, c2: IOutputChannelDescriptor) => { + if (!c1.log && c2.log) { + return -1; + } + if (c1.log && !c2.log) { + return 1; + } + return 0; + }); + this.outputChannels = groups[0] || []; + this.logChannels = groups[1] || []; + const showSeparator = this.outputChannels.length && this.logChannels.length; + const separatorIndex = showSeparator ? this.outputChannels.length : -1; + const options: string[] = [...this.outputChannels.map(c => c.label), ...(showSeparator ? [SwitchOutputActionItem.SEPARATOR] : []), ...this.logChannels.map(c => nls.localize('logChannel', "Log ({0})", c.label))]; + let selected = 0; + if (selectedChannel) { + selected = this.outputChannels.map(c => c.id).indexOf(selectedChannel); + if (selected === -1) { + const logChannelIndex = this.logChannels.map(c => c.id).indexOf(selectedChannel); + selected = logChannelIndex !== -1 ? separatorIndex + 1 + logChannelIndex : 0; + } } + this.setOptions(options.map((label, index) => { text: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected)); } - this.setOptions(options.map((label, index) => { text: label, isDisabled: (index === separatorIndex ? true : undefined) }), Math.max(0, selected)); } } @@ -192,17 +203,23 @@ export class OpenLogOutputFile extends Action { } private update(): void { - const outputChannelDescriptor = this.getOutputChannelDescriptor(); - this.enabled = !!(outputChannelDescriptor && outputChannelDescriptor.file && outputChannelDescriptor.log); + this.enabled = !!this.getLogFileOutputChannelDescriptor(); } public run(): Promise { - return this.enabled ? this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, this.getOutputChannelDescriptor())).then(() => null) : Promise.resolve(null); + const logFileOutputChannelDescriptor = this.getLogFileOutputChannelDescriptor(); + return logFileOutputChannelDescriptor ? this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, logFileOutputChannelDescriptor)).then(() => null) : Promise.resolve(null); } - private getOutputChannelDescriptor(): IOutputChannelDescriptor { + private getLogFileOutputChannelDescriptor(): IFileOutputChannelDescriptor | null { const channel = this.outputService.getActiveChannel(); - return channel ? this.outputService.getChannelDescriptors().filter(c => c.id === channel.id)[0] : null; + if (channel) { + const descriptor = this.outputService.getChannelDescriptors().filter(c => c.id === channel.id)[0]; + if (descriptor && descriptor.file && descriptor.log) { + return descriptor; + } + } + return null; } } @@ -219,15 +236,15 @@ export class ShowLogsOutputChannelAction extends Action { } run(): Promise { - const entries: IQuickPickItem[] = this.outputService.getChannelDescriptors().filter(c => c.file && c.log) - .map(({ id, label }) => ({ id, label })); + const entries: { id: string, label: string }[] = this.outputService.getChannelDescriptors().filter(c => c.file && c.log) + .map(({ id, label }) => ({ id, label })); return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectlog', "Select Log") }) .then(entry => { if (entry) { return this.outputService.showChannel(entry.id); } - return null; + return undefined; }); } } @@ -257,9 +274,9 @@ export class OpenOutputLogFileAction extends Action { return this.quickInputService.pick(entries, { placeHolder: nls.localize('selectlogFile', "Select Log file") }) .then(entry => { if (entry) { - return this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, entry.channel)).then(() => null); + return this.editorService.openEditor(this.instantiationService.createInstance(LogViewerInput, entry.channel)).then(() => undefined); } - return null; + return undefined; }); } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/output/browser/outputPanel.ts b/src/vs/workbench/contrib/output/browser/outputPanel.ts index d1e887071e8..944b643be3c 100644 --- a/src/vs/workbench/contrib/output/browser/outputPanel.ts +++ b/src/vs/workbench/contrib/output/browser/outputPanel.ts @@ -75,7 +75,7 @@ export class OutputPanel extends AbstractTextResourceEditor { return this.actions; } - public getActionItem(action: Action): IActionItem { + public getActionItem(action: Action): IActionItem | null { if (action.id === SwitchOutputAction.ID) { return this.instantiationService.createInstance(SwitchOutputActionItem, action); } @@ -154,11 +154,14 @@ export class OutputPanel extends AbstractTextResourceEditor { return; } - const newPositionLine = e.position.lineNumber; - const lastLine = codeEditor.getModel().getLineCount(); - const newLockState = lastLine !== newPositionLine; - const lockAction = this.actions.filter((action) => action.id === ToggleOrSetOutputScrollLockAction.ID)[0]; - lockAction.run(newLockState); + const model = codeEditor.getModel(); + if (model) { + const newPositionLine = e.position.lineNumber; + const lastLine = model.getLineCount(); + const newLockState = lastLine !== newPositionLine; + const lockAction = this.actions.filter((action) => action.id === ToggleOrSetOutputScrollLockAction.ID)[0]; + lockAction.run(newLockState); + } }); } diff --git a/src/vs/workbench/contrib/output/common/output.ts b/src/vs/workbench/contrib/output/common/output.ts index 6fee8571bbe..08e2a7a363e 100644 --- a/src/vs/workbench/contrib/output/common/output.ts +++ b/src/vs/workbench/contrib/output/common/output.ts @@ -68,7 +68,7 @@ export interface IOutputService { * Given the channel id returns the output channel instance. * Channel should be first registered via OutputChannelRegistry. */ - getChannel(id: string): IOutputChannel; + getChannel(id: string): IOutputChannel | null; /** * Returns an array of all known output channels descriptors. @@ -79,7 +79,7 @@ export interface IOutputService { * Returns the currently active channel. * Only one channel can be active at a given moment. */ - getActiveChannel(): IOutputChannel; + getActiveChannel(): IOutputChannel | null; /** * Show the channel with the passed id. @@ -137,6 +137,10 @@ export interface IOutputChannelDescriptor { file?: URI; } +export interface IFileOutputChannelDescriptor extends IOutputChannelDescriptor { + file: URI; +} + export interface IOutputChannelRegistry { readonly onDidRegisterChannel: Event; diff --git a/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts b/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts index e217ba7ab9e..65e36ae6aab 100644 --- a/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts +++ b/src/vs/workbench/contrib/output/electron-browser/output.contribution.ts @@ -30,7 +30,6 @@ registerSingleton(IOutputService, OutputService); ModesRegistry.registerLanguage({ id: OUTPUT_MODE_ID, extensions: [], - aliases: [null], mimetypes: [OUTPUT_MIME] }); @@ -38,7 +37,6 @@ ModesRegistry.registerLanguage({ ModesRegistry.registerLanguage({ id: LOG_MODE_ID, extensions: [], - aliases: [null], mimetypes: [LOG_MIME] }); @@ -99,7 +97,10 @@ registerAction({ when: CONTEXT_IN_OUTPUT }, handler(accessor) { - accessor.get(IOutputService).getActiveChannel().clear(); + const activeChannel = accessor.get(IOutputService).getActiveChannel(); + if (activeChannel) { + activeChannel.clear(); + } } }); diff --git a/src/vs/workbench/contrib/output/electron-browser/outputServices.ts b/src/vs/workbench/contrib/output/electron-browser/outputServices.ts index 19a30ee0d38..897620d45f8 100644 --- a/src/vs/workbench/contrib/output/electron-browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/electron-browser/outputServices.ts @@ -14,7 +14,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 { IOutputChannelDescriptor, IOutputChannel, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, OUTPUT_SCHEME, OUTPUT_MIME, LOG_SCHEME, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT, MAX_OUTPUT_LENGTH } from 'vs/workbench/contrib/output/common/output'; +import { IOutputChannelDescriptor, IOutputChannel, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, OUTPUT_SCHEME, OUTPUT_MIME, LOG_SCHEME, LOG_MIME, CONTEXT_ACTIVE_LOG_OUTPUT, MAX_OUTPUT_LENGTH, IFileOutputChannelDescriptor } from 'vs/workbench/contrib/output/common/output'; import { OutputPanel } from 'vs/workbench/contrib/output/browser/outputPanel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IModelService } from 'vs/editor/common/services/modelService'; @@ -44,7 +44,7 @@ import { isNumber } from 'vs/base/common/types'; const OUTPUT_ACTIVE_CHANNEL_KEY = 'output.activechannel'; let watchingOutputDir = false; -let callbacks: ((eventType: string, fileName: string) => void)[] = []; +let callbacks: ((eventType: string, fileName?: string) => void)[] = []; function watchOutputDirectory(outputDir: string, logService: ILogService, onChange: (eventType: string, fileName: string) => void): IDisposable { callbacks.push(onChange); if (!watchingOutputDir) { @@ -65,7 +65,7 @@ function watchOutputDirectory(outputDir: string, logService: ILogService, onChan } interface OutputChannel extends IOutputChannel { - readonly file: URI; + readonly file: URI | null; readonly onDidAppendedContent: Event; readonly onDispose: Event; loadModel(): Promise; @@ -83,14 +83,14 @@ abstract class AbstractFileOutputChannel extends Disposable implements OutputCha private readonly mimeType: string; protected modelUpdater: RunOnceScheduler; - protected model: ITextModel; + protected model: ITextModel | null; readonly file: URI; protected startOffset: number = 0; protected endOffset: number = 0; constructor( - readonly outputChannelDescriptor: IOutputChannelDescriptor, + readonly outputChannelDescriptor: IFileOutputChannelDescriptor, private readonly modelUri: URI, protected fileService: IFileService, protected modelService: IModelService, @@ -154,7 +154,7 @@ abstract class AbstractFileOutputChannel extends Disposable implements OutputCha abstract append(message: string); protected onModelCreated(model: ITextModel) { } - protected onModelWillDispose(model: ITextModel) { } + protected onModelWillDispose(model: ITextModel | null) { } protected onUpdateModelCancelled() { } protected updateModel() { } @@ -176,15 +176,14 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out private readonly rotatingFilePath: string; constructor( - outputChannelDescriptor: IOutputChannelDescriptor, - outputDir: string, + outputChannelDescriptor: IFileOutputChannelDescriptor, modelUri: URI, @IFileService fileService: IFileService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, @ILogService logService: ILogService ) { - super({ ...outputChannelDescriptor, file: URI.file(join(outputDir, `${outputChannelDescriptor.id}.log`)) }, modelUri, fileService, modelService, modeService); + super(outputChannelDescriptor, modelUri, fileService, modelService, modeService); // Use one rotating file to check for main file reset this.appender = new OutputAppender(this.id, this.file.fsPath); @@ -262,7 +261,7 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out } } - private onFileChangedInOutputDirector(eventType: string, fileName: string): void { + private onFileChangedInOutputDirector(eventType: string, fileName?: string): void { // Check if rotating file has changed. It changes only when the main file exceeds its limit. if (this.rotatingFilePath === fileName) { this.resettingDelayer.trigger(() => this.resetModel()); @@ -286,11 +285,11 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann private readonly fileHandler: FileListener; private updateInProgress: boolean = false; - private etag: string = ''; - private loadModelPromise: Promise = Promise.resolve(undefined); + private etag: string | undefined = ''; + private loadModelPromise: Promise | null = null; constructor( - outputChannelDescriptor: IOutputChannelDescriptor, + outputChannelDescriptor: IFileOutputChannelDescriptor, modelUri: URI, @IFileService fileService: IFileService, @IModelService modelService: IModelService, @@ -314,7 +313,8 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann } clear(till?: number): void { - this.loadModelPromise.then(() => { + const loadModelPromise: Promise = this.loadModelPromise ? this.loadModelPromise : Promise.resolve(); + loadModelPromise.then(() => { super.clear(till); this.update(); }); @@ -344,7 +344,7 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann this.fileHandler.watch(this.etag); } - protected onModelWillDispose(model: ITextModel): void { + protected onModelWillDispose(model: ITextModel | null): void { this.fileHandler.unwatch(); } @@ -353,13 +353,15 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann } update(size?: number): void { - if (!this.updateInProgress) { - this.updateInProgress = true; - if (isNumber(size) && this.endOffset > size) { // Reset - Content is removed - this.startOffset = this.endOffset = 0; - this.model.setValue(''); + if (this.model) { + if (!this.updateInProgress) { + this.updateInProgress = true; + if (isNumber(size) && this.endOffset > size) { // Reset - Content is removed + this.startOffset = this.endOffset = 0; + this.model.setValue(''); + } + this.modelUpdater.schedule(); } - this.modelUpdater.schedule(); } } } @@ -370,7 +372,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo private channels: Map = new Map(); private activeChannelIdInStorage: string; - private activeChannel: IOutputChannel; + private activeChannel: IOutputChannel | null; private readonly outputDir: string; private readonly _onActiveOutputChannel = new Emitter(); @@ -392,7 +394,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo @IContextKeyService private readonly contextKeyService: IContextKeyService, ) { super(); - this.activeChannelIdInStorage = this.storageService.get(OUTPUT_ACTIVE_CHANNEL_KEY, StorageScope.WORKSPACE, null); + this.activeChannelIdInStorage = this.storageService.get(OUTPUT_ACTIVE_CHANNEL_KEY, StorageScope.WORKSPACE, ''); this.outputDir = join(environmentService.logsPath, `output_${windowService.getCurrentWindowId()}_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`); // Register as text model content provider for output @@ -419,7 +421,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo this._register(this.storageService.onWillSaveState(() => this.saveState())); } - provideTextContent(resource: URI): Promise { + provideTextContent(resource: URI): Promise | null { const channel = this.getChannel(resource.path); if (channel) { return channel.loadModel(); @@ -447,15 +449,15 @@ export class OutputService extends Disposable implements IOutputService, ITextMo return promise.then(() => this._onActiveOutputChannel.fire(id)); } - getChannel(id: string): IOutputChannel { - return this.channels.get(id); + getChannel(id: string): IOutputChannel | null { + return this.channels.get(id) || null; } getChannelDescriptors(): IOutputChannelDescriptor[] { return Registry.as(Extensions.OutputChannels).getChannels(); } - getActiveChannel(): IOutputChannel { + getActiveChannel(): IOutputChannel | null { return this.activeChannel; } @@ -469,7 +471,7 @@ export class OutputService extends Disposable implements IOutputService, ITextMo } } - private onDidPanelOpen(panel: IPanel, preserveFocus: boolean): Promise { + private onDidPanelOpen(panel: IPanel | null, preserveFocus: boolean): Promise { if (panel && panel.getId() === OUTPUT_PANEL_ID) { this._outputPanel = this.panelService.getActivePanel(); if (this.activeChannel) { @@ -506,7 +508,9 @@ export class OutputService extends Disposable implements IOutputService, ITextMo this.showChannel(channel.id, true); } else { this.activeChannel = channel; - this._onActiveOutputChannel.fire(channel ? channel.id : undefined); + if (this.activeChannel) { + this._onActiveOutputChannel.fire(this.activeChannel.id); + } } } Registry.as(Extensions.OutputChannels).removeChannel(id); @@ -528,7 +532,8 @@ export class OutputService extends Disposable implements IOutputService, ITextMo return this.instantiationService.createInstance(FileOutputChannel, channelData, uri); } try { - return this.instantiationService.createInstance(OutputChannelBackedByFile, { id, label: channelData ? channelData.label : '' }, this.outputDir, uri); + const channelDescriptor: IFileOutputChannelDescriptor = { id, label: channelData ? channelData.label : '', log: false, file: URI.file(join(this.outputDir, `${id}.log`)) }; + return this.instantiationService.createInstance(OutputChannelBackedByFile, channelDescriptor, 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); @@ -584,7 +589,7 @@ export class LogContentProvider { ) { } - provideTextContent(resource: URI): Promise { + provideTextContent(resource: URI): Promise | null { if (resource.scheme === LOG_SCHEME) { let channel = this.getChannel(resource); if (channel) { @@ -594,7 +599,7 @@ export class LogContentProvider { return null; } - private getChannel(resource: URI): OutputChannel { + private getChannel(resource: URI): OutputChannel | undefined { const channelId = resource.path; let channel = this.channels.get(channelId); if (!channel) { @@ -624,9 +629,9 @@ class BufferredOutputChannel extends Disposable implements OutputChannel { readonly onDispose: Event = this._onDispose.event; private modelUpdater: RunOnceScheduler; - private model: ITextModel; + private model: ITextModel | null; private readonly bufferredContent: BufferedContent; - private lastReadId: number = undefined; + private lastReadId: number | undefined = undefined; constructor( protected readonly outputChannelIdentifier: IOutputChannelDescriptor, @@ -731,7 +736,9 @@ class BufferedContent { while (this.length > MAX_OUTPUT_LENGTH) { this.dataIds.shift(); const removed = this.data.shift(); - this.length -= removed.length; + if (removed) { + this.length -= removed.length; + } } } From 0a1e5ea6d12272f164784b15a2d9d1eaabfed609 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Mar 2019 15:21:38 +0100 Subject: [PATCH 123/290] #69689 Fix null checks in other files depending on output --- .../contrib/debug/node/debugAdapter.ts | 5 ++- .../electron-browser/terminalTaskSystem.ts | 19 +++++---- .../contrib/tasks/node/processTaskSystem.ts | 39 +++++++++++-------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/vs/workbench/contrib/debug/node/debugAdapter.ts b/src/vs/workbench/contrib/debug/node/debugAdapter.ts index b5f6da93cb8..1f0a6b7e6dc 100644 --- a/src/vs/workbench/contrib/debug/node/debugAdapter.ts +++ b/src/vs/workbench/contrib/debug/node/debugAdapter.ts @@ -394,7 +394,10 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter { // console.log('%c' + sanitize(data), 'background: #ddd; font-style: italic;'); // }); this.serverProcess.stderr.on('data', (data: string) => { - outputService.getChannel(ExtensionsChannelId).append(sanitize(data)); + const channel = outputService.getChannel(ExtensionsChannelId); + if (channel) { + channel.append(sanitize(data)); + } }); } diff --git a/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts index 14a2af17131..bfaaf9c091a 100644 --- a/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts @@ -28,7 +28,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { ITerminalService, ITerminalInstance, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; -import { IOutputService, IOutputChannel } from 'vs/workbench/contrib/output/common/output'; +import { IOutputService } from 'vs/workbench/contrib/output/common/output'; import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEventKind } from 'vs/workbench/contrib/tasks/common/problemCollectors'; import { Task, CustomTask, ContributedTask, RevealKind, CommandOptions, ShellConfiguration, RuntimeType, PanelKind, @@ -148,7 +148,6 @@ export class TerminalTaskSystem implements ITaskSystem { 'win32': TerminalTaskSystem.shellQuotes['powershell'] }; - private outputChannel: IOutputChannel; private activeTasks: IStringDictionary; private terminals: IStringDictionary; private idleTaskTerminals: LinkedMap; @@ -166,10 +165,9 @@ export class TerminalTaskSystem implements ITaskSystem { private telemetryService: ITelemetryService, private contextService: IWorkspaceContextService, private windowService: IWindowService, - outputChannelId: string, + private outputChannelId: string, taskSystemInfoResolver: TaskSystemInfoResovler) { - this.outputChannel = this.outputService.getChannel(outputChannelId); this.activeTasks = Object.create(null); this.terminals = Object.create(null); this.idleTaskTerminals = new LinkedMap(); @@ -184,11 +182,11 @@ export class TerminalTaskSystem implements ITaskSystem { } public log(value: string): void { - this.outputChannel.append(value + '\n'); + this.appendOutput(value + '\n'); } protected showOutput(): void { - this.outputService.showChannel(this.outputChannel.id, true); + this.outputService.showChannel(this.outputChannelId, true); } public run(task: Task, resolver: ITaskResolver, trigger: string = Triggers.command): ITaskExecuteResult { @@ -1156,7 +1154,7 @@ export class TerminalTaskSystem implements ITaskSystem { matcher = value; } if (!matcher) { - this.outputChannel.append(nls.localize('unkownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored')); + this.appendOutput(nls.localize('unkownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored')); return; } let taskSystemInfo: TaskSystemInfo | undefined = resolver.taskSystemInfo; @@ -1285,4 +1283,11 @@ export class TerminalTaskSystem implements ITaskSystem { } return 'other'; } + + private appendOutput(output: string): void { + const outputChannel = this.outputService.getChannel(this.outputChannelId); + if (outputChannel) { + outputChannel.append(output); + } + } } diff --git a/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts b/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts index 6098accc28c..4e128d5ded5 100644 --- a/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/node/processTaskSystem.ts @@ -15,7 +15,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { SuccessData, ErrorData } from 'vs/base/common/processes'; import { LineProcess, LineData } from 'vs/base/node/processes'; -import { IOutputService, IOutputChannel } from 'vs/workbench/contrib/output/common/output'; +import { IOutputService } from 'vs/workbench/contrib/output/common/output'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IMarkerService } from 'vs/platform/markers/common/markers'; @@ -48,8 +48,6 @@ export class ProcessTaskSystem implements ITaskSystem { private telemetryService: ITelemetryService; private configurationResolverService: IConfigurationResolverService; - private outputChannel: IOutputChannel; - private errorsShown: boolean; private childProcess: LineProcess | null; private activeTask: CustomTask | null; @@ -58,7 +56,7 @@ export class ProcessTaskSystem implements ITaskSystem { private readonly _onDidStateChange: Emitter; constructor(markerService: IMarkerService, modelService: IModelService, telemetryService: ITelemetryService, - outputService: IOutputService, configurationResolverService: IConfigurationResolverService, outputChannelId: string) { + outputService: IOutputService, configurationResolverService: IConfigurationResolverService, private outputChannelId: string) { this.markerService = markerService; this.modelService = modelService; this.outputService = outputService; @@ -68,7 +66,6 @@ export class ProcessTaskSystem implements ITaskSystem { this.childProcess = null; this.activeTask = null; this.activeTaskPromise = null; - this.outputChannel = this.outputService.getChannel(outputChannelId); this.errorsShown = true; this._onDidStateChange = new Emitter(); } @@ -188,10 +185,10 @@ export class ProcessTaskSystem implements ITaskSystem { throw err; } else if (err instanceof Error) { let error = err; - this.outputChannel.append(error.message); + this.appendOutput(error.message); throw new TaskError(Severity.Error, error.message, TaskErrors.UnknownError); } else { - this.outputChannel.append(err.toString()); + this.appendOutput(err.toString()); throw new TaskError(Severity.Error, nls.localize('TaskRunnerSystem.unknownError', 'A unknown error has occurred while executing a task. See task output log for details.'), TaskErrors.UnknownError); } } @@ -256,7 +253,7 @@ export class ProcessTaskSystem implements ITaskSystem { let processStartedSignaled: boolean = false; const onProgress = (progress: LineData) => { let line = Strings.removeAnsiEscapeCodes(progress.line); - this.outputChannel.append(line + '\n'); + this.appendOutput(line + '\n'); watchingProblemMatcher.processLine(line); if (delayer === null) { delayer = new Async.Delayer(3000); @@ -320,7 +317,7 @@ export class ProcessTaskSystem implements ITaskSystem { let processStartedSignaled: boolean = false; const onProgress = (progress) => { let line = Strings.removeAnsiEscapeCodes(progress.line); - this.outputChannel.append(line + '\n'); + this.appendOutput(line + '\n'); startStopProblemMatcher.processLine(line); }; const startPromise = this.childProcess.start(onProgress); @@ -367,16 +364,16 @@ export class ProcessTaskSystem implements ITaskSystem { if (errorData.error && !errorData.terminated) { let args: string = task.command.args ? task.command.args.join(' ') : ''; this.log(nls.localize('TaskRunnerSystem.childProcessError', 'Failed to launch external program {0} {1}.', JSON.stringify(task.command.name), args)); - this.outputChannel.append(errorData.error.message); + this.appendOutput(errorData.error.message); makeVisible = true; } if (errorData.stdout) { - this.outputChannel.append(errorData.stdout); + this.appendOutput(errorData.stdout); makeVisible = true; } if (errorData.stderr) { - this.outputChannel.append(errorData.stderr); + this.appendOutput(errorData.stderr); makeVisible = true; } makeVisible = this.checkTerminated(task, errorData) || makeVisible; @@ -436,7 +433,7 @@ export class ProcessTaskSystem implements ITaskSystem { matcher = value; } if (!matcher) { - this.outputChannel.append(nls.localize('unkownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored')); + this.appendOutput(nls.localize('unkownProblemMatcher', 'Problem matcher {0} can\'t be resolved. The matcher will be ignored')); return; } if (!matcher.filePrefix) { @@ -455,14 +452,24 @@ export class ProcessTaskSystem implements ITaskSystem { } public log(value: string): void { - this.outputChannel.append(value + '\n'); + this.appendOutput(value + '\n'); } private showOutput(): void { - this.outputService.showChannel(this.outputChannel.id, true); + this.outputService.showChannel(this.outputChannelId, true); + } + + private appendOutput(output: string): void { + const outputChannel = this.outputService.getChannel(this.outputChannelId); + if (outputChannel) { + outputChannel.append(output); + } } private clearOutput(): void { - this.outputChannel.clear(); + const outputChannel = this.outputService.getChannel(this.outputChannelId); + if (outputChannel) { + outputChannel.clear(); + } } } From ec70dcd87a2e83ac3d3aee71abbfc88386f0bd70 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 4 Mar 2019 15:37:07 +0100 Subject: [PATCH 124/290] Fix #69684 --- .../keybinding/common/keybindingEditing.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts index e0c03b9aef7..94b9c9bc0d8 100644 --- a/src/vs/workbench/services/keybinding/common/keybindingEditing.ts +++ b/src/vs/workbench/services/keybinding/common/keybindingEditing.ts @@ -141,7 +141,10 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding private removeDefaultKeybinding(keybindingItem: ResolvedKeybindingItem, model: ITextModel): void { const { tabSize, insertSpaces } = model.getOptions(); const eol = model.getEOL(); - this.applyEditsToBuffer(setProperty(model.getValue(), [-1], this.asObject(keybindingItem.resolvedKeybinding.getUserSettingsLabel(), keybindingItem.command, keybindingItem.when ? keybindingItem.when.serialize() : undefined, true), { tabSize, insertSpaces, eol })[0], model); + const key = keybindingItem.resolvedKeybinding ? keybindingItem.resolvedKeybinding.getUserSettingsLabel() : null; + if (key) { + this.applyEditsToBuffer(setProperty(model.getValue(), [-1], this.asObject(key, keybindingItem.command, keybindingItem.when ? keybindingItem.when.serialize() : undefined, true), { tabSize, insertSpaces, eol })[0], model); + } } private removeUnassignedDefaultKeybinding(keybindingItem: ResolvedKeybindingItem, model: ITextModel): void { @@ -162,7 +165,8 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding return index; } if (keybinding.when && keybindingItem.when) { - if (ContextKeyExpr.deserialize(keybinding.when).serialize() === keybindingItem.when.serialize()) { + const contextKeyExpr = ContextKeyExpr.deserialize(keybinding.when); + if (contextKeyExpr && contextKeyExpr.serialize() === keybindingItem.when.serialize()) { return index; } } @@ -181,9 +185,11 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding return indices; } - private asObject(key: string, command: string, when: string, negate: boolean): any { + private asObject(key: string, command: string | null, when: string | undefined, negate: boolean): any { const object = { key }; - object['command'] = negate ? `-${command}` : command; + if (command) { + object['command'] = negate ? `-${command}` : command; + } if (when) { object['when'] = when; } From a09fc246ed12bee6a0851f9396360d3b9a00ed1b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 15:49:32 +0100 Subject: [PATCH 125/290] remote - workaround issue with dialog channel --- src/vs/workbench/electron-browser/workbench.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 4267b0ceed9..4753d1ab5f6 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -425,13 +425,6 @@ export class Workbench extends Disposable implements IPartService { const remoteAgentService = new RemoteAgentService(this.configuration, this.notificationService, this.environmentService, remoteAuthorityResolverService); serviceCollection.set(IRemoteAgentService, remoteAgentService); - const remoteAgentConnection = remoteAgentService.getConnection(); - if (remoteAgentConnection) { - remoteAgentConnection.registerChannel('dialog', this.instantiationService.createInstance(DialogChannel)); - remoteAgentConnection.registerChannel('download', new DownloadServiceChannel()); - remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService)); - } - // Extensions Management const extensionManagementChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('extensions'))); const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel); @@ -554,6 +547,14 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(contributedService.id, contributedService.descriptor); } + // TODO this should move somewhere else + const remoteAgentConnection = remoteAgentService.getConnection(); + if (remoteAgentConnection) { + remoteAgentConnection.registerChannel('dialog', this.instantiationService.createInstance(DialogChannel)); + remoteAgentConnection.registerChannel('download', new DownloadServiceChannel()); + remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService)); + } + // Set the some services to registries that have been created eagerly Registry.as(ActionBarExtensions.Actionbar).setInstantiationService(this.instantiationService); Registry.as(WorkbenchExtensions.Workbench).start(this.instantiationService, this.lifecycleService); From 30e74b1468ba3f2bd4df741de112b2224d072abd Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 15:53:47 +0100 Subject: [PATCH 126/290] debt - layout => legacyLayout --- .../browser/{layout.ts => legacyLayout.ts} | 32 +++++++++---------- .../workbench/electron-browser/workbench.ts | 6 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) rename src/vs/workbench/browser/{layout.ts => legacyLayout.ts} (94%) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/legacyLayout.ts similarity index 94% rename from src/vs/workbench/browser/layout.ts rename to src/vs/workbench/browser/legacyLayout.ts index e9711a46e71..1d91550fcab 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/legacyLayout.ts @@ -43,9 +43,9 @@ const HIDE_PANEL_HEIGHT_THRESHOLD = 50; const HIDE_PANEL_WIDTH_THRESHOLD = 100; /** - * The workbench layout is responsible to lay out all parts that make the Workbench. + * @deprecated to be replaced by new Grid layout */ -export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutProvider, IHorizontalSashLayoutProvider { +export class WorkbenchLegacyLayout extends Disposable implements IVerticalSashLayoutProvider, IHorizontalSashLayoutProvider { private static readonly sashXOneWidthSettingsKey = 'workbench.sidebar.width'; private static readonly sashXTwoWidthSettingsKey = 'workbench.panel.width'; @@ -103,13 +103,13 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr } private restorePreviousState(): void { - this._sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, this.storageService.getNumber(WorkbenchLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_SIDEBAR_PART_WIDTH)); + this._sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, this.storageService.getNumber(WorkbenchLegacyLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_SIDEBAR_PART_WIDTH)); - this._panelWidth = Math.max(this.partLayoutInfo.panel.minWidth, this.storageService.getNumber(WorkbenchLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); - this._panelHeight = Math.max(this.partLayoutInfo.panel.minHeight, this.storageService.getNumber(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); + this._panelWidth = Math.max(this.partLayoutInfo.panel.minWidth, this.storageService.getNumber(WorkbenchLegacyLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); + this._panelHeight = Math.max(this.partLayoutInfo.panel.minHeight, this.storageService.getNumber(WorkbenchLegacyLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, DEFAULT_PANEL_PART_SIZE)); this.panelMaximized = false; - this.panelSizeBeforeMaximized = this.storageService.getNumber(WorkbenchLayout.panelSizeBeforeMaximizedKey, StorageScope.GLOBAL, 0); + this.panelSizeBeforeMaximized = this.storageService.getNumber(WorkbenchLegacyLayout.panelSizeBeforeMaximizedKey, StorageScope.GLOBAL, 0); } private registerListeners(): void { @@ -369,20 +369,20 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr })); this._register(this.sashXOne.onDidEnd(() => { - this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); })); this._register(this.sashY.onDidEnd(() => { - this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); })); this._register(this.sashXTwo.onDidEnd(() => { - this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); })); this._register(this.sashY.onDidReset(() => { this.panelHeight = this.sidebarHeight * DEFAULT_PANEL_SIZE_COEFFICIENT; - this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); this.layout(); })); @@ -391,7 +391,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr let activeViewlet = this.viewletService.getActiveViewlet(); let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth(); this.sidebarWidth = Math.max(optimalWidth, DEFAULT_SIDEBAR_PART_WIDTH); - this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); this.partService.setSideBarHidden(false); this.layout(); @@ -399,7 +399,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr this._register(this.sashXTwo.onDidReset(() => { this.panelWidth = (this.workbenchSize.width - this.sidebarWidth - this.activitybarWidth) * DEFAULT_PANEL_SIZE_COEFFICIENT; - this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); this.layout(); })); @@ -474,7 +474,7 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr } } - this.storageService.store(WorkbenchLayout.panelSizeBeforeMaximizedKey, this.panelSizeBeforeMaximized, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.panelSizeBeforeMaximizedKey, this.panelSizeBeforeMaximized, StorageScope.GLOBAL); const panelDimension = new Dimension(panelWidth, panelHeight); @@ -530,16 +530,16 @@ export class WorkbenchLayout extends Disposable implements IVerticalSashLayoutPr if (!isSidebarHidden) { this.sidebarWidth = sidebarSize.width; - this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); } if (!isPanelHidden) { if (panelPosition === Position.BOTTOM) { this.panelHeight = panelDimension.height; - this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); } else { this.panelWidth = panelDimension.width; - this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLegacyLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); } } diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 4753d1ab5f6..d3fbc90ed25 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -73,7 +73,7 @@ import { ContextViewService } from 'vs/platform/contextview/browser/contextViewS import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { Sizing, Direction, Grid, View } from 'vs/base/browser/ui/grid/grid'; import { IEditor } from 'vs/editor/common/editorCommon'; -import { WorkbenchLayout } from 'vs/workbench/browser/layout'; +import { WorkbenchLegacyLayout } from 'vs/workbench/browser/legacyLayout'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { setARIAContainer } from 'vs/base/browser/ui/aria/aria'; import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration'; @@ -913,7 +913,7 @@ export class Workbench extends Disposable implements IPartService { private readonly _onZenMode: Emitter = this._register(new Emitter()); get onZenModeChange(): Event { return this._onZenMode.event; } - private workbenchGrid: Grid | WorkbenchLayout; + private workbenchGrid: Grid | WorkbenchLegacyLayout; private titleBarPartView: View; private activityBarPartView: View; @@ -1374,7 +1374,7 @@ export class Workbench extends Disposable implements IPartService { this.workbench.prepend(this.workbenchGrid.element); } else { this.workbenchGrid = this.instantiationService.createInstance( - WorkbenchLayout, + WorkbenchLegacyLayout, this.container, this.workbench, { From 44b4f0e96716e0f41dd0b2bcecce236b717d3864 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 15:59:16 +0100 Subject: [PATCH 127/290] remove isMalformedUri thing --- src/vs/base/common/resources.ts | 17 +------------- src/vs/base/test/common/resources.test.ts | 27 ++--------------------- src/vs/workbench/api/node/apiCommands.ts | 8 ------- 3 files changed, 3 insertions(+), 49 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 607aff7911a..54f46ad9468 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -249,21 +249,6 @@ export function distinctParents(items: T[], resourceAccessor: (item: T) => UR return distinctParents; } -/** - * Tests whether 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); - } - return undefined; -} - - /** * Data URI related helpers. */ @@ -324,4 +309,4 @@ export class ResourceGlobMatcher { } return !!this.globalExpression(resource.path); } -} \ No newline at end of file +} diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index cf1ad37c228..fc2428541d6 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath, isMalformedFileUri, relativePath, removeTrailingPathSeparator, hasTrailingPathSeparator, resolvePath } from 'vs/base/common/resources'; -import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; +import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath, relativePath, removeTrailingPathSeparator, hasTrailingPathSeparator, resolvePath } from 'vs/base/common/resources'; +import { URI } from 'vs/base/common/uri'; import { isWindows } from 'vs/base/common/platform'; import { toSlashes } from 'vs/base/common/extpath'; import { startsWith } from 'vs/base/common/strings'; @@ -357,27 +357,4 @@ suite('Resources', () => { assert.equal(isEqualOrParent(fileURI3, fileURI, true), false, '15'); assert.equal(isEqualOrParent(fileURI5, fileURI5, true), true, '16'); }); - - function assertMalformedFileUri(path: string, expected: string | undefined) { - const old = setUriThrowOnMissingScheme(false); - const newURI = isMalformedFileUri(URI.parse(path)); - assert.equal(newURI && newURI.toString(), expected); - setUriThrowOnMissingScheme(old); - } - - test('isMalformedFileUri', () => { - 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'); - - assertMalformedFileUri('file:///foo/bar', undefined); - assertMalformedFileUri('file:///c%3A/foo/bar', undefined); - assertMalformedFileUri('file://localhost/c$/devel/test', undefined); - assertMalformedFileUri('foo://dadie/foo/bar', undefined); - assertMalformedFileUri('foo:///dadie/foo/bar', undefined); - }); }); diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index 8f748f3efb6..c5177b90d08 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -5,7 +5,6 @@ import * as vscode from 'vscode'; import { URI } from 'vs/base/common/uri'; -import { isMalformedFileUri } from 'vs/base/common/resources'; import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters'; import { CommandsRegistry, ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; @@ -39,13 +38,6 @@ export class OpenFolderAPICommand { if (!uri) { return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); } - 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', { urisToOpen: [{ uri }], forceNewWindow }); } } From 6fad3377f4fcd410e93881e7263dcca781d07a8d Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 4 Mar 2019 15:00:19 +0000 Subject: [PATCH 128/290] Start CLIServer with extension host --- src/vs/base/node/processes.ts | 22 ++-- src/vs/workbench/api/node/extHost.api.impl.ts | 7 +- src/vs/workbench/api/node/extHostCLIServer.ts | 101 ++++++++++++++++++ .../api/node/extHostTerminalService.ts | 90 +--------------- .../terminalProcessManager.ts | 2 +- 5 files changed, 123 insertions(+), 99 deletions(-) create mode 100644 src/vs/workbench/api/node/extHostCLIServer.ts diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index e16c0722a57..dfaa9042499 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -75,7 +75,11 @@ export function getWindowsShell(): string { /** * Sanitizes a VS Code process environment by removing all Electron/VS Code-related values. */ -export function sanitizeProcessEnvironment(env: Platform.IProcessEnvironment): void { +export function sanitizeProcessEnvironment(env: Platform.IProcessEnvironment, ...preserve: string[]): void { + const set = preserve.reduce((set, key) => { + set[key] = true; + return set; + }, {} as Record); const keysToRemove = [ /^ELECTRON_.+$/, /^GOOGLE_API_KEY$/, @@ -83,14 +87,16 @@ export function sanitizeProcessEnvironment(env: Platform.IProcessEnvironment): v /^SNAP(|_.*)$/ ]; const envKeys = Object.keys(env); - envKeys.forEach(envKey => { - for (let i = 0; i < keysToRemove.length; i++) { - if (envKey.search(keysToRemove[i]) !== -1) { - delete env[envKey]; - break; + envKeys + .filter(key => !set[key]) + .forEach(envKey => { + for (let i = 0; i < keysToRemove.length; i++) { + if (envKey.search(keysToRemove[i]) !== -1) { + delete env[envKey]; + break; + } } - } - }); + }); } export abstract class AbstractProcess { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index d14dab1dd99..c3edba1ed2a 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -65,6 +65,7 @@ import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/n import * as vscode from 'vscode'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { originalFSPath } from 'vs/base/common/resources'; +import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer'; export interface IExtensionApiFactory { (extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -113,7 +114,7 @@ export function createApiFactory( 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)); - const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService, extHostCommands)); + const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, new ExtHostTerminalService(rpcProtocol, extHostConfiguration, extHostLogService)); const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, new ExtHostDebugService(rpcProtocol, extHostWorkspace, extensionService, extHostDocumentsAndEditors, extHostConfiguration, extHostTerminalService, extHostCommands)); const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService)); const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments)); @@ -124,6 +125,10 @@ export function createApiFactory( const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(initData.logsLocation, rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); + if (initData.remoteAuthority) { + const cliServer = new CLIServer(extHostCommands); + process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath; + } // Check that no named customers are missing const expected: ProxyIdentifier[] = Object.keys(ExtHostContext).map((key) => (ExtHostContext)[key]); diff --git a/src/vs/workbench/api/node/extHostCLIServer.ts b/src/vs/workbench/api/node/extHostCLIServer.ts new file mode 100644 index 00000000000..89f6c02d448 --- /dev/null +++ b/src/vs/workbench/api/node/extHostCLIServer.ts @@ -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. + *--------------------------------------------------------------------------------------------*/ + +import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net'; +import * as http from 'http'; +import * as fs from 'fs'; +import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands'; +import { IURIToOpen, URIType } from 'vs/platform/windows/common/windows'; +import { URI } from 'vs/base/common/uri'; +import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces'; + + +export class CLIServer { + + private _server: http.Server; + private _ipcHandlePath: string | undefined; + + constructor(private _commands: ExtHostCommands) { + this._server = http.createServer((req, res) => this.onRequest(req, res)); + this.setup().catch(err => { + console.error(err); + return ''; + }); + } + + public get ipcHandlePath() { + return this._ipcHandlePath; + } + + private async setup(): Promise { + this._ipcHandlePath = generateRandomPipeName(); + + try { + this._server.listen(this.ipcHandlePath); + this._server.on('error', err => console.error(err)); + } catch (err) { + console.error('Could not start open from terminal server.'); + } + + return this.ipcHandlePath; + } + private collectURIToOpen(strs: string[], typeHint: URIType, result: IURIToOpen[]): void { + if (Array.isArray(strs)) { + for (const s of strs) { + try { + result.push({ uri: URI.parse(s), typeHint }); + } catch (e) { + // ignore + } + } + } + } + + private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void { + const chunks: string[] = []; + req.setEncoding('utf8'); + req.on('data', (d: string) => chunks.push(d)); + req.on('end', () => { + const data = JSON.parse(chunks.join('')); + switch (data.type) { + case 'open': + this.open(data, res); + break; + default: + res.writeHead(404); + res.write(`Unkown message type: ${data.type}`, err => { + if (err) { + console.error(err); + } + }); + res.end(); + break; + } + }); + } + + private open(data: any, res: http.ServerResponse) { + let { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow } = data; + if (folderURIs && folderURIs.length || fileURIs && fileURIs.length) { + const urisToOpen: IURIToOpen[] = []; + this.collectURIToOpen(folderURIs, 'folder', urisToOpen); + this.collectURIToOpen(fileURIs, 'file', urisToOpen); + if (!forceReuseWindow && urisToOpen.some(o => o.typeHint === 'folder' || (o.typeHint === 'file' && hasWorkspaceFileExtension(o.uri.path)))) { + forceNewWindow = true; + } + this._commands.executeCommand('_files.windowOpen', { urisToOpen, forceNewWindow, diffMode, addMode, forceReuseWindow }); + } + res.writeHead(200); + res.end(); + } + + dispose(): void { + this._server.close(); + + if (this._ipcHandlePath && process.platform !== 'win32' && fs.existsSync(this._ipcHandlePath)) { + fs.unlinkSync(this._ipcHandlePath); + } + } +} diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 49d23649a80..4e10c68feb2 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -14,12 +14,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { timeout } from 'vs/base/common/async'; -import { generateRandomPipeName } from 'vs/base/parts/ipc/node/ipc.net'; -import * as http from 'http'; -import * as fs from 'fs'; -import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands'; import { sanitizeProcessEnvironment } from 'vs/base/node/processes'; -import { IURIToOpen, URIType } from 'vs/platform/windows/common/windows'; const RENDERER_NO_PROCESS_ID = -1; @@ -270,7 +265,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { private _terminalProcesses: { [id: number]: TerminalProcess } = {}; private _terminalRenderers: ExtHostTerminalRenderer[] = []; private _getTerminalPromises: { [id: number]: Promise } = {}; - private _cliServer: CLIServer | undefined; public get activeTerminal(): ExtHostTerminal { return this._activeTerminal; } public get terminals(): ExtHostTerminal[] { return this._terminals; } @@ -288,7 +282,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { mainContext: IMainContext, private _extHostConfiguration: ExtHostConfiguration, private _logService: ILogService, - private _commands: ExtHostCommands ) { this._proxy = mainContext.getProxy(MainContext.MainThreadTerminalService); } @@ -453,17 +446,12 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Sanitize the environment, removing any undesirable VS Code and Electron environment // variables - sanitizeProcessEnvironment(env); + sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI'); // Continue env initialization, merging in the env from the launch // config and adding keys that are needed to create the process terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, terminalConfig.get('setLocaleVariables')); - if (!this._cliServer) { - this._cliServer = new CLIServer(this._commands); - } - env['VSCODE_IPC_HOOK_CLI'] = this._cliServer.ipcHandlePath; - // Fork the process and listen for messages this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env); const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, terminalConfig.get('windowsEnableConpty')); @@ -512,11 +500,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Send exit event to main side this._proxy.$sendProcessExit(id, exitCode); - if (this._cliServer && !Object.keys(this._terminalProcesses).length) { - this._cliServer.dispose(); - this._cliServer = undefined; - } - } private _getTerminalByIdEventually(id: number, retries: number = 5): Promise { @@ -588,74 +571,3 @@ class ApiRequest { this._callback.apply(proxy, [id].concat(this._args)); } } - - -class CLIServer { - - private _server: http.Server; - private _ipcHandlePath: string | undefined; - - constructor(private _commands: ExtHostCommands) { - this._server = http.createServer((req, res) => this.onRequest(req, res)); - this.setup().catch(err => { - console.error(err); - return ''; - }); - } - - public get ipcHandlePath() { - return this._ipcHandlePath; - } - - private async setup(): Promise { - this._ipcHandlePath = generateRandomPipeName(); - - try { - this._server.listen(this.ipcHandlePath); - this._server.on('error', err => console.error(err)); - } catch (err) { - console.error('Could not start open from terminal server.'); - } - - return this.ipcHandlePath; - } - private collectURIToOpen(strs: string[], typeHint: URIType, result: IURIToOpen[]): void { - if (Array.isArray(strs)) { - for (const s of strs) { - try { - result.push({ uri: URI.parse(s), typeHint }); - } catch (e) { - // ignore - } - } - } - } - - private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void { - const chunks: string[] = []; - req.setEncoding('utf8'); - req.on('data', (d: string) => chunks.push(d)); - req.on('end', () => { - let { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow } = JSON.parse(chunks.join('')); - if (folderURIs && folderURIs.length || fileURIs && fileURIs.length) { - if (folderURIs && folderURIs.length && !forceReuseWindow) { - forceNewWindow = true; - } - const urisToOpen: IURIToOpen[] = []; - this.collectURIToOpen(folderURIs, 'folder', urisToOpen); - this.collectURIToOpen(fileURIs, 'file', urisToOpen); - this._commands.executeCommand('_files.windowOpen', { urisToOpen, forceNewWindow, diffMode, addMode, forceReuseWindow }); - } - res.writeHead(200); - res.end(); - }); - } - - dispose(): void { - this._server.close(); - - if (this._ipcHandlePath && process.platform !== 'win32' && fs.existsSync(this._ipcHandlePath)) { - fs.unlinkSync(this._ipcHandlePath); - } - } -} diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts index 330b7644171..a3fa9af9e3d 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts @@ -138,7 +138,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { // Sanitize the environment, removing any undesirable VS Code and Electron environment // variables - sanitizeProcessEnvironment(env); + sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI'); // Adding other env keys necessary to create the process terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, this._configHelper.config.setLocaleVariables); From 977f414c20f0285c96b096f5045622b6374815fb Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 4 Mar 2019 16:10:26 +0100 Subject: [PATCH 129/290] Strict null check vs/workbench/contrib/tasks Fixes #69685 --- src/tsconfig.strictNullChecks.json | 22 +-- .../contrib/tasks/common/taskService.ts | 4 +- .../contrib/tasks/common/taskSystem.ts | 4 +- .../workbench/contrib/tasks/common/tasks.ts | 4 +- .../electron-browser/task.contribution.ts | 145 ++++++++++-------- 5 files changed, 90 insertions(+), 89 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index a77304a37b6..5093639c590 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -18,6 +18,7 @@ "./vs/workbench/contrib/snippets/**/*.ts", "./vs/workbench/contrib/welcome/**/*.ts", "./vs/workbench/contrib/issue/**/*", + "./vs/workbench/contrib/tasks/**/*.ts", "./vs/workbench/services/commands/**/*", "./vs/workbench/services/files/node/watcher/**/*", "./vs/workbench/services/themes/**/*.ts" @@ -268,26 +269,7 @@ "./vs/workbench/contrib/stats/test/workspaceStats.test.ts", "./vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts", "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", - "./vs/workbench/contrib/tasks/browser/quickOpen.ts", - "./vs/workbench/contrib/tasks/browser/taskQuickOpen.ts", - "./vs/workbench/contrib/tasks/common/problemCollectors.ts", - "./vs/workbench/contrib/tasks/common/problemMatcher.ts", - "./vs/workbench/contrib/tasks/common/taskDefinitionRegistry.ts", - "./vs/workbench/contrib/tasks/common/taskService.ts", - "./vs/workbench/contrib/tasks/common/taskSystem.ts", - "./vs/workbench/contrib/tasks/common/taskTemplates.ts", - "./vs/workbench/contrib/tasks/common/tasks.ts", - "./vs/workbench/contrib/tasks/electron-browser/jsonSchemaCommon.ts", - "./vs/workbench/contrib/tasks/electron-browser/jsonSchema_v1.ts", - "./vs/workbench/contrib/tasks/electron-browser/jsonSchema_v2.ts", - "./vs/workbench/contrib/tasks/electron-browser/runAutomaticTasks.ts", - "./vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts", - "./vs/workbench/contrib/tasks/node/processRunnerDetector.ts", - "./vs/workbench/contrib/tasks/node/processTaskSystem.ts", - "./vs/workbench/contrib/tasks/node/taskConfiguration.ts", - "./vs/workbench/contrib/tasks/node/tasks.ts", - "./vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts", - "./vs/workbench/contrib/tasks/test/electron-browser/configuration.test.ts", + "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", "./vs/workbench/contrib/terminal/browser/terminalTab.ts", diff --git a/src/vs/workbench/contrib/tasks/common/taskService.ts b/src/vs/workbench/contrib/tasks/common/taskService.ts index 8e24623e7eb..c592c6d64f6 100644 --- a/src/vs/workbench/contrib/tasks/common/taskService.ts +++ b/src/vs/workbench/contrib/tasks/common/taskService.ts @@ -38,10 +38,10 @@ export interface TaskFilter { } interface WorkspaceTaskResult { - set: TaskSet; + set: TaskSet | undefined; configurations: { byIdentifier: IStringDictionary; - }; + } | undefined; hasErrors: boolean; } diff --git a/src/vs/workbench/contrib/tasks/common/taskSystem.ts b/src/vs/workbench/contrib/tasks/common/taskSystem.ts index 722fcffdc93..9a2fb0787e4 100644 --- a/src/vs/workbench/contrib/tasks/common/taskSystem.ts +++ b/src/vs/workbench/contrib/tasks/common/taskSystem.ts @@ -93,7 +93,7 @@ export interface ITaskExecuteResult { } export interface ITaskResolver { - resolve(workspaceFolder: IWorkspaceFolder, identifier: string | KeyedTaskIdentifier): Task; + resolve(workspaceFolder: IWorkspaceFolder, identifier: string | KeyedTaskIdentifier | undefined): Task | undefined; } export interface TaskTerminateResponse extends TerminateResponse { @@ -122,7 +122,7 @@ export interface TaskSystemInfo { } export interface TaskSystemInfoResovler { - (workspaceFolder: IWorkspaceFolder): TaskSystemInfo; + (workspaceFolder: IWorkspaceFolder): TaskSystemInfo | undefined; } export interface ITaskSystem { diff --git a/src/vs/workbench/contrib/tasks/common/tasks.ts b/src/vs/workbench/contrib/tasks/common/tasks.ts index 64284fe4728..e8489a6f345 100644 --- a/src/vs/workbench/contrib/tasks/common/tasks.ts +++ b/src/vs/workbench/contrib/tasks/common/tasks.ts @@ -514,7 +514,7 @@ export abstract class CommonTask { return 'unknown'; } - public matches(key: string | KeyedTaskIdentifier, compareId: boolean = false): boolean { + public matches(key: string | KeyedTaskIdentifier | undefined, compareId: boolean = false): boolean { if (key === undefined) { return false; } @@ -631,7 +631,7 @@ export class CustomTask extends CommonTask { return JSON.stringify(key); } - public getWorkspaceFolder(): IWorkspaceFolder | undefined { + public getWorkspaceFolder(): IWorkspaceFolder { return this._source.config.workspaceFolder; } diff --git a/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts index b23a34581ac..bdc28aa2723 100644 --- a/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/contrib/tasks/electron-browser/task.contribution.ts @@ -382,7 +382,7 @@ class ProblemReporter implements TaskConfig.IProblemReporter { interface WorkspaceFolderConfigurationResult { workspaceFolder: IWorkspaceFolder; - config: TaskConfig.ExternalTaskRunnerConfiguration; + config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; hasErrors: boolean; } @@ -426,7 +426,7 @@ class TaskMap { } interface TaskQuickPickEntry extends IQuickPickItem { - task: Task | null; + task: Task | undefined | null; } class TaskService extends Disposable implements ITaskService { @@ -493,7 +493,7 @@ class TaskService extends Disposable implements ITaskService { this._workspaceTasksPromise = undefined; this._taskSystem = undefined; this._taskSystemListener = undefined; - this._outputChannel = this.outputService.getChannel(TaskService.OutputChannelId); + this._outputChannel = this.outputService.getChannel(TaskService.OutputChannelId)!; this._providers = new Map(); this._taskSystemInfos = new Map(); this._register(this.contextService.onDidChangeWorkspaceFolders(() => { @@ -865,22 +865,21 @@ class TaskService extends Disposable implements ITaskService { } public run(task: Task | undefined, options?: ProblemMatcherRunOptions): Promise { + if (!task) { + throw new TaskError(Severity.Info, nls.localize('TaskServer.noTask', 'Task to execute is undefined'), TaskErrors.TaskNotFound); + } return this.getGroupedTasks().then((grouped) => { - if (!task) { - throw new TaskError(Severity.Info, nls.localize('TaskServer.noTask', 'Requested task {0} to execute not found.', task.configurationProperties.name), TaskErrors.TaskNotFound); - } else { - let resolver = this.createResolver(grouped); - if (options && options.attachProblemMatcher && this.shouldAttachProblemMatcher(task) && !InMemoryTask.is(task)) { - return this.attachProblemMatcher(task).then((toExecute) => { - if (toExecute) { - return this.executeTask(toExecute, resolver); - } else { - return Promise.resolve(undefined); - } - }); - } - return this.executeTask(task, resolver); + let resolver = this.createResolver(grouped); + if (options && options.attachProblemMatcher && this.shouldAttachProblemMatcher(task) && !InMemoryTask.is(task)) { + return this.attachProblemMatcher(task).then((toExecute) => { + if (toExecute) { + return this.executeTask(toExecute, resolver); + } else { + return Promise.resolve(undefined); + } + }); } + return this.executeTask(task, resolver); }).then(value => value, (error) => { this.handleError(error); return Promise.reject(error); @@ -898,7 +897,7 @@ class TaskService extends Disposable implements ITaskService { return false; } if (ContributedTask.is(task)) { - return !task.hasDefinedMatchers && task.configurationProperties.problemMatchers.length === 0; + return !task.hasDefinedMatchers && !!task.configurationProperties.problemMatchers && (task.configurationProperties.problemMatchers.length === 0); } if (CustomTask.is(task)) { let configProperties: TaskConfig.ConfigurationProperties = task._source.config.element; @@ -907,9 +906,9 @@ class TaskService extends Disposable implements ITaskService { return false; } - private attachProblemMatcher(task: ContributedTask | CustomTask): Promise { + private attachProblemMatcher(task: ContributedTask | CustomTask): Promise { interface ProblemMatcherPickEntry extends IQuickPickItem { - matcher: NamedProblemMatcher; + matcher: NamedProblemMatcher | undefined; never?: boolean; learnMore?: boolean; } @@ -930,7 +929,13 @@ class TaskService extends Disposable implements ITaskService { } } if (entries.length > 0) { - entries = entries.sort((a, b) => a.label.localeCompare(b.label)); + entries = entries.sort((a, b) => { + if (a.label && b.label) { + return a.label.localeCompare(b.label); + } else { + return 0; + } + }); 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 }, @@ -1002,7 +1007,7 @@ class TaskService extends Disposable implements ITaskService { } public customize(task: ContributedTask | CustomTask, properties?: CustomizationProperties, openConfig?: boolean): Promise { - let workspaceFolder = task.getWorkspaceFolder(); + const workspaceFolder = task.getWorkspaceFolder(); if (!workspaceFolder) { return Promise.resolve(undefined); } @@ -1024,7 +1029,7 @@ class TaskService extends Disposable implements ITaskService { }; let identifier: TaskConfig.TaskIdentifier = Objects.assign(Object.create(null), task.defines); delete identifier['_key']; - Object.keys(identifier).forEach(key => toCustomize[key] = identifier[key]); + Object.keys(identifier).forEach(key => toCustomize![key] = identifier[key]); if (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length > 0 && Types.isStringArray(task.configurationProperties.problemMatchers)) { toCustomize.problemMatcher = task.configurationProperties.problemMatchers; } @@ -1040,7 +1045,7 @@ class TaskService extends Disposable implements ITaskService { } } } else { - if (toCustomize.problemMatcher === undefined && task.configurationProperties.problemMatchers === undefined || task.configurationProperties.problemMatchers.length === 0) { + if (toCustomize.problemMatcher === undefined && task.configurationProperties.problemMatchers === undefined || (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length === 0)) { toCustomize.problemMatcher = []; } } @@ -1062,7 +1067,7 @@ class TaskService extends Disposable implements ITaskService { promise = this.fileService.createFile(workspaceFolder.toResource('.vscode/tasks.json'), content).then(() => { }); } else { // We have a global task configuration - if (index === -1) { + if ((index === -1) && properties) { if (properties.problemMatcher !== undefined) { fileConfig.problemMatcher = properties.problemMatcher; promise = this.writeConfiguration(workspaceFolder, 'tasks.problemMatchers', fileConfig.problemMatcher); @@ -1108,7 +1113,7 @@ class TaskService extends Disposable implements ITaskService { }); } - private writeConfiguration(workspaceFolder: IWorkspaceFolder, key: string, value: any): Promise { + private writeConfiguration(workspaceFolder: IWorkspaceFolder, key: string, value: any): Promise | undefined { if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) { return this.configurationService.updateValue(key, value, { resource: workspaceFolder.uri }, ConfigurationTarget.WORKSPACE); } else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) { @@ -1119,7 +1124,7 @@ class TaskService extends Disposable implements ITaskService { } public openConfig(task: CustomTask | undefined): Promise { - let resource: URI; + let resource: URI | undefined; if (task) { resource = task.getWorkspaceFolder().toResource(task._source.config.file); } else { @@ -1133,7 +1138,7 @@ class TaskService extends Disposable implements ITaskService { }).then(() => undefined); } - private createRunnableTask(tasks: TaskMap, group: TaskGroup): { task: Task; resolver: ITaskResolver } { + private createRunnableTask(tasks: TaskMap, group: TaskGroup): { task: Task; resolver: ITaskResolver } | undefined { interface ResolverData { id: Map; label: Map; @@ -1156,7 +1161,9 @@ class TaskService extends Disposable implements ITaskService { for (let task of tasks) { data.id.set(task._id, task); data.label.set(task._label, task); - data.identifier.set(task.configurationProperties.identifier, task); + if (task.configurationProperties.identifier) { + data.identifier.set(task.configurationProperties.identifier, task); + } if (group && task.configurationProperties.group === group) { if (task._source.kind === TaskSourceKind.Workspace) { workspaceTasks.push(task); @@ -1199,7 +1206,7 @@ class TaskService extends Disposable implements ITaskService { { reevaluateOnRerun: true }, { identifier: id, - dependsOn: extensionTasks.map((task) => { return { workspaceFolder: task.getWorkspaceFolder(), task: task._id }; }), + dependsOn: extensionTasks.map((extensionTask) => { return { workspaceFolder: extensionTask.getWorkspaceFolder()!, task: extensionTask._id }; }), name: id, } ); @@ -1223,7 +1230,9 @@ class TaskService extends Disposable implements ITaskService { } for (let task of tasks) { data.label.set(task._label, task); - data.identifier.set(task.configurationProperties.identifier, task); + if (task.configurationProperties.identifier) { + data.identifier.set(task.configurationProperties.identifier, task); + } let keyedIdentifier = task.getDefinition(true); if (keyedIdentifier !== undefined) { data.taskIdentifier.set(keyedIdentifier._key, task); @@ -1231,9 +1240,9 @@ class TaskService extends Disposable implements ITaskService { } }); return { - resolve: (workspaceFolder: IWorkspaceFolder, identifier: string | TaskIdentifier) => { + resolve: (workspaceFolder: IWorkspaceFolder, identifier: string | TaskIdentifier | undefined) => { let data = resolverData.get(workspaceFolder.uri.toString()); - if (!data) { + if (!data || !identifier) { return undefined; } if (Types.isString(identifier)) { @@ -1269,7 +1278,7 @@ class TaskService extends Disposable implements ITaskService { } if (executeResult.kind === TaskExecuteKind.Active) { let active = executeResult.active; - if (active.same) { + if (active && active.same) { let message; if (active.background) { message = nls.localize('TaskSystem.activeSame.background', 'The task \'{0}\' is already active and in background mode.', executeResult.task.getQualifiedLabel()); @@ -1349,13 +1358,13 @@ class TaskService extends Disposable implements ITaskService { system.hasErrors(this._configHasErrors); this._taskSystem = system; } - this._taskSystemListener = this._taskSystem.onDidStateChange((event) => { + this._taskSystemListener = this._taskSystem!.onDidStateChange((event) => { if (this._taskSystem) { this._taskRunningState.set(this._taskSystem.isActiveSync()); } this._onDidStateChange.fire(event); }); - return this._taskSystem; + return this._taskSystem!; } private getGroupedTasks(): Promise { @@ -1470,7 +1479,7 @@ class TaskService extends Disposable implements ITaskService { result.add(key, ...folderTasks.set.tasks); } unUsedConfigurations.forEach((value) => { - let configuringTask = configurations.byIdentifier[value]; + let configuringTask = configurations!.byIdentifier[value]; this._outputChannel.append(nls.localize( 'TaskService.noConfiguration', 'Error: The {0} task detection didn\'t contribute a task for the following configuration:\n{1}\nThe task will be ignored.\n', @@ -1491,7 +1500,10 @@ class TaskService extends Disposable implements ITaskService { let result: TaskMap = new TaskMap(); for (let set of contributedTaskSets) { for (let task of set.tasks) { - result.add(task.getWorkspaceFolder(), task); + const folder = task.getWorkspaceFolder(); + if (folder) { + result.add(folder, task); + } } } return result; @@ -1499,14 +1511,14 @@ class TaskService extends Disposable implements ITaskService { }); } - private getLegacyTaskConfigurations(workspaceTasks: TaskSet): IStringDictionary { + private getLegacyTaskConfigurations(workspaceTasks: TaskSet): IStringDictionary | undefined { let result: IStringDictionary | undefined; - function getResult() { + function getResult(): IStringDictionary { if (result) { return result; } result = Object.create(null); - return result; + return result!; } for (let task of workspaceTasks.tasks) { if (CustomTask.is(task)) { @@ -1531,11 +1543,11 @@ class TaskService extends Disposable implements ITaskService { } this.updateWorkspaceTasks(runSource); if (runSource === TaskRunSource.User) { - this._workspaceTasksPromise.then(workspaceFolderTasks => { + this._workspaceTasksPromise!.then(workspaceFolderTasks => { RunAutomaticTasks.promptForPermission(this, this.storageService, this.notificationService, workspaceFolderTasks); }); } - return this._workspaceTasksPromise; + return this._workspaceTasksPromise!; } private updateWorkspaceTasks(runSource: TaskRunSource = TaskRunSource.User): void { @@ -1555,7 +1567,7 @@ class TaskService extends Disposable implements ITaskService { if (this.workspaceFolders.length === 0) { return Promise.resolve(new Map()); } else { - let promises: Promise[] = []; + let promises: Promise[] = []; for (let folder of this.workspaceFolders) { promises.push(this.computeWorkspaceFolderTasks(folder, runSource).then((value) => value, () => undefined)); } @@ -1580,9 +1592,9 @@ class TaskService extends Disposable implements ITaskService { return Promise.resolve({ workspaceFolder, set: undefined, configurations: undefined, hasErrors: workspaceFolderConfiguration ? workspaceFolderConfiguration.hasErrors : false }); } return ProblemMatcherRegistry.onReady().then((): WorkspaceFolderTaskResult => { - let taskSystemInfo: TaskSystemInfo = this._taskSystemInfos.get(workspaceFolder.uri.scheme); + let taskSystemInfo: TaskSystemInfo | undefined = this._taskSystemInfos.get(workspaceFolder.uri.scheme); let problemReporter = new ProblemReporter(this._outputChannel); - let parseResult = TaskConfig.parse(workspaceFolder, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config, problemReporter); + let parseResult = TaskConfig.parse(workspaceFolder, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config!, problemReporter); let hasErrors = false; if (!parseResult.validationStatus.isOK()) { hasErrors = true; @@ -1624,19 +1636,26 @@ class TaskService extends Disposable implements ITaskService { if (!detectedConfig) { return { workspaceFolder, config, hasErrors }; } - let result: TaskConfig.ExternalTaskRunnerConfiguration = Objects.deepClone(config); + let result: TaskConfig.ExternalTaskRunnerConfiguration = Objects.deepClone(config)!; let configuredTasks: IStringDictionary = Object.create(null); - if (!result.tasks) { + const resultTasks = result.tasks; + if (!resultTasks) { if (detectedConfig.tasks) { result.tasks = detectedConfig.tasks; } } else { - result.tasks.forEach(task => configuredTasks[task.taskName] = task); - detectedConfig.tasks.forEach((task) => { - if (!configuredTasks[task.taskName]) { - result.tasks.push(task); + resultTasks.forEach(task => { + if (task.taskName) { + configuredTasks[task.taskName] = task; } }); + if (detectedConfig.tasks) { + detectedConfig.tasks.forEach((task) => { + if (task.taskName && !configuredTasks[task.taskName]) { + resultTasks.push(task); + } + }); + } } return { workspaceFolder, config: result, hasErrors }; }); @@ -1646,7 +1665,7 @@ class TaskService extends Disposable implements ITaskService { } else { return new ProcessRunnerDetector(workspaceFolder, this.fileService, this.contextService, this.configurationResolverService).detect(true).then((value) => { let hasErrors = this.printStderr(value.stderr); - return { workspaceFolder, config: value.config, hasErrors }; + return { workspaceFolder, config: value.config!, hasErrors }; }); } } @@ -1694,7 +1713,7 @@ class TaskService extends Disposable implements ITaskService { return TaskConfig.JsonSchemaVersion.from(config); } - private getConfiguration(workspaceFolder: IWorkspaceFolder): { config: TaskConfig.ExternalTaskRunnerConfiguration; hasParseErrors: boolean } { + private getConfiguration(workspaceFolder: IWorkspaceFolder): { config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } { let result = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? Objects.deepClone(this.configurationService.getValue('tasks', { resource: workspaceFolder.uri })) : undefined; @@ -1780,7 +1799,7 @@ class TaskService extends Disposable implements ITaskService { return terminatePromise.then(res => { if (res.confirmed) { - return this._taskSystem.terminateAll().then((responses) => { + return this._taskSystem!.terminateAll().then((responses) => { let success = true; let code: number | undefined = undefined; for (let response of responses) { @@ -1792,7 +1811,7 @@ class TaskService extends Disposable implements ITaskService { } } if (success) { - this._taskSystem = null; + this._taskSystem = undefined; this.disposeTaskSystemListeners(); return false; // no veto } else if (code && code === TerminateResponseCode.ProcessNotFound) { @@ -1932,7 +1951,7 @@ class TaskService extends Disposable implements ITaskService { return entries; } - private showQuickPick(tasks: Promise | Task[], placeHolder: string, defaultEntry?: TaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry): Promise { + private showQuickPick(tasks: Promise | Task[], placeHolder: string, defaultEntry?: TaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry): Promise { let _createEntries = (): Promise => { if (Array.isArray(tasks)) { return Promise.resolve(this.createTaskQuickPickEntries(tasks, group, sort, selectedEntry)); @@ -2044,7 +2063,7 @@ class TaskService extends Disposable implements ITaskService { return this.handleExecuteResult(executeResult); } else { this.doRunTaskCommand(); - return undefined; + return Promise.resolve(undefined); } }); }); @@ -2266,7 +2285,7 @@ class TaskService extends Disposable implements ITaskService { } private getTaskIdentifier(arg?: any): string | KeyedTaskIdentifier | undefined { - let result: string | KeyedTaskIdentifier = undefined; + let result: string | KeyedTaskIdentifier | undefined = undefined; if (Types.isString(arg)) { result = arg; } else if (arg && Types.isString((arg as TaskIdentifier).type)) { @@ -2295,7 +2314,7 @@ class TaskService extends Disposable implements ITaskService { } return this.quickInputService.pick(getTaskTemplates(), { placeHolder: nls.localize('TaskService.template', 'Select a Task Template') }).then((selection) => { if (!selection) { - return undefined; + return Promise.resolve(undefined); } let content = selection.content; let editorConfig = this.configurationService.getValue(); @@ -2345,7 +2364,7 @@ class TaskService extends Disposable implements ITaskService { return candidate && !!candidate.task; } - let stats = this.contextService.getWorkspace().folders.map>((folder) => { + let stats = this.contextService.getWorkspace().folders.map>((folder) => { return this.fileService.resolveFile(folder.toResource('.vscode/tasks.json')).then(stat => stat, () => undefined); }); @@ -2443,7 +2462,7 @@ class TaskService extends Disposable implements ITaskService { this.showQuickPick(tasks, nls.localize('TaskService.pickDefaultBuildTask', 'Select the task to be used as the default build task'), undefined, true, false, selectedEntry). then((task) => { - if (task === undefined) { + if ((task === undefined) || (task === null)) { return; } if (task === selectedTask && CustomTask.is(task)) { @@ -2529,7 +2548,7 @@ class TaskService extends Disposable implements ITaskService { if (task === undefined || task === null) { return; } - this._taskSystem.revealTask(task); + this._taskSystem!.revealTask(task); }); } } From 07e498f887c32cbb621233c3d40aa69ed30aeeae Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 4 Mar 2019 16:29:21 +0100 Subject: [PATCH 130/290] Add filename selection and extension to simple file picker Also fixes drive letter display --- .../electron-browser/remoteFileDialog.ts | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts index 82aefb51aff..50395ba25f6 100644 --- a/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts @@ -90,7 +90,7 @@ export class RemoteFileDialog { newOptions.canSelectFolders = true; newOptions.canSelectFiles = true; return new Promise((resolve) => { - this.pickResource(newOptions).then(folderUri => { + this.pickResource(newOptions, true).then(folderUri => { resolve(folderUri); }); }); @@ -116,12 +116,13 @@ export class RemoteFileDialog { this.scheme = defaultUri ? defaultUri.scheme : (available ? available[0] : Schemas.file); } - private async pickResource(options: IOpenDialogOptions): Promise { + private async pickResource(options: IOpenDialogOptions, isSave: boolean = false): Promise { this.allowFolderSelection = !!options.canSelectFolders; this.allowFileSelection = !!options.canSelectFiles; let homedir: URI = options.defaultUri && options.defaultUri.scheme === REMOTE_HOST_SCHEME ? options.defaultUri : this.workspaceContextService.getWorkspace().folders[0].uri; let trailing: string | undefined; let stat: IFileStat | undefined; + let ext: string = resources.extname(options.defaultUri); if (options.defaultUri) { try { stat = await this.remoteFileService.resolveFile(options.defaultUri); @@ -132,6 +133,16 @@ export class RemoteFileDialog { homedir = resources.dirname(options.defaultUri); trailing = resources.basename(options.defaultUri); } + // append extension + if (isSave && !ext && options.filters) { + for (let i = 0; i < options.filters.length; i++) { + if (options.filters[i].extensions[0] !== '*') { + ext = '.' + options.filters[i].extensions[0]; + trailing = trailing ? trailing + ext : ext; + break; + } + } + } } return new Promise((resolve) => { @@ -221,6 +232,9 @@ export class RemoteFileDialog { this.filePickBox.show(); this.updateItems(homedir, trailing); + if (trailing) { + this.filePickBox.valueSelection = [this.filePickBox.value.length - trailing.length, this.filePickBox.value.length - ext.length]; + } this.userValue = this.filePickBox.value; }); } @@ -375,7 +389,12 @@ export class RemoteFileDialog { private pathFromUri(uri: URI, endWithSeparator: boolean = false): string { const sep = this.labelService.getSeparator(uri.scheme, uri.authority); - let result = uri.path.replace(/\//g, sep); + let result: string; + if (sep === '/') { + result = uri.fsPath.replace(/\\/g, sep); + } else { + result = uri.fsPath.replace(/\//g, sep); + } if (endWithSeparator && !this.endsWithSlash(result)) { result = result + sep; } @@ -433,9 +452,6 @@ export class RemoteFileDialog { const result: FileQuickPickItem[] = []; const backDir = this.createBackItem(currentFolder); - if (backDir) { - result.push(backDir); - } try { const fileNames = await this.remoteFileService.readFolder(currentFolder); const items = await Promise.all(fileNames.map(fileName => this.createItem(fileName, currentFolder))); @@ -448,12 +464,17 @@ export class RemoteFileDialog { // ignore console.log(e); } - return result.sort((i1, i2) => { + const sorted = result.sort((i1, i2) => { if (i1.isFolder !== i2.isFolder) { return i1.isFolder ? -1 : 1; } return i1.label.localeCompare(i2.label); }); + + if (backDir) { + sorted.unshift(backDir); + } + return sorted; } private async createItem(filename: string, parent: URI): Promise { From d9aeef5de618cb403006cf344dea1a7f489da5d5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 4 Mar 2019 16:27:24 +0100 Subject: [PATCH 131/290] remove hasChanges-check, fixes #68971 --- src/vs/workbench/api/node/extHostDiagnostics.ts | 16 ++-------------- .../api/extHostDiagnostics.test.ts | 8 ++++---- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index 791de4d587d..e88ae6266c9 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -8,9 +8,9 @@ import { IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers' import { URI } from 'vs/base/common/uri'; import * as vscode from 'vscode'; import { MainContext, MainThreadDiagnosticsShape, ExtHostDiagnosticsShape, IMainContext } from './extHost.protocol'; -import { DiagnosticSeverity, Diagnostic } from './extHostTypes'; +import { DiagnosticSeverity } from './extHostTypes'; import * as converter from './extHostTypeConverters'; -import { mergeSort, equals } from 'vs/base/common/arrays'; +import { mergeSort } from 'vs/base/common/arrays'; import { Event, Emitter } from 'vs/base/common/event'; import { keys } from 'vs/base/common/map'; @@ -61,13 +61,9 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { this._checkDisposed(); let toSync: vscode.Uri[] = []; - let hasChanged = true; if (first instanceof URI) { - // check if this has actually changed - hasChanged = hasChanged && !equals(diagnostics, this.get(first), Diagnostic.isEqual); - if (!diagnostics) { // remove this entry this.delete(first); @@ -109,14 +105,6 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { // send event for extensions this._onDidChangeDiagnostics.fire(toSync); - // if nothing has changed then there is nothing else to do - // we have updated the diagnostics but we don't send a message - // to the renderer. tho we have still send an event for other - // extensions because the diagnostic might carry more information - // than known to us - if (!hasChanged) { - return; - } // compute change and send to main side const entries: [URI, IMarkerData[]][] = []; for (let uri of toSync) { diff --git a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts index de772e5d024..02419a4d34e 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostDiagnostics.test.ts @@ -188,7 +188,7 @@ suite('ExtHostDiagnostics', () => { lastEntries = undefined!; }); - test('don\'t send message when not making a change', function () { + test('do send message when not making a change', function () { let changeCount = 0; let eventCount = 0; @@ -209,7 +209,7 @@ suite('ExtHostDiagnostics', () => { assert.equal(eventCount, 1); collection.set(uri, [diag]); - assert.equal(changeCount, 1); + assert.equal(changeCount, 2); assert.equal(eventCount, 2); }); @@ -418,10 +418,10 @@ suite('ExtHostDiagnostics', () => { assert.equal(callCount, 1); collection.set(URI.parse('test:me'), array); - assert.equal(callCount, 1); // equal array + assert.equal(callCount, 2); // equal array array.push(diag2); collection.set(URI.parse('test:me'), array); - assert.equal(callCount, 2); // same but un-equal array + assert.equal(callCount, 3); // same but un-equal array }); }); From 13a11b3931477a9c84effa4a5d3c6e59e1ab932c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 16:57:29 +0100 Subject: [PATCH 132/290] debt - split more layout things out of workbench --- .../workbench/electron-browser/workbench.ts | 214 +++++++++--------- 1 file changed, 111 insertions(+), 103 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index d3fbc90ed25..067a2e1489f 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -158,10 +158,7 @@ enum Settings { ZEN_MODE_RESTORE = 'zenMode.restore' } -type FontAliasingOption = 'default' | 'antialiased' | 'none' | 'auto'; -const fontAliasingValues: FontAliasingOption[] = ['antialiased', 'none', 'auto']; - -enum State { +enum Storage { SIDEBAR_HIDDEN = 'workbench.sidebar.hidden', PANEL_HIDDEN = 'workbench.panel.hidden', @@ -213,8 +210,6 @@ export class Workbench extends Disposable implements IPartService { private notificationsCenter: NotificationsCenter; private notificationsToasts: NotificationsToasts; - private fontAliasing: FontAliasingOption; - constructor( private container: HTMLElement, private configuration: IWindowConfiguration, @@ -325,11 +320,12 @@ export class Workbench extends Disposable implements IPartService { // Register Listeners this.registerListeners(); + this.registerLayoutListeners(); - // Settings - this.initState(); + // Layout State + this.initLayoutState(); - // Create Workbench and Parts + // Render Workbench this.renderWorkbench(); // Workbench Layout @@ -571,73 +567,16 @@ export class Workbench extends Disposable implements IPartService { (this.configuration.filesToDiff && this.configuration.filesToDiff.length > 0)); } - //#region event handling - private registerListeners(): void { // Storage this._register(this.storageService.onWillSaveState(e => this.saveState(e))); - // Restore editor if hidden and it changes - this._register(this.editorService.onDidVisibleEditorsChange(() => this.setEditorHidden(false))); - this._register(this.editorPart.onDidActivateGroup(() => this.setEditorHidden(false))); - // Configuration changes this._register(this.configurationService.onDidChangeConfiguration(() => this.setFontAliasing())); - this._register(this.configurationService.onDidChangeConfiguration(() => this.onDidUpdateConfiguration())); - - // Fullscreen changes - this._register(onDidChangeFullscreen(() => this.onFullscreenChanged())); - - // Group changes - this._register(this.editorGroupService.onDidAddGroup(() => this.centerEditorLayout(this.state.editor.centered))); - this._register(this.editorGroupService.onDidRemoveGroup(() => this.centerEditorLayout(this.state.editor.centered))); - - // Prevent workbench from scrolling #55456 - this._register(addDisposableListener(this.workbench, EventType.SCROLL, () => this.workbench.scrollTop = 0)); - - // Menubar visibility changes - if ((isWindows || isLinux) && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { - this._register(this.titlebarPart.onMenubarVisibilityChange(visible => this.onMenubarToggled(visible))); - } } - private onMenubarToggled(visible: boolean) { - if (visible !== this.state.menuBar.toggled) { - this.state.menuBar.toggled = visible; - - if (isFullscreen() && (this.state.menuBar.visibility === 'toggle' || this.state.menuBar.visibility === 'default')) { - this._onTitleBarVisibilityChange.fire(); - this.layout(); - } - } - } - - private onFullscreenChanged(): void { - - // Apply as CSS class - if (isFullscreen()) { - addClass(this.workbench, 'fullscreen'); - } else { - removeClass(this.workbench, 'fullscreen'); - - if (this.state.zenMode.transitionedToFullScreen && this.state.zenMode.active) { - this.toggleZenMode(); - } - } - - // Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update - if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { - this._onTitleBarVisibilityChange.fire(); - this.layout(); // handle title bar when fullscreen changes - } - } - - //#endregion - private renderWorkbench(): void { - - // Apply sidebar state as CSS class if (this.state.sideBar.hidden) { addClass(this.workbench, 'nosidebar'); } @@ -650,14 +589,13 @@ export class Workbench extends Disposable implements IPartService { addClass(this.workbench, 'nostatusbar'); } - // Apply font aliasing - this.setFontAliasing(); - - // Apply fullscreen state - if (isFullscreen()) { + if (this.state.fullscreen) { addClass(this.workbench, 'fullscreen'); } + // Apply font aliasing + this.setFontAliasing(); + // Create Parts this.createTitlebarPart(); this.createActivityBarPart(); @@ -673,8 +611,9 @@ export class Workbench extends Disposable implements IPartService { this.container.appendChild(this.workbench); } + private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto'; private setFontAliasing() { - const aliasing = this.configurationService.getValue(Settings.FONT_ALIASING); + const aliasing = this.configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>(Settings.FONT_ALIASING); if (this.fontAliasing === aliasing) { return; } @@ -682,6 +621,7 @@ export class Workbench extends Disposable implements IPartService { this.fontAliasing = aliasing; // Remove all + const fontAliasingValues: (typeof aliasing)[] = ['antialiased', 'none', 'auto']; removeClasses(this.workbench, ...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); // Add specific @@ -882,19 +822,6 @@ export class Workbench extends Disposable implements IPartService { private saveState(e: IWillSaveStateEvent): void { - // Zen Mode - if (this.state.zenMode.active) { - this.storageService.store(State.ZEN_MODE_ENABLED, true, StorageScope.WORKSPACE); - } else { - this.storageService.remove(State.ZEN_MODE_ENABLED, StorageScope.WORKSPACE); - } - - if (e.reason === WillSaveStateReason.SHUTDOWN && this.state.zenMode.active) { - if (!this.configurationService.getValue(Settings.ZEN_MODE_RESTORE)) { - this.toggleZenMode(true); // We will not restore zen mode, need to clear all zen mode state changes - } - } - // Font info saveFontInfo(this.storageService); } @@ -922,7 +849,9 @@ export class Workbench extends Disposable implements IPartService { private editorPartView: View; private statusBarPartView: View; - private state = { + private readonly state = { + fullscreen: false, + menuBar: { visibility: undefined as MenuBarVisibility, toggled: false @@ -969,7 +898,67 @@ export class Workbench extends Disposable implements IPartService { } }; - private onDidUpdateConfiguration(skipLayout?: boolean): void { + private registerLayoutListeners(): void { + + // Storage + this._register(this.storageService.onWillSaveState(e => this.saveLayoutState(e))); + + // Restore editor if hidden and it changes + this._register(this.editorService.onDidVisibleEditorsChange(() => this.setEditorHidden(false))); + this._register(this.editorPart.onDidActivateGroup(() => this.setEditorHidden(false))); + + // Configuration changes + this._register(this.configurationService.onDidChangeConfiguration(() => this.doUpdateLayoutConfiguration())); + + // Fullscreen changes + this._register(onDidChangeFullscreen(() => this.onFullscreenChanged())); + + // Group changes + this._register(this.editorGroupService.onDidAddGroup(() => this.centerEditorLayout(this.state.editor.centered))); + this._register(this.editorGroupService.onDidRemoveGroup(() => this.centerEditorLayout(this.state.editor.centered))); + + // Prevent workbench from scrolling #55456 + this._register(addDisposableListener(this.workbench, EventType.SCROLL, () => this.workbench.scrollTop = 0)); + + // Menubar visibility changes + if ((isWindows || isLinux) && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { + this._register(this.titlebarPart.onMenubarVisibilityChange(visible => this.onMenubarToggled(visible))); + } + } + + private onMenubarToggled(visible: boolean) { + if (visible !== this.state.menuBar.toggled) { + this.state.menuBar.toggled = visible; + + if (this.state.fullscreen && (this.state.menuBar.visibility === 'toggle' || this.state.menuBar.visibility === 'default')) { + this._onTitleBarVisibilityChange.fire(); + this.layout(); + } + } + } + + private onFullscreenChanged(): void { + this.state.fullscreen = isFullscreen(); + + // Apply as CSS class + if (this.state.fullscreen) { + addClass(this.workbench, 'fullscreen'); + } else { + removeClass(this.workbench, 'fullscreen'); + + if (this.state.zenMode.transitionedToFullScreen && this.state.zenMode.active) { + this.toggleZenMode(); + } + } + + // Changing fullscreen state of the window has an impact on custom title bar visibility, so we need to update + if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { + this._onTitleBarVisibilityChange.fire(); + this.layout(); // handle title bar when fullscreen changes + } + } + + private doUpdateLayoutConfiguration(skipLayout?: boolean): void { // Sidebar Position const newSidebarPositionValue = this.configurationService.getValue(Settings.SIDEBAR_POSITION); @@ -1001,7 +990,10 @@ export class Workbench extends Disposable implements IPartService { this.setMenubarVisibility(newMenubarVisibility, !!skipLayout); } - private initState(): void { + private initLayoutState(): void { + + // Fullscreen + this.state.fullscreen = isFullscreen(); // Menubar visibility this.state.menuBar.visibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); @@ -1010,7 +1002,7 @@ export class Workbench extends Disposable implements IPartService { this.state.activityBar.hidden = !this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); // Sidebar visibility - this.state.sideBar.hidden = this.storageService.getBoolean(State.SIDEBAR_HIDDEN, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); + this.state.sideBar.hidden = this.storageService.getBoolean(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); // Sidebar position this.state.sideBar.position = (this.configurationService.getValue(Settings.SIDEBAR_POSITION) === 'right') ? Position.RIGHT : Position.LEFT; @@ -1035,13 +1027,13 @@ export class Workbench extends Disposable implements IPartService { } // Editor centered layout - this.state.editor.restoreCentered = this.storageService.getBoolean(State.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false); + this.state.editor.restoreCentered = this.storageService.getBoolean(Storage.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false); // Editors to open this.state.editor.editorsToOpen = this.resolveEditorsToOpen(); // Panel visibility - this.state.panel.hidden = this.storageService.getBoolean(State.PANEL_HIDDEN, StorageScope.WORKSPACE, true); + this.state.panel.hidden = this.storageService.getBoolean(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE, true); // Panel position this.setPanelPositionFromStorageOrConfig(); @@ -1067,7 +1059,7 @@ export class Workbench extends Disposable implements IPartService { this.state.statusBar.hidden = !statusBarVisible; // Zen mode enablement - const wasZenActive = this.storageService.getBoolean(State.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false); + const wasZenActive = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false); this.state.zenMode.restore = wasZenActive && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); } @@ -1154,7 +1146,7 @@ export class Workbench extends Disposable implements IPartService { private setPanelPositionFromStorageOrConfig() { const defaultPanelPosition = this.configurationService.getValue(Settings.PANEL_POSITION); - const panelPosition = this.storageService.get(State.PANEL_POSITION, StorageScope.WORKSPACE, defaultPanelPosition); + const panelPosition = this.storageService.get(Storage.PANEL_POSITION, StorageScope.WORKSPACE, defaultPanelPosition); this.state.panel.position = (panelPosition === 'right') ? Position.RIGHT : Position.BOTTOM; } @@ -1198,7 +1190,7 @@ export class Workbench extends Disposable implements IPartService { case Parts.TITLEBAR_PART: if (getTitleBarStyle(this.configurationService, this.environmentService) === 'native') { return false; - } else if (!isFullscreen()) { + } else if (!this.state.fullscreen) { return true; } else if (isMacintosh) { return false; @@ -1272,7 +1264,7 @@ export class Workbench extends Disposable implements IPartService { hideLineNumbers: boolean; } = this.configurationService.getValue('zenMode'); - toggleFullScreen = !isFullscreen() && config.fullScreen; + toggleFullScreen = !this.state.fullscreen && config.fullScreen; this.state.zenMode.transitionedToFullScreen = restoring ? config.fullScreen : toggleFullScreen; this.state.zenMode.transitionedToCenteredEditorLayout = !this.isEditorLayoutCentered() && config.centerLayout; this.state.zenMode.wasSideBarVisible = this.isVisible(Parts.SIDEBAR_PART); @@ -1319,11 +1311,11 @@ export class Workbench extends Disposable implements IPartService { setLineNumbers(this.configurationService.getValue('editor.lineNumbers')); // Status bar and activity bar visibility come from settings -> update their visibility. - this.onDidUpdateConfiguration(true); + this.doUpdateLayoutConfiguration(true); this.editorGroupService.activeGroup.focus(); - toggleFullScreen = this.state.zenMode.transitionedToFullScreen && isFullscreen(); + toggleFullScreen = this.state.zenMode.transitionedToFullScreen && this.state.fullscreen; } if (!skipLayout) { @@ -1512,7 +1504,7 @@ export class Workbench extends Disposable implements IPartService { } centerEditorLayout(active: boolean, skipLayout?: boolean): void { - this.storageService.store(State.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE); + this.storageService.store(Storage.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE); this.state.editor.centered = active; let smartActive = active; @@ -1617,9 +1609,9 @@ export class Workbench extends Disposable implements IPartService { // Remember in settings const defaultHidden = this.contextService.getWorkbenchState() === WorkbenchState.EMPTY; if (hidden !== defaultHidden) { - this.storageService.store(State.SIDEBAR_HIDDEN, hidden ? 'true' : 'false', StorageScope.WORKSPACE); + this.storageService.store(Storage.SIDEBAR_HIDDEN, hidden ? 'true' : 'false', StorageScope.WORKSPACE); } else { - this.storageService.remove(State.SIDEBAR_HIDDEN, StorageScope.WORKSPACE); + this.storageService.remove(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE); } // Layout @@ -1659,9 +1651,9 @@ export class Workbench extends Disposable implements IPartService { // Remember in settings if (!hidden) { - this.storageService.store(State.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE); + this.storageService.store(Storage.PANEL_HIDDEN, 'false', StorageScope.WORKSPACE); } else { - this.storageService.remove(State.PANEL_HIDDEN, StorageScope.WORKSPACE); + this.storageService.remove(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE); } // The editor and panel cannot be hidden at the same time @@ -1779,7 +1771,7 @@ export class Workbench extends Disposable implements IPartService { const newPositionValue = (position === Position.BOTTOM) ? 'bottom' : 'right'; const oldPositionValue = (this.state.panel.position === Position.BOTTOM) ? 'bottom' : 'right'; this.state.panel.position = position; - this.storageService.store(State.PANEL_POSITION, PositionToString(this.state.panel.position).toLowerCase(), StorageScope.WORKSPACE); + this.storageService.store(Storage.PANEL_POSITION, PositionToString(this.state.panel.position).toLowerCase(), StorageScope.WORKSPACE); // Adjust CSS removeClass(this.panelPart.getContainer(), oldPositionValue); @@ -1817,5 +1809,21 @@ export class Workbench extends Disposable implements IPartService { } } + private saveLayoutState(e: IWillSaveStateEvent): void { + + // Zen Mode + if (this.state.zenMode.active) { + this.storageService.store(Storage.ZEN_MODE_ENABLED, true, StorageScope.WORKSPACE); + } else { + this.storageService.remove(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE); + } + + if (e.reason === WillSaveStateReason.SHUTDOWN && this.state.zenMode.active) { + if (!this.configurationService.getValue(Settings.ZEN_MODE_RESTORE)) { + this.toggleZenMode(true); // We will not restore zen mode, need to clear all zen mode state changes + } + } + } + //#endregion } From 4b1c338a8f396d27ed21991b269c5f0eac5916bf Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 4 Mar 2019 17:08:35 +0100 Subject: [PATCH 133/290] improve launch.json schema for serverReady feature --- extensions/debug-server-ready/package.json | 102 ++++++++++++++------- 1 file changed, 69 insertions(+), 33 deletions(-) diff --git a/extensions/debug-server-ready/package.json b/extensions/debug-server-ready/package.json index 7d84a8e27d5..ee66be8012d 100644 --- a/extensions/debug-server-ready/package.json +++ b/extensions/debug-server-ready/package.json @@ -23,41 +23,77 @@ "launch": { "properties": { "serverReadyAction": { - "type": "object", - "markdownDescription": "%debug.server.ready.serverReadyAction.description%", - "default": { - "action": "openExternally" - }, - "properties": { - "pattern": { - "type": "string", - "markdownDescription": "%debug.server.ready.pattern.description%", - "default": "listening on port ([0-9]+)" + "oneOf": [ + { + "type": "object", + "additionalProperties": false, + "markdownDescription": "%debug.server.ready.serverReadyAction.description%", + "default": { + "action": "openExternally" + }, + "properties": { + "action": { + "type": "string", + "enum": [ + "openExternally" + ], + "enumDescriptions": [ + "%debug.server.ready.action.openExternally.description%", + "%debug.server.ready.action.debugWithChrome.description%" + ], + "markdownDescription": "%debug.server.ready.action.description%", + "default": "openExternally" + }, + "pattern": { + "type": "string", + "markdownDescription": "%debug.server.ready.pattern.description%", + "default": "listening on port ([0-9]+)" + }, + "uriFormat": { + "type": "string", + "markdownDescription": "%debug.server.ready.uriFormat.description%", + "default": "http://localhost:%s" + } + } }, - "uriFormat": { - "type": "string", - "markdownDescription": "%debug.server.ready.uriFormat.description%", - "default": "http://localhost:%s" - }, - "action": { - "type": "string", - "enum": [ - "openExternally", - "debugWithChrome" - ], - "enumDescriptions": [ - "%debug.server.ready.action.openExternally.description%", - "%debug.server.ready.action.debugWithChrome.description%" - ], - "markdownDescription": "%debug.server.ready.action.description%", - "default": "openExternally" - }, - "webRoot": { - "type": "string", - "markdownDescription": "%debug.server.ready.webRoot.description%", - "default": "${workspaceFolder}" + { + "type": "object", + "additionalProperties": false, + "markdownDescription": "%debug.server.ready.serverReadyAction.description%", + "default": { + "action": "openExternally" + }, + "properties": { + "action": { + "type": "string", + "enum": [ + "debugWithChrome" + ], + "enumDescriptions": [ + "%debug.server.ready.action.openExternally.description%", + "%debug.server.ready.action.debugWithChrome.description%" + ], + "markdownDescription": "%debug.server.ready.action.description%", + "default": "openExternally" + }, + "pattern": { + "type": "string", + "markdownDescription": "%debug.server.ready.pattern.description%", + "default": "listening on port ([0-9]+)" + }, + "uriFormat": { + "type": "string", + "markdownDescription": "%debug.server.ready.uriFormat.description%", + "default": "http://localhost:%s" + }, + "webRoot": { + "type": "string", + "markdownDescription": "%debug.server.ready.webRoot.description%", + "default": "${workspaceFolder}" + } + } } - } + ] } } } From f8d688f0c5b617f848aa877d4ab6fc06b3a0a912 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 4 Mar 2019 17:43:48 +0100 Subject: [PATCH 134/290] :lipstick: IPartService --- .../workbench/electron-browser/workbench.ts | 158 +++++++++--------- .../services/part/common/partService.ts | 7 - 2 files changed, 75 insertions(+), 90 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 067a2e1489f..d293d8e11b0 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -33,7 +33,7 @@ import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickO import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { QuickInputService } from 'vs/workbench/browser/parts/quickinput/quickInput'; import { getServices } from 'vs/platform/instantiation/common/extensions'; -import { Position, Parts, IPartService, PositionToString, ILayoutOptions } from 'vs/workbench/services/part/common/partService'; +import { Position, Parts, IPartService, ILayoutOptions } from 'vs/workbench/services/part/common/partService'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IStorageService, StorageScope, IWillSaveStateEvent, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { ContextMenuService as HTMLContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; @@ -72,7 +72,6 @@ import { EditorService } from 'vs/workbench/services/editor/browser/editorServic import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { Sizing, Direction, Grid, View } from 'vs/base/browser/ui/grid/grid'; -import { IEditor } from 'vs/editor/common/editorCommon'; import { WorkbenchLegacyLayout } from 'vs/workbench/browser/legacyLayout'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { setARIAContainer } from 'vs/base/browser/ui/aria/aria'; @@ -170,6 +169,8 @@ enum Storage { export class Workbench extends Disposable implements IPartService { + //#region workbench + _serviceBrand: any; private readonly _onShutdown = this._register(new Emitter()); @@ -832,6 +833,8 @@ export class Workbench extends Disposable implements IPartService { this.disposed = true; } + //#endregion + //#region IPartService private readonly _onTitleBarVisibilityChange: Emitter = this._register(new Emitter()); @@ -960,36 +963,76 @@ export class Workbench extends Disposable implements IPartService { private doUpdateLayoutConfiguration(skipLayout?: boolean): void { - // Sidebar Position + // Sidebar position const newSidebarPositionValue = this.configurationService.getValue(Settings.SIDEBAR_POSITION); const newSidebarPosition = (newSidebarPositionValue === 'right') ? Position.RIGHT : Position.LEFT; if (newSidebarPosition !== this.getSideBarPosition()) { this.setSideBarPosition(newSidebarPosition); } - // Panel Position - this.setPanelPositionFromStorageOrConfig(); + // Panel position + this.updatePanelPosition(); if (!this.state.zenMode.active) { - // Statusbar Visibility + // Statusbar visibility const newStatusbarHiddenValue = !this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); if (newStatusbarHiddenValue !== this.state.statusBar.hidden) { this.setStatusBarHidden(newStatusbarHiddenValue, skipLayout); } - // Activitybar Visibility + // Activitybar visibility const newActivityBarHiddenValue = !this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); if (newActivityBarHiddenValue !== this.state.activityBar.hidden) { this.setActivityBarHidden(newActivityBarHiddenValue, skipLayout); } } - // Menubar Visibility + // Menubar visibility const newMenubarVisibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); this.setMenubarVisibility(newMenubarVisibility, !!skipLayout); } + private setSideBarPosition(position: Position): void { + const wasHidden = this.state.sideBar.hidden; + + if (this.state.sideBar.hidden) { + this.setSideBarHidden(false, true /* Skip Layout */); + } + + const newPositionValue = (position === Position.LEFT) ? 'left' : 'right'; + const oldPositionValue = (this.state.sideBar.position === Position.LEFT) ? 'left' : 'right'; + this.state.sideBar.position = position; + + // Adjust CSS + removeClass(this.activitybarPart.getContainer(), oldPositionValue); + removeClass(this.sidebarPart.getContainer(), oldPositionValue); + addClass(this.activitybarPart.getContainer(), newPositionValue); + addClass(this.sidebarPart.getContainer(), newPositionValue); + + // Update Styles + this.activitybarPart.updateStyles(); + this.sidebarPart.updateStyles(); + + // Layout + if (this.workbenchGrid instanceof Grid) { + if (!wasHidden) { + this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView); + } + + this.workbenchGrid.removeView(this.sideBarPartView); + this.workbenchGrid.removeView(this.activityBarPartView); + + if (!this.state.panel.hidden && this.state.panel.position === Position.BOTTOM) { + this.workbenchGrid.removeView(this.panelPartView); + } + + this.layout(); + } else { + this.workbenchGrid.layout(); + } + } + private initLayoutState(): void { // Fullscreen @@ -1036,7 +1079,7 @@ export class Workbench extends Disposable implements IPartService { this.state.panel.hidden = this.storageService.getBoolean(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE, true); // Panel position - this.setPanelPositionFromStorageOrConfig(); + this.updatePanelPosition(); // Panel to restore if (!this.state.panel.hidden) { @@ -1055,12 +1098,10 @@ export class Workbench extends Disposable implements IPartService { } // Statusbar visibility - const statusBarVisible = this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); - this.state.statusBar.hidden = !statusBarVisible; + this.state.statusBar.hidden = !this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); // Zen mode enablement - const wasZenActive = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false); - this.state.zenMode.restore = wasZenActive && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); + this.state.zenMode.restore = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false) && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); } private resolveEditorsToOpen(): Promise | IResourceEditor[] { @@ -1087,7 +1128,7 @@ export class Workbench extends Disposable implements IPartService { } // Empty workbench - else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && this.openUntitledFile()) { + else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && this.configurationService.inspect('workbench.startupEditor').value === 'newUntitledFile') { const isEmpty = this.editorGroupService.count === 1 && this.editorGroupService.activeGroup.count === 0; if (!isEmpty) { return []; // do not open any empty untitled file if we restored editors from previous session @@ -1130,21 +1171,7 @@ export class Workbench extends Disposable implements IPartService { }); } - private openUntitledFile(): boolean { - const startupEditor = this.configurationService.inspect('workbench.startupEditor'); - - // Fallback to previous workbench.welcome.enabled setting in case startupEditor is not defined - if (!startupEditor.user && !startupEditor.workspace) { - const welcomeEnabledValue = this.configurationService.getValue('workbench.welcome.enabled'); - if (typeof welcomeEnabledValue === 'boolean') { - return !welcomeEnabledValue; - } - } - - return startupEditor.value === 'newUntitledFile'; - } - - private setPanelPositionFromStorageOrConfig() { + private updatePanelPosition() { const defaultPanelPosition = this.configurationService.getValue(Settings.PANEL_POSITION); const panelPosition = this.storageService.get(Storage.PANEL_POSITION, StorageScope.WORKSPACE, defaultPanelPosition); @@ -1241,17 +1268,11 @@ export class Workbench extends Disposable implements IPartService { this.state.zenMode.active = !this.state.zenMode.active; this.state.zenMode.transitionDisposeables = dispose(this.state.zenMode.transitionDisposeables); + const setLineNumbers = (lineNumbers: any) => this.editorService.visibleTextEditorWidgets.forEach(editor => editor.updateOptions({ lineNumbers })); + // Check if zen mode transitioned to full screen and if now we are out of zen mode // -> we need to go out of full screen (same goes for the centered editor layout) let toggleFullScreen = false; - const setLineNumbers = (lineNumbers: any) => { - this.editorService.visibleControls.forEach(editor => { - const control = editor.getControl(); - if (control) { - control.updateOptions({ lineNumbers }); - } - }); - }; // Zen Mode Active if (this.state.zenMode.active) { @@ -1265,6 +1286,7 @@ export class Workbench extends Disposable implements IPartService { } = this.configurationService.getValue('zenMode'); toggleFullScreen = !this.state.fullscreen && config.fullScreen; + this.state.zenMode.transitionedToFullScreen = restoring ? config.fullScreen : toggleFullScreen; this.state.zenMode.transitionedToCenteredEditorLayout = !this.isEditorLayoutCentered() && config.centerLayout; this.state.zenMode.wasSideBarVisible = this.isVisible(Parts.SIDEBAR_PART); @@ -1499,14 +1521,19 @@ export class Workbench extends Disposable implements IPartService { } } + private getPanelDimension(position: Position): number | undefined { + return position === Position.BOTTOM ? this.state.panel.height : this.state.panel.width; + } + isEditorLayoutCentered(): boolean { return this.state.editor.centered; } centerEditorLayout(active: boolean, skipLayout?: boolean): void { - this.storageService.store(Storage.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE); this.state.editor.centered = active; + this.storageService.store(Storage.CENTERED_LAYOUT_ENABLED, active, StorageScope.WORKSPACE); + let smartActive = active; if (this.editorPart.groups.length > 1 && this.configurationService.getValue('workbench.editor.centeredLayoutAutoResize')) { smartActive = false; // Respect the auto resize setting - do not go into centered layout if there is more than 1 group. @@ -1695,46 +1722,6 @@ export class Workbench extends Disposable implements IPartService { return this.state.sideBar.position; } - private setSideBarPosition(position: Position): void { - const wasHidden = this.state.sideBar.hidden; - - if (this.state.sideBar.hidden) { - this.setSideBarHidden(false, true /* Skip Layout */); - } - - const newPositionValue = (position === Position.LEFT) ? 'left' : 'right'; - const oldPositionValue = (this.state.sideBar.position === Position.LEFT) ? 'left' : 'right'; - this.state.sideBar.position = position; - - // Adjust CSS - removeClass(this.activitybarPart.getContainer(), oldPositionValue); - removeClass(this.sidebarPart.getContainer(), oldPositionValue); - addClass(this.activitybarPart.getContainer(), newPositionValue); - addClass(this.sidebarPart.getContainer(), newPositionValue); - - // Update Styles - this.activitybarPart.updateStyles(); - this.sidebarPart.updateStyles(); - - // Layout - if (this.workbenchGrid instanceof Grid) { - if (!wasHidden) { - this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView); - } - - this.workbenchGrid.removeView(this.sideBarPartView); - this.workbenchGrid.removeView(this.activityBarPartView); - - if (!this.state.panel.hidden && this.state.panel.position === Position.BOTTOM) { - this.workbenchGrid.removeView(this.panelPartView); - } - - this.layout(); - } else { - this.workbenchGrid.layout(); - } - } - setMenubarVisibility(visibility: MenuBarVisibility, skipLayout: boolean): void { if (this.state.menuBar.visibility !== visibility) { this.state.menuBar.visibility = visibility; @@ -1771,7 +1758,16 @@ export class Workbench extends Disposable implements IPartService { const newPositionValue = (position === Position.BOTTOM) ? 'bottom' : 'right'; const oldPositionValue = (this.state.panel.position === Position.BOTTOM) ? 'bottom' : 'right'; this.state.panel.position = position; - this.storageService.store(Storage.PANEL_POSITION, PositionToString(this.state.panel.position).toLowerCase(), StorageScope.WORKSPACE); + + function positionToString(position: Position): string { + switch (position) { + case Position.LEFT: return 'left'; + case Position.RIGHT: return 'right'; + case Position.BOTTOM: return 'bottom'; + } + } + + this.storageService.store(Storage.PANEL_POSITION, positionToString(this.state.panel.position), StorageScope.WORKSPACE); // Adjust CSS removeClass(this.panelPart.getContainer(), oldPositionValue); @@ -1793,10 +1789,6 @@ export class Workbench extends Disposable implements IPartService { } } - private getPanelDimension(position: Position): number | undefined { - return position === Position.BOTTOM ? this.state.panel.height : this.state.panel.width; - } - private savePanelDimension(): void { if (!(this.workbenchGrid instanceof Grid)) { return; diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index 269ce816af3..6ccd362ba74 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -21,13 +21,6 @@ export const enum Position { RIGHT, BOTTOM } -export function PositionToString(position: Position): string { - switch (position) { - case Position.LEFT: return 'LEFT'; - case Position.RIGHT: return 'RIGHT'; - case Position.BOTTOM: return 'BOTTOM'; - } -} export interface ILayoutOptions { toggleMaximizedPanel?: boolean; From 6c5aadb0c2cd7d8bf182a3888b8f00d2a56a967b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 4 Mar 2019 09:01:18 -0800 Subject: [PATCH 135/290] Re#69258. Another typo. --- src/vs/editor/contrib/dnd/dnd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/dnd/dnd.ts b/src/vs/editor/contrib/dnd/dnd.ts index 6016641bcf5..a716d8fa10d 100644 --- a/src/vs/editor/contrib/dnd/dnd.ts +++ b/src/vs/editor/contrib/dnd/dnd.ts @@ -64,7 +64,7 @@ export class DragAndDropController implements editorCommon.IEditorContribution { this._removeDecoration(); this._dragSelection = null; this._mouseDown = false; - this._modiferPressed = false; + this._modifierPressed = false; } private onEditorKeyDown(e: IKeyboardEvent): void { From 02a6339139d7c0b113cc510cc589aa2ae3bb9127 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 11:35:53 -0800 Subject: [PATCH 136/290] Remove most null supressions --- .../textfile/common/textFileEditorModel.ts | 24 +++++++++++++------ .../common/textFileEditorModelManager.ts | 6 ++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index d492662209f..64f2a50b4dc 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -480,7 +480,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // where `value` was captured in the content change listener closure scope. // Content Change - this._register(this.textEditorModel!.onDidChangeContent(() => this.onModelContentChanged())); + if (this.textEditorModel) { + this._register(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged())); + } } private doLoadBackup(backup: URI | undefined): Promise { @@ -511,7 +513,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // In this case we clear the dirty flag and emit a SAVED event to indicate this state. // Note: we currently only do this check when auto-save is turned off because there you see // a dirty indicator that you want to get rid of when undoing to the saved version. - if (!this.autoSaveAfterMilliesEnabled && this.textEditorModel!.getAlternativeVersionId() === this.bufferSavedVersionId) { + if (!this.autoSaveAfterMilliesEnabled && this.textEditorModel && this.textEditorModel.getAlternativeVersionId() === this.bufferSavedVersionId) { this.logService.trace('onModelContentChanged() - model content changed back to last saved version', this.resource); // Clear flags @@ -642,8 +644,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Push all edit operations to the undo stack so that the user has a chance to // Ctrl+Z back to the saved version. We only do this when auto-save is turned off - if (!this.autoSaveAfterMilliesEnabled) { - this.textEditorModel!.pushStackElement(); + if (!this.autoSaveAfterMilliesEnabled && this.textEditorModel) { + this.textEditorModel.pushStackElement(); } // A save participant can still change the model now and since we are so close to saving @@ -698,7 +700,11 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Save to Disk // mark the save operation as currently pending with the versionId (it might have changed from a save participant triggering) this.logService.trace(`doSave(${versionId}) - before updateContent()`, this.resource); - return this.saveSequentializer.setPending(newVersionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot()!, { + const snapshot = this.createSnapshot(); + if (!snapshot) { + throw new Error('Invalid snapshot'); + } + return this.saveSequentializer.setPending(newVersionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, snapshot, { overwriteReadonly: options.overwriteReadonly, overwriteEncoding: options.overwriteEncoding, mtime: this.lastResolvedDiskStat.mtime, @@ -834,7 +840,11 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil } private doTouch(versionId: number): Promise { - return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, this.createSnapshot()!, { + const snapshot = this.createSnapshot(); + if (!snapshot) { + throw new Error('invalid snapshot'); + } + return this.saveSequentializer.setPending(versionId, this.fileService.updateContent(this.lastResolvedDiskStat.resource, snapshot, { mtime: this.lastResolvedDiskStat.mtime, encoding: this.getEncoding(), etag: this.lastResolvedDiskStat.etag @@ -1120,7 +1130,7 @@ export class SaveSequentializer { this._nextSave.run = run; } - return this._nextSave!.promise; + return this._nextSave.promise; } } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts index f90ff9bc7d6..33dc731d7bb 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts @@ -153,12 +153,12 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE // Model does not exist else { - model = this.instantiationService.createInstance(TextFileEditorModel, resource, options ? options.encoding : undefined); + const newModel = model = this.instantiationService.createInstance(TextFileEditorModel, resource, options ? options.encoding : undefined); modelPromise = model.load(options); // Install state change listener this.mapResourceToStateChangeListener.set(resource, model.onDidStateChange(state => { - const event = new TextFileModelChangeEvent(model!, state); + const event = new TextFileModelChangeEvent(newModel, state); switch (state) { case StateChange.DIRTY: this._onModelDirty.fire(event); @@ -183,7 +183,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE // Install model content change listener this.mapResourceToModelContentChangeListener.set(resource, model.onDidContentChange(e => { - this._onModelContentChanged.fire(new TextFileModelChangeEvent(model!, e)); + this._onModelContentChanged.fire(new TextFileModelChangeEvent(newModel, e)); })); } From 53ac75cd9a1f49927c314ef82c01ca6fcc53bbdf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 12:43:50 -0800 Subject: [PATCH 137/290] Also dispose windows shell helper --- .../contrib/terminal/electron-browser/terminalInstance.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index 709bdfe60bb..b45de738612 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -1254,8 +1254,8 @@ export class TerminalInstance implements ITerminalInstance { // If the title has not been set by the API or the rename command, unregister the handler that // automatically updates the terminal name if (this._messageTitleDisposable) { - lifecycle.dispose(this._messageTitleDisposable); - this._messageTitleDisposable = undefined; + this._messageTitleDisposable = lifecycle.dispose(this._messageTitleDisposable); + this._windowsShellHelper = lifecycle.dispose(this._windowsShellHelper); } } const didTitleChange = title !== this._title; From b8a184d998c1d35a260ed1475013988cc9f624ce Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 12:45:05 -0800 Subject: [PATCH 138/290] Mark windows shell helper as | undefined --- .../contrib/terminal/electron-browser/terminalInstance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index b45de738612..e1ac2cc4a16 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -175,7 +175,7 @@ export class TerminalInstance implements ITerminalInstance { private _cols: number; private _rows: number; private _dimensionsOverride: ITerminalDimensions; - private _windowsShellHelper: WindowsShellHelper; + private _windowsShellHelper: WindowsShellHelper | undefined; private _xtermReadyPromise: Promise; private _titleReadyPromise: Promise; private _titleReadyComplete: (title: string) => any; From fc860b8c0af4af57df6692d7775d81dd4b2fc698 Mon Sep 17 00:00:00 2001 From: Krish De Souza Date: Sun, 3 Mar 2019 02:19:37 +0000 Subject: [PATCH 139/290] Fix for bug 69583 to use a mechanism that is more Linux compatible to get the value of the cwd for the integrated terminal --- .../contrib/terminal/node/terminalProcess.ts | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index fdadec7eda5..3fdb6a7683d 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -7,6 +7,7 @@ import * as os from 'os'; import * as path from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; import * as pty from 'node-pty'; +import * as fs from 'fs'; import { Event, Emitter } from 'vs/base/common/event'; import { ITerminalChildProcess } from 'vs/workbench/contrib/terminal/node/terminal'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -196,18 +197,28 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { } public getCwd(): Promise { - if (platform.isWindows) { + if (platform.isMacintosh) { return new Promise(resolve => { - resolve(this._initialCwd); + exec('lsof -p ' + this._ptyProcess.pid + ' | grep cwd', (error, stdout, stderr) => { + if (stdout !== '') { + resolve(stdout.substring(stdout.indexOf('/'), stdout.length - 1)); + } + }); + }); + } + + if (platform.isLinux) { + return new Promise(resolve => { + fs.readlink('/proc/' + this._ptyProcess.pid + '/cwd', (err, linkedstr) => { + if (linkedstr) { + resolve(linkedstr); + } + }); }); } return new Promise(resolve => { - exec('lsof -p ' + this._ptyProcess.pid + ' | grep cwd', (error, stdout, stderr) => { - if (stdout !== '') { - resolve(stdout.substring(stdout.indexOf('/'), stdout.length - 1)); - } - }); + resolve(this._initialCwd); }); } } From 1eb7e38b6d06e3ed61c443f3362800e939332aaf Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 15:33:48 -0800 Subject: [PATCH 140/290] Correctly set disposables to undefined --- .../terminal/electron-browser/terminalInstance.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index e1ac2cc4a16..f3764101c3a 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -717,7 +717,8 @@ export class TerminalInstance implements ITerminalInstance { public dispose(immediate?: boolean): void { this._logService.trace(`terminalInstance#dispose (id: ${this.id})`); - this._windowsShellHelper = lifecycle.dispose(this._windowsShellHelper); + lifecycle.dispose(this._windowsShellHelper); + this._windowsShellHelper = undefined; this._linkHandler = lifecycle.dispose(this._linkHandler); this._commandTracker = lifecycle.dispose(this._commandTracker); this._widgetManager = lifecycle.dispose(this._widgetManager); @@ -1254,8 +1255,10 @@ export class TerminalInstance implements ITerminalInstance { // If the title has not been set by the API or the rename command, unregister the handler that // automatically updates the terminal name if (this._messageTitleDisposable) { - this._messageTitleDisposable = lifecycle.dispose(this._messageTitleDisposable); - this._windowsShellHelper = lifecycle.dispose(this._windowsShellHelper); + lifecycle.dispose(this._messageTitleDisposable); + lifecycle.dispose(this._windowsShellHelper); + this._messageTitleDisposable = undefined; + this._windowsShellHelper = undefined; } } const didTitleChange = title !== this._title; From da85a2c302021a5d741381426c6603cff355e71a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 15:41:40 -0800 Subject: [PATCH 141/290] Handle error in getCwd for Linux --- src/vs/workbench/contrib/terminal/node/terminalProcess.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index 3fdb6a7683d..fbebae679ee 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -210,9 +210,10 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { if (platform.isLinux) { return new Promise(resolve => { fs.readlink('/proc/' + this._ptyProcess.pid + '/cwd', (err, linkedstr) => { - if (linkedstr) { - resolve(linkedstr); + if (err) { + resolve(this._initialCwd); } + resolve(linkedstr); }); }); } From 0e5614f00287597620702a570441ec8da3613d99 Mon Sep 17 00:00:00 2001 From: Takashi Tamura Date: Tue, 5 Mar 2019 08:44:13 +0900 Subject: [PATCH 142/290] change the message to clarify the intention. --- build/gulpfile.hygiene.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 9ec4d5ef336..187968a95bc 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -228,7 +228,7 @@ function hygiene(some) { let formatted = result.dest.replace(/\r\n/gm, '\n'); if (original !== formatted) { - console.error('File not formatted with tsfmt:', file.relative); + console.error("File not formatted. Run the 'Format Document' command to fix it:", file.relative); errorCount++; } cb(null, file); From d93221d7d5bf30b3161a230909c3c85191139574 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 16:07:52 -0800 Subject: [PATCH 143/290] Strict null check contrib/terminal Fixes #69686 --- .../contrib/terminal/common/terminal.ts | 2 +- .../terminal/common/terminalService.ts | 2 +- .../electron-browser/terminalService.ts | 19 +++++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index d36b3cbeae3..5673030976d 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -251,7 +251,7 @@ export interface ITerminalService { findPrevious(): void; setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; - selectDefaultWindowsShell(): Promise; + selectDefaultWindowsShell(): Promise; setWorkspaceShellAllowed(isAllowed: boolean): void; requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 2af5a375481..ab539243fc7 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -92,7 +92,7 @@ export abstract class TerminalService implements ITerminalService { public abstract createTerminalRenderer(name: string): ITerminalInstance; public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; public abstract getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance; - public abstract selectDefaultWindowsShell(): Promise; + public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index fbace8ec6fb..fcbd99a09b3 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -64,7 +64,10 @@ export class TerminalService extends AbstractTerminalService implements ITermina if (request.termProgram === 'vscode' && request.filesToWait) { pfs.whenDeleted(request.filesToWait.waitMarkerFilePath).then(() => { if (this.terminalInstances.length > 0) { - this.getActiveInstance().focus(); + const terminal = this.getActiveInstance(); + if (terminal) { + terminal.focus(); + } } }); } @@ -215,14 +218,14 @@ export class TerminalService extends AbstractTerminalService implements ITermina ); } - public selectDefaultWindowsShell(): Promise { + public selectDefaultWindowsShell(): Promise { return this._detectWindowsShells().then(shells => { const options: IPickOptions = { placeHolder: nls.localize('terminal.integrated.chooseWindowsShell', "Select your preferred terminal shell, you can change this later in your settings") }; return this._quickInputService.pick(shells, options).then(value => { if (!value) { - return null; + return undefined; } const shell = value.description; return this._configurationService.updateValue('terminal.integrated.shell.windows', shell, ConfigurationTarget.USER).then(() => shell); @@ -270,13 +273,13 @@ export class TerminalService extends AbstractTerminalService implements ITermina }); } - private _validateShellPaths(label: string, potentialPaths: string[]): Promise<[string, string]> { + private _validateShellPaths(label: string, potentialPaths: string[]): Promise<[string, string] | null> { + if (potentialPaths.length === 0) { + return Promise.resolve(null); + } const current = potentialPaths.shift(); - return pfs.fileExists(current).then(exists => { + return pfs.fileExists(current!).then(exists => { if (!exists) { - if (potentialPaths.length === 0) { - return null; - } return this._validateShellPaths(label, potentialPaths); } return [label, current] as [string, string]; From 08f1e188f6e66c8b6f97640069e600bf83e9b708 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 16:29:20 -0800 Subject: [PATCH 144/290] Rename contrib/execution to externalTerminal Part of #69107 --- build/gulpfile.vscode.js | 2 +- build/lib/i18n.resources.json | 4 +- src/tsconfig.strictNullChecks.json | 2 +- .../debug/electron-browser/terminalSupport.ts | 6 +-- .../workbench/contrib/debug/node/terminals.ts | 2 +- .../common/externalTerminal.ts} | 15 +++++++- .../electron-browser/TerminalHelper.scpt | Bin .../externalTerminal.contribution.ts} | 18 ++++----- .../electron-browser/externalTerminal.ts} | 11 ------ .../externalTerminalService.ts} | 36 +++++++++--------- .../electron-browser/iTermHelper.scpt | Bin .../externalTerminalService.test.ts} | 22 +++++------ src/vs/workbench/workbench.main.ts | 2 +- 13 files changed, 60 insertions(+), 60 deletions(-) rename src/vs/workbench/contrib/{execution/common/execution.ts => externalTerminal/common/externalTerminal.ts} (65%) rename src/vs/workbench/contrib/{execution => externalTerminal}/electron-browser/TerminalHelper.scpt (100%) rename src/vs/workbench/contrib/{execution/electron-browser/execution.contribution.ts => externalTerminal/electron-browser/externalTerminal.contribution.ts} (87%) rename src/vs/workbench/contrib/{execution/electron-browser/terminal.ts => externalTerminal/electron-browser/externalTerminal.ts} (90%) rename src/vs/workbench/contrib/{execution/electron-browser/terminalService.ts => externalTerminal/electron-browser/externalTerminalService.ts} (82%) rename src/vs/workbench/contrib/{execution => externalTerminal}/electron-browser/iTermHelper.scpt (100%) rename src/vs/workbench/contrib/{execution/test/electron-browser/terminalService.test.ts => externalTerminal/test/electron-browser/externalTerminalService.test.ts} (86%) diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 1770b2c149d..9c2231119e9 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -69,7 +69,7 @@ const vscodeResources = [ 'out-build/vs/base/browser/ui/octiconLabel/octicons/**', 'out-build/vs/workbench/browser/media/*-theme.css', 'out-build/vs/workbench/contrib/debug/**/*.json', - 'out-build/vs/workbench/contrib/execution/**/*.scpt', + 'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt', 'out-build/vs/workbench/contrib/webview/electron-browser/webview-pre.js', 'out-build/vs/**/markdown.css', 'out-build/vs/workbench/contrib/tasks/**/*.json', diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index dc49b431f87..424fd364c57 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -55,11 +55,11 @@ "project": "vscode-workbench" }, { - "name": "vs/workbench/contrib/execution", + "name": "vs/workbench/contrib/extensions", "project": "vscode-workbench" }, { - "name": "vs/workbench/contrib/extensions", + "name": "vs/workbench/contrib/externalTerminal", "project": "vscode-workbench" }, { diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 7802f41674b..cc45a82aa66 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -14,7 +14,7 @@ "./vs/workbench/browser/parts/quickinput/**/*", "./vs/workbench/electron-browser/actions/**/*", "./vs/workbench/contrib/emmet/**/*", - "./vs/workbench/contrib/execution/**/*", + "./vs/workbench/contrib/externalTerminal/**/*", "./vs/workbench/contrib/snippets/**/*.ts", "./vs/workbench/contrib/welcome/**/*.ts", "./vs/workbench/contrib/issue/**/*", diff --git a/src/vs/workbench/contrib/debug/electron-browser/terminalSupport.ts b/src/vs/workbench/contrib/debug/electron-browser/terminalSupport.ts index 43be1917204..e91e056226a 100644 --- a/src/vs/workbench/contrib/debug/electron-browser/terminalSupport.ts +++ b/src/vs/workbench/contrib/debug/electron-browser/terminalSupport.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { IDisposable } from 'vs/base/common/lifecycle'; import { ITerminalService, ITerminalInstance } from 'vs/workbench/contrib/terminal/common/terminal'; -import { ITerminalService as IExternalTerminalService } from 'vs/workbench/contrib/execution/common/execution'; +import { IExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal'; import { ITerminalLauncher, ITerminalSettings } from 'vs/workbench/contrib/debug/common/debug'; import { hasChildProcesses, prepareCommand } from 'vs/workbench/contrib/debug/node/terminals'; @@ -17,14 +17,14 @@ export class TerminalLauncher implements ITerminalLauncher { constructor( @ITerminalService private readonly terminalService: ITerminalService, - @IExternalTerminalService private readonly nativeTerminalService: IExternalTerminalService + @IExternalTerminalService private readonly externalTerminalService: IExternalTerminalService ) { } runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): Promise { if (args.kind === 'external') { - return this.nativeTerminalService.runInTerminal(args.title, args.cwd, args.args, args.env || {}); + return this.externalTerminalService.runInTerminal(args.title, args.cwd, args.args, args.env || {}); } if (!this.terminalDisposedListener) { diff --git a/src/vs/workbench/contrib/debug/node/terminals.ts b/src/vs/workbench/contrib/debug/node/terminals.ts index d91a788c908..f399b6bb8d9 100644 --- a/src/vs/workbench/contrib/debug/node/terminals.ts +++ b/src/vs/workbench/contrib/debug/node/terminals.ts @@ -129,7 +129,7 @@ class MacTerminalService extends TerminalLauncher { // and then launches the program inside that window. const script = terminalApp === MacTerminalService.DEFAULT_TERMINAL_OSX ? 'TerminalHelper' : 'iTermHelper'; - const scriptpath = getPathFromAmdModule(require, `vs/workbench/contrib/execution/electron-browser/${script}.scpt`); + const scriptpath = getPathFromAmdModule(require, `vs/workbench/contrib/externalTerminal/electron-browser/${script}.scpt`); const osaArgs = [ scriptpath, diff --git a/src/vs/workbench/contrib/execution/common/execution.ts b/src/vs/workbench/contrib/externalTerminal/common/externalTerminal.ts similarity index 65% rename from src/vs/workbench/contrib/execution/common/execution.ts rename to src/vs/workbench/contrib/externalTerminal/common/externalTerminal.ts index 4be8a75555e..8b7f051b339 100644 --- a/src/vs/workbench/contrib/execution/common/execution.ts +++ b/src/vs/workbench/contrib/externalTerminal/common/externalTerminal.ts @@ -6,10 +6,21 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment } from 'vs/base/common/platform'; -export const ITerminalService = createDecorator('nativeTerminalService'); +export const IExternalTerminalService = createDecorator('nativeTerminalService'); -export interface ITerminalService { +export interface IExternalTerminalService { _serviceBrand: any; openTerminal(path: string): void; runInTerminal(title: string, cwd: string, args: string[], env: IProcessEnvironment): Promise; +} + +export interface IExternalTerminalConfiguration { + terminal: { + explorerKind: 'integrated' | 'external', + external: { + linuxExec: string, + osxExec: string, + windowsExec: string + } + }; } \ No newline at end of file diff --git a/src/vs/workbench/contrib/execution/electron-browser/TerminalHelper.scpt b/src/vs/workbench/contrib/externalTerminal/electron-browser/TerminalHelper.scpt similarity index 100% rename from src/vs/workbench/contrib/execution/electron-browser/TerminalHelper.scpt rename to src/vs/workbench/contrib/externalTerminal/electron-browser/TerminalHelper.scpt diff --git a/src/vs/workbench/contrib/execution/electron-browser/execution.contribution.ts b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts similarity index 87% rename from src/vs/workbench/contrib/execution/electron-browser/execution.contribution.ts rename to src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts index b7993790f8c..d72561ce0a0 100644 --- a/src/vs/workbench/contrib/execution/electron-browser/execution.contribution.ts +++ b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts @@ -10,13 +10,13 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import * as paths from 'vs/base/common/path'; import { URI as uri } from 'vs/base/common/uri'; -import { ITerminalService } from 'vs/workbench/contrib/execution/common/execution'; +import { IExternalTerminalConfiguration, IExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { Extensions, IConfigurationRegistry, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { ITerminalService as IIntegratedTerminalService, KEYBINDING_CONTEXT_TERMINAL_NOT_FOCUSED } from 'vs/workbench/contrib/terminal/common/terminal'; -import { getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX, ITerminalConfiguration } from 'vs/workbench/contrib/execution/electron-browser/terminal'; -import { WinTerminalService, MacTerminalService, LinuxTerminalService } from 'vs/workbench/contrib/execution/electron-browser/terminalService'; +import { getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal'; +import { WindowsExternalTerminalService, MacExternalTerminalService, LinuxExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminalService'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { ResourceContextKey } from 'vs/workbench/common/resources'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -29,11 +29,11 @@ import { distinct } from 'vs/base/common/arrays'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; if (env.isWindows) { - registerSingleton(ITerminalService, WinTerminalService, true); + registerSingleton(IExternalTerminalService, WindowsExternalTerminalService, true); } else if (env.isMacintosh) { - registerSingleton(ITerminalService, MacTerminalService, true); + registerSingleton(IExternalTerminalService, MacExternalTerminalService, true); } else if (env.isLinux) { - registerSingleton(ITerminalService, LinuxTerminalService, true); + registerSingleton(IExternalTerminalService, LinuxExternalTerminalService, true); } getDefaultTerminalLinuxReady().then(defaultTerminalLinux => { @@ -87,13 +87,13 @@ CommandsRegistry.registerCommand({ const editorService = accessor.get(IEditorService); const fileService = accessor.get(IFileService); const integratedTerminalService = accessor.get(IIntegratedTerminalService); - const terminalService = accessor.get(ITerminalService); + const terminalService = accessor.get(IExternalTerminalService); const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService); return fileService.resolveFiles(resources.map(r => ({ resource: r }))).then(stats => { const directoriesToOpen = distinct(stats.map(({ stat }) => stat.isDirectory ? stat.resource.fsPath : paths.dirname(stat.resource.fsPath))); return directoriesToOpen.map(dir => { - if (configurationService.getValue().terminal.explorerKind === 'integrated') { + if (configurationService.getValue().terminal.explorerKind === 'integrated') { const instance = integratedTerminalService.createTerminal({ cwd: dir }, true); if (instance && (resources.length === 1 || !resource || dir === resource.fsPath || dir === paths.dirname(resource.fsPath))) { integratedTerminalService.setActiveInstance(instance); @@ -115,7 +115,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ weight: KeybindingWeight.WorkbenchContrib, handler: (accessor) => { const historyService = accessor.get(IHistoryService); - const terminalService = accessor.get(ITerminalService); + const terminalService = accessor.get(IExternalTerminalService); const root = historyService.getLastActiveWorkspaceRoot(Schemas.file); if (root) { terminalService.openTerminal(root.fsPath); diff --git a/src/vs/workbench/contrib/execution/electron-browser/terminal.ts b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.ts similarity index 90% rename from src/vs/workbench/contrib/execution/electron-browser/terminal.ts rename to src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.ts index 64ca19ecb76..ccbfeed874f 100644 --- a/src/vs/workbench/contrib/execution/electron-browser/terminal.ts +++ b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.ts @@ -45,14 +45,3 @@ export function getDefaultTerminalWindows(): string { } return _DEFAULT_TERMINAL_WINDOWS; } - -export interface ITerminalConfiguration { - terminal: { - explorerKind: 'integrated' | 'external', - external: { - linuxExec: string, - osxExec: string, - windowsExec: string - } - }; -} diff --git a/src/vs/workbench/contrib/execution/electron-browser/terminalService.ts b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminalService.ts similarity index 82% rename from src/vs/workbench/contrib/execution/electron-browser/terminalService.ts rename to src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminalService.ts index 0462e10ec86..e463d6893ce 100644 --- a/src/vs/workbench/contrib/execution/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminalService.ts @@ -8,9 +8,9 @@ import * as path from 'vs/base/common/path'; import * as processes from 'vs/base/node/processes'; import * as nls from 'vs/nls'; import { assign } from 'vs/base/common/objects'; -import { ITerminalService } from 'vs/workbench/contrib/execution/common/execution'; +import { IExternalTerminalService, IExternalTerminalConfiguration } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ITerminalConfiguration, getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/execution/electron-browser/terminal'; +import { getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { getPathFromAmdModule } from 'vs/base/common/amd'; @@ -21,7 +21,7 @@ enum WinSpawnType { CMDER } -export class WinTerminalService implements ITerminalService { +export class WindowsExternalTerminalService implements IExternalTerminalService { public _serviceBrand: any; private static readonly CMD = 'cmd.exe'; @@ -32,14 +32,14 @@ export class WinTerminalService implements ITerminalService { } public openTerminal(cwd?: string): void { - const configuration = this._configurationService.getValue(); + const configuration = this._configurationService.getValue(); this.spawnTerminal(cp, configuration, processes.getWindowsShell(), cwd); } public runInTerminal(title: string, dir: string, args: string[], envVars: IProcessEnvironment): Promise { - const configuration = this._configurationService.getValue(); + const configuration = this._configurationService.getValue(); const terminalConfig = configuration.terminal.external; const exec = terminalConfig.windowsExec || getDefaultTerminalWindows(); @@ -64,14 +64,14 @@ export class WinTerminalService implements ITerminalService { windowsVerbatimArguments: true }; - const cmd = cp.spawn(WinTerminalService.CMD, cmdArgs, options); + const cmd = cp.spawn(WindowsExternalTerminalService.CMD, cmdArgs, options); cmd.on('error', e); c(undefined); }); } - private spawnTerminal(spawner, configuration: ITerminalConfiguration, command: string, cwd?: string): Promise { + private spawnTerminal(spawner, configuration: IExternalTerminalConfiguration, command: string, cwd?: string): Promise { const terminalConfig = configuration.terminal.external; const exec = terminalConfig.windowsExec || getDefaultTerminalWindows(); const spawnType = this.getSpawnType(exec); @@ -113,7 +113,7 @@ export class WinTerminalService implements ITerminalService { } } -export class MacTerminalService implements ITerminalService { +export class MacExternalTerminalService implements IExternalTerminalService { public _serviceBrand: any; private static readonly OSASCRIPT = '/usr/bin/osascript'; // osascript is the AppleScript interpreter on OS X @@ -123,14 +123,14 @@ export class MacTerminalService implements ITerminalService { ) { } public openTerminal(cwd?: string): void { - const configuration = this._configurationService.getValue(); + const configuration = this._configurationService.getValue(); this.spawnTerminal(cp, configuration, cwd); } public runInTerminal(title: string, dir: string, args: string[], envVars: IProcessEnvironment): Promise { - const configuration = this._configurationService.getValue(); + const configuration = this._configurationService.getValue(); const terminalConfig = configuration.terminal.external; const terminalApp = terminalConfig.osxExec || DEFAULT_TERMINAL_OSX; @@ -142,7 +142,7 @@ export class MacTerminalService implements ITerminalService { // and then launches the program inside that window. const script = terminalApp === DEFAULT_TERMINAL_OSX ? 'TerminalHelper' : 'iTermHelper'; - const scriptpath = getPathFromAmdModule(require, `vs/workbench/contrib/execution/electron-browser/${script}.scpt`); + const scriptpath = getPathFromAmdModule(require, `vs/workbench/contrib/externalTerminal/electron-browser/${script}.scpt`); const osaArgs = [ scriptpath, @@ -169,7 +169,7 @@ export class MacTerminalService implements ITerminalService { } let stderr = ''; - const osa = cp.spawn(MacTerminalService.OSASCRIPT, osaArgs); + const osa = cp.spawn(MacExternalTerminalService.OSASCRIPT, osaArgs); osa.on('error', e); osa.stderr.on('data', (data) => { stderr += data.toString(); @@ -192,7 +192,7 @@ export class MacTerminalService implements ITerminalService { }); } - private spawnTerminal(spawner, configuration: ITerminalConfiguration, cwd?: string): Promise { + private spawnTerminal(spawner, configuration: IExternalTerminalConfiguration, cwd?: string): Promise { const terminalConfig = configuration.terminal.external; const terminalApp = terminalConfig.osxExec || DEFAULT_TERMINAL_OSX; @@ -204,7 +204,7 @@ export class MacTerminalService implements ITerminalService { } } -export class LinuxTerminalService implements ITerminalService { +export class LinuxExternalTerminalService implements IExternalTerminalService { public _serviceBrand: any; private static readonly WAIT_MESSAGE = nls.localize('press.any.key', "Press any key to continue..."); @@ -215,14 +215,14 @@ export class LinuxTerminalService implements ITerminalService { public openTerminal(cwd?: string): void { - const configuration = this._configurationService.getValue(); + const configuration = this._configurationService.getValue(); this.spawnTerminal(cp, configuration, cwd); } public runInTerminal(title: string, dir: string, args: string[], envVars: IProcessEnvironment): Promise { - const configuration = this._configurationService.getValue(); + const configuration = this._configurationService.getValue(); const terminalConfig = configuration.terminal.external; const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : getDefaultTerminalLinuxReady(); @@ -240,7 +240,7 @@ export class LinuxTerminalService implements ITerminalService { termArgs.push('bash'); termArgs.push('-c'); - const bashCommand = `${quote(args)}; echo; read -p "${LinuxTerminalService.WAIT_MESSAGE}" -n1;`; + const bashCommand = `${quote(args)}; echo; read -p "${LinuxExternalTerminalService.WAIT_MESSAGE}" -n1;`; termArgs.push(`''${bashCommand}''`); // wrapping argument in two sets of ' because node is so "friendly" that it removes one set... // merge environment variables into a copy of the process.env @@ -276,7 +276,7 @@ export class LinuxTerminalService implements ITerminalService { }); } - private spawnTerminal(spawner, configuration: ITerminalConfiguration, cwd?: string): Promise { + private spawnTerminal(spawner, configuration: IExternalTerminalConfiguration, cwd?: string): Promise { const terminalConfig = configuration.terminal.external; const execPromise = terminalConfig.linuxExec ? Promise.resolve(terminalConfig.linuxExec) : getDefaultTerminalLinuxReady(); const env = cwd ? { cwd: cwd } : undefined; diff --git a/src/vs/workbench/contrib/execution/electron-browser/iTermHelper.scpt b/src/vs/workbench/contrib/externalTerminal/electron-browser/iTermHelper.scpt similarity index 100% rename from src/vs/workbench/contrib/execution/electron-browser/iTermHelper.scpt rename to src/vs/workbench/contrib/externalTerminal/electron-browser/iTermHelper.scpt diff --git a/src/vs/workbench/contrib/execution/test/electron-browser/terminalService.test.ts b/src/vs/workbench/contrib/externalTerminal/test/electron-browser/externalTerminalService.test.ts similarity index 86% rename from src/vs/workbench/contrib/execution/test/electron-browser/terminalService.test.ts rename to src/vs/workbench/contrib/externalTerminal/test/electron-browser/externalTerminalService.test.ts index 7795082c1fa..8690ad8ae34 100644 --- a/src/vs/workbench/contrib/execution/test/electron-browser/terminalService.test.ts +++ b/src/vs/workbench/contrib/externalTerminal/test/electron-browser/externalTerminalService.test.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { deepEqual, equal } from 'assert'; -import { WinTerminalService, LinuxTerminalService, MacTerminalService } from 'vs/workbench/contrib/execution/electron-browser/terminalService'; -import { getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/execution/electron-browser/terminal'; +import { WindowsExternalTerminalService, LinuxExternalTerminalService, MacExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminalService'; +import { getDefaultTerminalWindows, getDefaultTerminalLinuxReady, DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal'; -suite('Execution - TerminalService', () => { +suite('ExternalTerminalService', () => { let mockOnExit: Function; let mockOnError: Function; let mockConfig: any; @@ -42,7 +42,7 @@ suite('Execution - TerminalService', () => { }; } }; - let testService = new WinTerminalService(mockConfig); + let testService = new WindowsExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -67,7 +67,7 @@ suite('Execution - TerminalService', () => { } }; mockConfig.terminal.external.windowsExec = undefined; - let testService = new WinTerminalService(mockConfig); + let testService = new WindowsExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -91,7 +91,7 @@ suite('Execution - TerminalService', () => { }; } }; - let testService = new WinTerminalService(mockConfig); + let testService = new WindowsExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -115,7 +115,7 @@ suite('Execution - TerminalService', () => { return { on: (evt: any) => evt }; } }; - let testService = new WinTerminalService(mockConfig); + let testService = new WindowsExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -138,7 +138,7 @@ suite('Execution - TerminalService', () => { }; } }; - let testService = new MacTerminalService(mockConfig); + let testService = new MacExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -161,7 +161,7 @@ suite('Execution - TerminalService', () => { } }; mockConfig.terminal.external.osxExec = undefined; - let testService = new MacTerminalService(mockConfig); + let testService = new MacExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -184,7 +184,7 @@ suite('Execution - TerminalService', () => { }; } }; - let testService = new LinuxTerminalService(mockConfig); + let testService = new LinuxExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, @@ -208,7 +208,7 @@ suite('Execution - TerminalService', () => { } }; mockConfig.terminal.external.linuxExec = undefined; - let testService = new LinuxTerminalService(mockConfig); + let testService = new LinuxExternalTerminalService(mockConfig); (testService).spawnTerminal( mockSpawner, mockConfig, diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 7fc0c7748e1..7a1ce54df5f 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -171,7 +171,7 @@ import 'vs/workbench/contrib/codeEditor/browser/codeEditor.contribution'; import 'vs/workbench/contrib/codeEditor/electron-browser/codeEditor.contribution'; // Execution -import 'vs/workbench/contrib/execution/electron-browser/execution.contribution'; +import 'vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution'; // Snippets import 'vs/workbench/contrib/snippets/browser/snippets.contribution'; From fe169ce4d28fde2a8f71c2d8600c4780b6457e46 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 16:46:45 -0800 Subject: [PATCH 145/290] Move terminalLinkHandler, electron-browser->browser Part of #69115 --- src/tsconfig.strictNullChecks.json | 2 +- .../terminalLinkHandler.ts | 58 +++++++++++++++++-- .../electron-browser/terminalInstance.ts | 2 +- .../terminalLinkHandler.test.ts | 16 ++--- 4 files changed, 62 insertions(+), 16 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/terminalLinkHandler.ts (87%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 7802f41674b..c6deb24a509 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -279,6 +279,7 @@ "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", + "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", "./vs/workbench/contrib/terminal/browser/terminalTab.ts", "./vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts", @@ -290,7 +291,6 @@ "./vs/workbench/contrib/terminal/electron-browser/terminalActions.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", - "./vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts similarity index 87% rename from src/vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler.ts rename to src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index 734d13fd45a..d0c1214879c 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -6,8 +6,7 @@ import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; -import * as pfs from 'vs/base/node/pfs'; -import { URI as Uri } from 'vs/base/common/uri'; +import { URI } from 'vs/base/common/uri'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; @@ -15,7 +14,53 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { ILinkMatcherOptions } from 'vscode-xterm'; +import { IFileService } from 'vs/platform/files/common/files'; + +// Since importing from vscode-xterm would be a layer breakage here the type is copied inline +// import { ILinkMatcherOptions } from 'vscode-xterm'; + +/** + * An object containing options for a link matcher. + */ +export interface ILinkMatcherOptions { + /** + * The index of the link from the regex.match(text) call. This defaults to 0 + * (for regular expressions without capture groups). + */ + matchIndex?: number; + + /** + * A callback that validates whether to create an individual link, pass + * whether the link is valid to the callback. + */ + validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void; + + /** + * A callback that fires when the mouse hovers over a link for a moment. + */ + tooltipCallback?: (event: MouseEvent, uri: string) => boolean | void; + + /** + * A callback that fires when the mouse leaves a link. Note that this can + * happen even when tooltipCallback hasn't fired for the link yet. + */ + leaveCallback?: (event: MouseEvent, uri: string) => boolean | void; + + /** + * The priority of the link matcher, this defines the order in which the link + * matcher is evaluated relative to others, from highest to lowest. The + * default value is 0. + */ + priority?: number; + + /** + * A callback that fires when the mousedown and click events occur that + * determines whether a link will be activated upon click. This enables + * only activating a link when a certain modifier is held down, if not the + * mouse event will continue propagation (eg. double click to select word). + */ + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; +} const pathPrefix = '(\\.\\.?|\\~)'; const pathSeparatorClause = '\\/'; @@ -74,6 +119,7 @@ export class TerminalLinkHandler { @IEditorService private readonly _editorService: IEditorService, @IConfigurationService private readonly _configurationService: IConfigurationService, @ITerminalService private readonly _terminalService: ITerminalService, + @IFileService private readonly _fileService: IFileService ) { const baseLocalLinkClause = _platform === platform.Platform.Windows ? winLocalLinkClause : unixLocalLinkClause; // Append line and column number regex @@ -203,7 +249,7 @@ export class TerminalLinkHandler { if (!normalizedUrl) { return Promise.resolve(null); } - const resource = Uri.file(normalizedUrl); + const resource = URI.file(normalizedUrl); const lineColumnInfo: LineColumnInfo = this.extractLineColumnInfo(link); const selection: ITextEditorSelection = { startLineNumber: lineColumnInfo.lineNumber, @@ -223,7 +269,7 @@ export class TerminalLinkHandler { } private _handleHypertextLink(url: string): void { - const uri = Uri.parse(url); + const uri = URI.parse(url); this._openerService.open(uri); } @@ -288,7 +334,7 @@ export class TerminalLinkHandler { } // Ensure the file exists on disk, so an editor can be opened after clicking it - return pfs.fileExists(linkUrl).then(isFile => { + return this._fileService.existsFile(URI.file(linkUrl)).then(isFile => { if (!isFile) { return null; } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index f3764101c3a..22f9378da7b 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -31,7 +31,7 @@ import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalPr import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; -import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler'; +import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/electron-browser/terminalProcessManager'; import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/node/terminalCommandTracker'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index 99edaab4671..5b708d68123 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Platform } from 'vs/base/common/platform'; -import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/contrib/terminal/electron-browser/terminalLinkHandler'; +import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; import * as strings from 'vs/base/common/strings'; import * as path from 'vs/base/common/path'; import * as sinon from 'sinon'; @@ -39,7 +39,7 @@ interface LinkFormatInfo { suite('Workbench - TerminalLinkHandler', () => { suite('localLinkRegex', () => { test('Windows', () => { - const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Windows, null!, null!, null!, null!); + const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Windows, null!, null!, null!, null!, null!); function testLink(link: string, linkUrl: string, lineNo?: string, columnNo?: string) { assert.equal(terminalLinkHandler.extractLinkUrl(link), linkUrl); assert.equal(terminalLinkHandler.extractLinkUrl(`:${link}:`), linkUrl); @@ -111,7 +111,7 @@ suite('Workbench - TerminalLinkHandler', () => { }); test('Linux', () => { - const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!); + const terminalLinkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!, null!); function testLink(link: string, linkUrl: string, lineNo?: string, columnNo?: string) { assert.equal(terminalLinkHandler.extractLinkUrl(link), linkUrl); assert.equal(terminalLinkHandler.extractLinkUrl(`:${link}:`), linkUrl); @@ -175,7 +175,7 @@ suite('Workbench - TerminalLinkHandler', () => { suite('preprocessPath', () => { test('Windows', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Windows, null!, null!, null!, null!); + const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Windows, null!, null!, null!, null!, null!); linkHandler.processCwd = 'C:\\base'; let stub = sinon.stub(path, 'join', function (arg1: string, arg2: string) { @@ -188,7 +188,7 @@ suite('Workbench - TerminalLinkHandler', () => { stub.restore(); }); test('Windows - spaces', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Windows, null!, null!, null!, null!); + const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Windows, null!, null!, null!, null!, null!); linkHandler.processCwd = 'C:\\base dir'; let stub = sinon.stub(path, 'join', function (arg1: string, arg2: string) { @@ -202,7 +202,7 @@ suite('Workbench - TerminalLinkHandler', () => { }); test('Linux', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!); + const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!, null!); linkHandler.processCwd = '/base'; let stub = sinon.stub(path, 'join', function (arg1: string, arg2: string) { @@ -216,7 +216,7 @@ suite('Workbench - TerminalLinkHandler', () => { }); test('No Workspace', () => { - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!); + const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!, null!); assert.equal(linkHandler.preprocessPath('./src/file1'), null); assert.equal(linkHandler.preprocessPath('src/file2'), null); @@ -226,7 +226,7 @@ suite('Workbench - TerminalLinkHandler', () => { test('gitDiffLinkRegex', () => { // The platform is irrelevant because the links generated by Git are the same format regardless of platform - const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!); + const linkHandler = new TestTerminalLinkHandler(new TestXterm(), Platform.Linux, null!, null!, null!, null!, null!); function assertAreGoodMatches(matches: RegExpMatchArray | null) { if (matches) { From 5d2a154da6e3c0f0e019b91b0e02e17beac74995 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 16:56:26 -0800 Subject: [PATCH 146/290] Add terminal-specific tslint rule to allow vscode-xterm imports --- .../terminal/browser/terminalLinkHandler.ts | 47 +------------------ tslint.json | 7 +++ 2 files changed, 8 insertions(+), 46 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts index d0c1214879c..0c7246a7038 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts @@ -15,52 +15,7 @@ import { ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal' import { ITextEditorSelection } from 'vs/platform/editor/common/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IFileService } from 'vs/platform/files/common/files'; - -// Since importing from vscode-xterm would be a layer breakage here the type is copied inline -// import { ILinkMatcherOptions } from 'vscode-xterm'; - -/** - * An object containing options for a link matcher. - */ -export interface ILinkMatcherOptions { - /** - * The index of the link from the regex.match(text) call. This defaults to 0 - * (for regular expressions without capture groups). - */ - matchIndex?: number; - - /** - * A callback that validates whether to create an individual link, pass - * whether the link is valid to the callback. - */ - validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void; - - /** - * A callback that fires when the mouse hovers over a link for a moment. - */ - tooltipCallback?: (event: MouseEvent, uri: string) => boolean | void; - - /** - * A callback that fires when the mouse leaves a link. Note that this can - * happen even when tooltipCallback hasn't fired for the link yet. - */ - leaveCallback?: (event: MouseEvent, uri: string) => boolean | void; - - /** - * The priority of the link matcher, this defines the order in which the link - * matcher is evaluated relative to others, from highest to lowest. The - * default value is 0. - */ - priority?: number; - - /** - * A callback that fires when the mousedown and click events occur that - * determines whether a link will be activated upon click. This enables - * only activating a link when a certain modifier is held down, if not the - * mouse event will continue propagation (eg. double click to select word). - */ - willLinkActivate?: (event: MouseEvent, uri: string) => boolean; -} +import { ILinkMatcherOptions } from 'vscode-xterm'; const pathPrefix = '(\\.\\.?|\\~)'; const pathSeparatorClause = '\\/'; diff --git a/tslint.json b/tslint.json index 0383001a61b..5365738399a 100644 --- a/tslint.json +++ b/tslint.json @@ -485,6 +485,13 @@ "assert" ] }, + { + "target": "**/vs/workbench/contrib/terminal/browser/**", + "restrictions": [ + "vscode-xterm", + "**/vs/**" + ] + }, { "target": "**/vs/code/node/**", "restrictions": [ From 8afa7773d5237bcfd8602d6afb2f5a92c6c21b57 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 17:16:21 -0800 Subject: [PATCH 147/290] Remove os dep in terminalEnvironment --- .../api/node/extHostTerminalService.ts | 3 ++- .../terminal/browser/terminalService.ts | 25 +++++++++++++++++++ .../terminal/common/terminalService.ts | 9 +++++-- .../terminalProcessManager.ts | 4 ++- .../electron-browser/terminalService.ts | 13 ++-------- .../terminal/node/terminalEnvironment.ts | 5 ++-- .../test/node/terminalEnvironment.test.ts | 23 ++++++++--------- 7 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 src/vs/workbench/contrib/terminal/browser/terminalService.ts diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 4e10c68feb2..156d7ad5c82 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import * as os from 'os'; import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; @@ -429,7 +430,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // TODO: @daniel const activeWorkspaceRootUri = URI.revive(activeWorkspaceRootUriComponents); - const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, activeWorkspaceRootUri, terminalConfig.cwd); + const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, os.homedir(), activeWorkspaceRootUri, terminalConfig.cwd); // TODO: Pull in and resolve config settings // // Resolve env vars from config and shell diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts new file mode 100644 index 00000000000..060ce2863aa --- /dev/null +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.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 { ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TerminalService as CommonTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; +import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IStorageService } from 'vs/platform/storage/common/storage'; + +export abstract class TerminalService extends CommonTerminalService implements ITerminalService { + + constructor( + @IContextKeyService contextKeyService: IContextKeyService, + @IPanelService panelService: IPanelService, + @IPartService partService: IPartService, + @ILifecycleService lifecycleService: ILifecycleService, + @IStorageService storageService: IStorageService + ) { + super(contextKeyService, panelService, partService, lifecycleService, storageService); + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 2af5a375481..ab3e50b1885 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -21,7 +21,9 @@ export abstract class TerminalService implements ITerminalService { protected _findWidgetVisible: IContextKey; protected _terminalContainer: HTMLElement; protected _terminalTabs: ITerminalTab[]; - protected abstract _terminalInstances: ITerminalInstance[]; + protected get _terminalInstances(): ITerminalInstance[] { + return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); + } private _findState: FindReplaceState; private _activeTabIndex: number; @@ -89,13 +91,16 @@ export abstract class TerminalService implements ITerminalService { protected abstract _showTerminalCloseConfirmation(): Promise; protected abstract _showNotEnoughSpaceToast(): void; public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance; - public abstract createTerminalRenderer(name: string): ITerminalInstance; public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; public abstract getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance; public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; + public createTerminalRenderer(name: string): ITerminalInstance { + return this.createTerminal({ name, isRendererOnly: true }); + } + private _onBeforeShutdown(): boolean | Promise { if (this.terminalInstances.length === 0) { // No terminal instances, don't veto diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts index a3fa9af9e3d..786c7f7f2f8 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts @@ -21,6 +21,7 @@ import { Schemas } from 'vs/base/common/network'; import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { sanitizeProcessEnvironment } from 'vs/base/node/processes'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -61,6 +62,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService, @IWindowService private readonly _windowService: IWindowService, @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, + @IEnvironmentService private readonly _environmentSertvice: IEnvironmentService ) { this.ptyProcessReady = new Promise(c => { this.onProcessReady(() => { @@ -110,7 +112,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { } const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); - const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, activeWorkspaceRootUri, this._configHelper.config.cwd); + const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentSertvice.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd); // Compel type system as process.env should not have any undefined entries let env: platform.IProcessEnvironment = {}; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index fbace8ec6fb..f916502d8f5 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -13,7 +13,7 @@ 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 { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, TERMINAL_PANEL_ID, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; -import { TerminalService as AbstractTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; +import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; import Severity from 'vs/base/common/severity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; @@ -30,15 +30,10 @@ import { URI } from 'vs/base/common/uri'; import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; import { coalesce } from 'vs/base/common/arrays'; -export class TerminalService extends AbstractTerminalService implements ITerminalService { +export class TerminalService extends BrowserTerminalService implements ITerminalService { private _configHelper: TerminalConfigHelper; public get configHelper(): ITerminalConfigHelper { return this._configHelper; } - protected _terminalTabs: TerminalTab[]; - protected get _terminalInstances(): ITerminalInstance[] { - return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); - } - constructor( @IContextKeyService contextKeyService: IContextKeyService, @IPanelService panelService: IPanelService, @@ -98,10 +93,6 @@ export class TerminalService extends AbstractTerminalService implements ITermina return instance; } - public createTerminalRenderer(name: string): ITerminalInstance { - return this.createTerminal({ name, isRendererOnly: true }); - } - public createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance { const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig); this._onInstanceCreated.fire(instance); diff --git a/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts index 612ea746d21..668ec2ef2ac 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; import * as path from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; import pkg from 'vs/platform/product/node/package'; @@ -102,7 +101,7 @@ function _getLangEnvVariable(locale?: string) { return parts.join('_') + '.UTF-8'; } -export function getCwd(shell: IShellLaunchConfig, root?: Uri, customCwd?: string): string { +export function getCwd(shell: IShellLaunchConfig, userHome: string, root?: Uri, customCwd?: string): string { if (shell.cwd) { return (typeof shell.cwd === 'object') ? shell.cwd.fsPath : shell.cwd; } @@ -120,7 +119,7 @@ export function getCwd(shell: IShellLaunchConfig, root?: Uri, customCwd?: string // If there was no custom cwd or it was relative with no workspace if (!cwd) { - cwd = root ? root.fsPath : os.homedir(); + cwd = root ? root.fsPath : userHome; } return _sanitizeCwd(cwd); diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 0f9ecc1299a..1549d0b2e56 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as os from 'os'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; import { URI as Uri } from 'vs/base/common/uri'; @@ -101,32 +100,32 @@ suite('Workbench - TerminalEnvironment', () => { assert.equal(Uri.file(a).fsPath, Uri.file(b).fsPath); } - test('should default to os.homedir() for an empty workspace', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, undefined), os.homedir()); + test('should default to userHome for an empty workspace', () => { + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined), '/userHome/'); }); test('should use to the workspace if it exists', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/foo'), undefined), '/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/foo'), undefined), '/foo'); }); test('should use an absolute custom cwd as is', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, '/foo'), '/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '/foo'), '/foo'); }); test('should normalize a relative custom cwd against the workspace path', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/bar'), 'foo'), '/bar/foo'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/bar'), './foo'), '/bar/foo'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, Uri.file('/bar'), '../foo'), '/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), 'foo'), '/bar/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), './foo'), '/bar/foo'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', Uri.file('/bar'), '../foo'), '/foo'); }); test('should fall back for relative a custom cwd that doesn\'t have a workspace', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, 'foo'), os.homedir()); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, './foo'), os.homedir()); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, undefined, '../foo'), os.homedir()); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, 'foo'), '/userHome/'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, './foo'), '/userHome/'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, '../foo'), '/userHome/'); }); test('should ignore custom cwd when told to ignore', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, Uri.file('/bar'), '/foo'), '/bar'); + assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', Uri.file('/bar'), '/foo'), '/bar'); }); }); From badedf5d7d88fbb3adef5cd43c7a2cc9ad06a586 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 17:22:46 -0800 Subject: [PATCH 148/290] Move terminalEnvironment, node->common Part of #69115 --- src/tsconfig.strictNullChecks.json | 2 +- src/vs/workbench/api/node/extHostTerminalService.ts | 5 +++-- .../terminal/{node => common}/terminalEnvironment.ts | 5 ++--- .../terminal/electron-browser/terminalPanel.ts | 2 +- .../electron-browser/terminalProcessManager.ts | 10 ++++++---- .../terminal/test/node/terminalEnvironment.test.ts | 12 ++++++------ 6 files changed, 19 insertions(+), 17 deletions(-) rename src/vs/workbench/contrib/terminal/{node => common}/terminalEnvironment.ts (96%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 7412a04e395..6d5d4e9b370 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -286,6 +286,7 @@ "./vs/workbench/contrib/terminal/common/terminal.ts", "./vs/workbench/contrib/terminal/common/terminalColorRegistry.ts", "./vs/workbench/contrib/terminal/common/terminalCommands.ts", + "./vs/workbench/contrib/terminal/common/terminalEnvironment.ts", "./vs/workbench/contrib/terminal/common/terminalMenu.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalActions.ts", @@ -295,7 +296,6 @@ "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalCommandTracker.ts", - "./vs/workbench/contrib/terminal/node/terminalEnvironment.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", "./vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts", "./vs/workbench/contrib/terminal/node/windowsShellHelper.ts", diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 156d7ad5c82..6f80fc77c38 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -4,10 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; +import pkg from 'vs/platform/product/node/package'; import * as os from 'os'; import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; -import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; +import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Event, Emitter } from 'vs/base/common/event'; import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/node/extHost.protocol'; import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration'; @@ -451,7 +452,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Continue env initialization, merging in the env from the launch // config and adding keys that are needed to create the process - terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, terminalConfig.get('setLocaleVariables')); + terminalEnvironment.addTerminalEnvironmentKeys(env, pkg.version, platform.locale, terminalConfig.get('setLocaleVariables')); // Fork the process and listen for messages this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env); diff --git a/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts similarity index 96% rename from src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts rename to src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 668ec2ef2ac..cf8e7fab850 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -5,7 +5,6 @@ import * as path from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; -import pkg from 'vs/platform/product/node/package'; import { URI as Uri } from 'vs/base/common/uri'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -50,9 +49,9 @@ function _mergeEnvironmentValue(env: ITerminalEnvironment, key: string, value: s } } -export function addTerminalEnvironmentKeys(env: ITerminalEnvironment, locale: string | undefined, setLocaleVariables: boolean): void { +export function addTerminalEnvironmentKeys(env: ITerminalEnvironment, version: string | undefined, locale: string | undefined, setLocaleVariables: boolean): void { env['TERM_PROGRAM'] = 'vscode'; - env['TERM_PROGRAM_VERSION'] = pkg.version; + env['TERM_PROGRAM_VERSION'] = version ? version : null; if (setLocaleVariables) { env['LANG'] = _getLangEnvVariable(locale); } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts index b4e7019e896..7d301112c40 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts @@ -6,7 +6,7 @@ import * as dom from 'vs/base/browser/dom'; import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; -import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; +import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Action, IAction } from 'vs/base/common/actions'; import { IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts index 786c7f7f2f8..0a9923779e8 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as platform from 'vs/base/common/platform'; -import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; +import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { ILogService } from 'vs/platform/log/common/log'; @@ -22,6 +22,7 @@ import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/commo import { sanitizeProcessEnvironment } from 'vs/base/node/processes'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IProductService } from 'vs/platform/product/common/product'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -62,7 +63,8 @@ export class TerminalProcessManager implements ITerminalProcessManager { @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService, @IWindowService private readonly _windowService: IWindowService, @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, - @IEnvironmentService private readonly _environmentSertvice: IEnvironmentService + @IEnvironmentService private readonly _environmentService: IEnvironmentService, + @IProductService private readonly _productService: IProductService ) { this.ptyProcessReady = new Promise(c => { this.onProcessReady(() => { @@ -112,7 +114,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { } const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); - const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentSertvice.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd); + const initialCwd = terminalEnvironment.getCwd(shellLaunchConfig, this._environmentService.userHome, activeWorkspaceRootUri, this._configHelper.config.cwd); // Compel type system as process.env should not have any undefined entries let env: platform.IProcessEnvironment = {}; @@ -143,7 +145,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI'); // Adding other env keys necessary to create the process - terminalEnvironment.addTerminalEnvironmentKeys(env, platform.locale, this._configHelper.config.setLocaleVariables); + terminalEnvironment.addTerminalEnvironmentKeys(env, this._productService.version, platform.locale, this._configHelper.config.setLocaleVariables); } this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env); diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 1549d0b2e56..6153a741193 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as platform from 'vs/base/common/platform'; -import * as terminalEnvironment from 'vs/workbench/contrib/terminal/node/terminalEnvironment'; +import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { URI as Uri } from 'vs/base/common/uri'; import { IStringDictionary } from 'vs/base/common/collections'; @@ -13,21 +13,21 @@ suite('Workbench - TerminalEnvironment', () => { test('addTerminalEnvironmentKeys', () => { const env = { FOO: 'bar' }; const locale = 'en-au'; - terminalEnvironment.addTerminalEnvironmentKeys(env, locale, true); + terminalEnvironment.addTerminalEnvironmentKeys(env, '1.2.3', locale, true); assert.equal(env['TERM_PROGRAM'], 'vscode'); - assert.equal(env['TERM_PROGRAM_VERSION'].search(/^\d+\.\d+\.\d+$/), 0); + assert.equal(env['TERM_PROGRAM_VERSION'], '1.2.3'); assert.equal(env['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8'); const env2 = { FOO: 'bar' }; - terminalEnvironment.addTerminalEnvironmentKeys(env2, undefined, true); + terminalEnvironment.addTerminalEnvironmentKeys(env2, '1.2.3', undefined, true); assert.equal(env2['LANG'], 'en_US.UTF-8', 'LANG is equal to en_US.UTF-8 as fallback.'); // More info on issue #14586 const env3 = { LANG: 'replace' }; - terminalEnvironment.addTerminalEnvironmentKeys(env3, undefined, true); + terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, true); assert.equal(env3['LANG'], 'en_US.UTF-8', 'LANG is set to the fallback LANG'); const env4 = { LANG: 'en_US.UTF-8' }; - terminalEnvironment.addTerminalEnvironmentKeys(env3, undefined, true); + terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, true); assert.equal(env4['LANG'], 'en_US.UTF-8', 'LANG is equal to the parent environment\'s LANG'); }); From 5b7bdaccdecbab4d19521369dc2d5f65cb094db4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 17:31:58 -0800 Subject: [PATCH 149/290] Move terminalActions, electron-browser->browser Part of #69115 --- src/tsconfig.strictNullChecks.json | 2 +- .../terminal/{electron-browser => browser}/terminalActions.ts | 4 ++-- .../terminal/electron-browser/terminal.contribution.ts | 2 +- .../contrib/terminal/electron-browser/terminalPanel.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/terminalActions.ts (99%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 6d5d4e9b370..19a576445ba 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -278,6 +278,7 @@ "./vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts", "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", + "./vs/workbench/contrib/terminal/browser/terminalActions.ts", "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", @@ -289,7 +290,6 @@ "./vs/workbench/contrib/terminal/common/terminalEnvironment.ts", "./vs/workbench/contrib/terminal/common/terminalMenu.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", - "./vs/workbench/contrib/terminal/electron-browser/terminalActions.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts", diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts similarity index 99% rename from src/vs/workbench/contrib/terminal/electron-browser/terminalActions.ts rename to src/vs/workbench/contrib/terminal/browser/terminalActions.ts index a202076042b..ea11c54029c 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import * as os from 'os'; import { Action, IAction } from 'vs/base/common/actions'; import { EndOfLinePreference } from 'vs/editor/common/model'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -34,6 +33,7 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { Schemas } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; +import { isWindows } from 'vs/base/common/platform'; export const TERMINAL_PICKER_PREFIX = 'term '; @@ -659,7 +659,7 @@ export class RunSelectedTextInTerminalAction extends Action { if (selection.isEmpty()) { text = editor.getModel().getLineContent(selection.selectionStartLineNumber).trim(); } else { - const endOfLinePreference = os.EOL === '\n' ? EndOfLinePreference.LF : EndOfLinePreference.CRLF; + const endOfLinePreference = isWindows ? EndOfLinePreference.LF : EndOfLinePreference.CRLF; text = editor.getModel().getValueInRange(selection, endOfLinePreference); } instance.sendText(text, true); diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index b15ee85b95b..562568064b1 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -16,7 +16,7 @@ import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { KillTerminalAction, ClearSelectionTerminalAction, CopyTerminalSelectionAction, CreateNewTerminalAction, CreateNewInActiveWorkspaceTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ToggleTerminalAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand, RenameTerminalAction, SelectAllTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, TERMINAL_PICKER_PREFIX, MoveToLineStartTerminalAction, MoveToLineEndTerminalAction, SplitTerminalAction, SplitInActiveWorkspaceTerminalAction, FocusPreviousPaneTerminalAction, FocusNextPaneTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, ResizePaneDownTerminalAction, ScrollToPreviousCommandAction, ScrollToNextCommandAction, SelectToPreviousCommandAction, SelectToNextCommandAction, SelectToPreviousLineAction, SelectToNextLineAction, ToggleEscapeSequenceLoggingAction, SendSequenceTerminalCommand, ToggleRegexCommand, ToggleWholeWordCommand, ToggleCaseSensitiveCommand, FindNext, FindPrevious, DeleteToLineStartTerminalAction } from 'vs/workbench/contrib/terminal/electron-browser/terminalActions'; +import { ClearSelectionTerminalAction, CreateNewTerminalAction, CreateNewInActiveWorkspaceTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand, RenameTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, MoveToLineStartTerminalAction, MoveToLineEndTerminalAction, SplitTerminalAction, SplitInActiveWorkspaceTerminalAction, FocusPreviousPaneTerminalAction, FocusNextPaneTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, ResizePaneDownTerminalAction, ScrollToPreviousCommandAction, ScrollToNextCommandAction, SelectToPreviousCommandAction, SelectToNextCommandAction, SelectToPreviousLineAction, SelectToNextLineAction, ToggleEscapeSequenceLoggingAction, SendSequenceTerminalCommand, ToggleRegexCommand, ToggleWholeWordCommand, ToggleCaseSensitiveCommand, FindNext, FindPrevious, DeleteToLineStartTerminalAction, TERMINAL_PICKER_PREFIX, KillTerminalAction, CopyTerminalSelectionAction, SelectAllTerminalAction, ToggleTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { TerminalService } from 'vs/workbench/contrib/terminal/electron-browser/terminalService'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts index 7d301112c40..036053299f8 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts @@ -17,7 +17,7 @@ import { ITerminalService, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/termin import { IThemeService, ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { TerminalFindWidget } from 'vs/workbench/contrib/terminal/browser/terminalFindWidget'; import { editorHoverBackground, editorHoverBorder, editorForeground } from 'vs/platform/theme/common/colorRegistry'; -import { KillTerminalAction, SwitchTerminalAction, SwitchTerminalActionItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction, SelectAllTerminalAction, CreateNewTerminalAction, SplitTerminalAction } from 'vs/workbench/contrib/terminal/electron-browser/terminalActions'; +import { KillTerminalAction, SwitchTerminalAction, SwitchTerminalActionItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction, SelectAllTerminalAction, CreateNewTerminalAction, SplitTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; import { Panel } from 'vs/workbench/browser/panel'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { URI } from 'vs/base/common/uri'; From 3760c273fa12e6b89274049bb546fd013ae21ec5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 17:34:36 -0800 Subject: [PATCH 150/290] Move terminalPanel, electron-browser->browser Part of #69115 --- src/tsconfig.strictNullChecks.json | 2 +- .../terminalPanel.ts | 15 ++++++--------- .../workbench/contrib/terminal/common/terminal.ts | 1 + .../electron-browser/terminal.contribution.ts | 2 +- .../terminal/electron-browser/terminalService.ts | 2 +- src/vs/workbench/workbench.main.ts | 2 +- 6 files changed, 11 insertions(+), 13 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/terminalPanel.ts (96%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 19a576445ba..41f71cf9d5c 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -281,6 +281,7 @@ "./vs/workbench/contrib/terminal/browser/terminalActions.ts", "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", + "./vs/workbench/contrib/terminal/browser/terminalPanel.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", "./vs/workbench/contrib/terminal/browser/terminalTab.ts", "./vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts", @@ -292,7 +293,6 @@ "./vs/workbench/contrib/terminal/common/terminalService.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", - "./vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalCommandTracker.ts", diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts similarity index 96% rename from src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts rename to src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index 036053299f8..60286fd0e37 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -24,7 +24,6 @@ import { URI } from 'vs/base/common/uri'; import { TERMINAL_BACKGROUND_COLOR, TERMINAL_BORDER_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { DataTransfers } from 'vs/base/browser/dnd'; import { INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification'; -import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; import { IStorageService } from 'vs/platform/storage/common/storage'; const FIND_FOCUS_CLASS = 'find-focused'; @@ -82,14 +81,12 @@ export class TerminalPanel extends Panel { if (e.affectsConfiguration('terminal.integrated.fontFamily') || e.affectsConfiguration('editor.fontFamily')) { const configHelper = this._terminalService.configHelper; - if (configHelper instanceof TerminalConfigHelper) { - if (!configHelper.configFontIsMonospace()) { - const choices: IPromptChoice[] = [{ - label: nls.localize('terminal.useMonospace', "Use 'monospace'"), - run: () => this._configurationService.updateValue('terminal.integrated.fontFamily', 'monospace'), - }]; - this._notificationService.prompt(Severity.Warning, nls.localize('terminal.monospaceOnly', "The terminal only supports monospace fonts."), choices); - } + if (!configHelper.configFontIsMonospace()) { + const choices: IPromptChoice[] = [{ + label: nls.localize('terminal.useMonospace', "Use 'monospace'"), + run: () => this._configurationService.updateValue('terminal.integrated.fontFamily', 'monospace'), + }]; + this._notificationService.prompt(Severity.Warning, nls.localize('terminal.monospaceOnly', "The terminal only supports monospace fonts."), choices); } } })); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 5673030976d..57217bb480c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -107,6 +107,7 @@ export interface ITerminalConfiguration { export interface ITerminalConfigHelper { config: ITerminalConfiguration; + configFontIsMonospace(): boolean; getFont(): ITerminalFont; /** * Merges the default shell path and args into the provided launch configuration diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index 562568064b1..e703212b0b4 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -28,7 +28,7 @@ import { getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/qu import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actions'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { TerminalPanel } from 'vs/workbench/contrib/terminal/electron-browser/terminalPanel'; +import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; import { setupTerminalCommands, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminalMenu'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index 1914cf4af95..aa6c650d924 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -18,7 +18,7 @@ import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-bro import Severity from 'vs/base/common/severity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; -import { TerminalPanel } from 'vs/workbench/contrib/terminal/electron-browser/terminalPanel'; +import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 7a1ce54df5f..84ed6ce8f02 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -154,7 +154,7 @@ import 'vs/workbench/contrib/output/browser/outputPanel'; // Terminal import 'vs/workbench/contrib/terminal/electron-browser/terminal.contribution'; import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; -import 'vs/workbench/contrib/terminal/electron-browser/terminalPanel'; +import 'vs/workbench/contrib/terminal/browser/terminalPanel'; // Relauncher import 'vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution'; From 2675ffeaafa5b91dd2102795543cde8e8f4d6075 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 17:39:47 -0800 Subject: [PATCH 151/290] Move parts of terminalService up to common/browser --- .../terminal/browser/terminalService.ts | 44 ++++++++++++- .../terminal/common/terminalService.ts | 33 ++++++++-- .../electron-browser/terminalService.ts | 65 ++----------------- 3 files changed, 74 insertions(+), 68 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 060ce2863aa..7bf4664b9e6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -3,13 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as CommonTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IStorageService } from 'vs/platform/storage/common/storage'; +import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { INotificationService } from 'vs/platform/notification/common/notification'; export abstract class TerminalService extends CommonTerminalService implements ITerminalService { @@ -18,8 +21,43 @@ export abstract class TerminalService extends CommonTerminalService implements I @IPanelService panelService: IPanelService, @IPartService partService: IPartService, @ILifecycleService lifecycleService: ILifecycleService, - @IStorageService storageService: IStorageService + @IStorageService storageService: IStorageService, + @INotificationService notificationService: INotificationService, + @IDialogService dialogService: IDialogService ) { - super(contextKeyService, panelService, partService, lifecycleService, storageService); + super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService); + } + + public focusFindWidget(): Promise { + return this.showPanel(false).then(() => { + const panel = this._panelService.getActivePanel() as TerminalPanel; + panel.focusFindWidget(); + this._findWidgetVisible.set(true); + }); + } + + public hideFindWidget(): void { + const panel = this._panelService.getActivePanel() as TerminalPanel; + if (panel && panel.getId() === TERMINAL_PANEL_ID) { + panel.hideFindWidget(); + this._findWidgetVisible.reset(); + panel.focus(); + } + } + + public findNext(): void { + const panel = this._panelService.getActivePanel() as TerminalPanel; + if (panel && panel.getId() === TERMINAL_PANEL_ID) { + panel.showFindWidget(); + panel.getFindWidget().find(false); + } + } + + public findPrevious(): void { + const panel = this._panelService.getActivePanel() as TerminalPanel; + if (panel && panel.getId() === TERMINAL_PANEL_ID) { + panel.showFindWidget(); + panel.getFindWidget().find(true); + } } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 792ffad09b7..1999fd8a6ec 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vs/nls'; import { Event, Emitter } from 'vs/base/common/event'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; @@ -12,6 +13,8 @@ import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfi import { IStorageService } from 'vs/platform/storage/common/storage'; import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; +import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -60,7 +63,9 @@ export abstract class TerminalService implements ITerminalService { @IPanelService protected readonly _panelService: IPanelService, @IPartService private readonly _partService: IPartService, @ILifecycleService lifecycleService: ILifecycleService, - @IStorageService protected readonly _storageService: IStorageService + @IStorageService protected readonly _storageService: IStorageService, + @INotificationService protected readonly _notificationService: INotificationService, + @IDialogService private readonly _dialogService: IDialogService ) { this._activeTabIndex = 0; this._isShuttingDown = false; @@ -88,11 +93,8 @@ export abstract class TerminalService implements ITerminalService { this.onInstancesChanged(() => updateTerminalContextKeys()); } - protected abstract _showTerminalCloseConfirmation(): Promise; - protected abstract _showNotEnoughSpaceToast(): void; public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance; public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; - public abstract getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance; public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; @@ -101,6 +103,11 @@ export abstract class TerminalService implements ITerminalService { return this.createTerminal({ name, isRendererOnly: true }); } + public getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance { + const activeInstance = this.getActiveInstance(); + return activeInstance ? activeInstance : this.createTerminal(undefined, wasNewTerminalAction); + } + private _onBeforeShutdown(): boolean | Promise { if (this.terminalInstances.length === 0) { // No terminal instances, don't veto @@ -373,4 +380,22 @@ export abstract class TerminalService implements ITerminalService { public setWorkspaceShellAllowed(isAllowed: boolean): void { this.configHelper.setWorkspaceShellAllowed(isAllowed); } + + protected _showTerminalCloseConfirmation(): Promise { + let message; + if (this.terminalInstances.length === 1) { + message = nls.localize('terminalService.terminalCloseConfirmationSingular', "There is an active terminal session, do you want to kill it?"); + } else { + message = nls.localize('terminalService.terminalCloseConfirmationPlural', "There are {0} active terminal sessions, do you want to kill them?", this.terminalInstances.length); + } + + return this._dialogService.confirm({ + message, + type: 'warning', + }).then(res => !res.confirmed); + } + + protected _showNotEnoughSpaceToast(): void { + this._notificationService.info(nls.localize('terminal.minWidth', "Not enough space to split terminal.")); + } } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index aa6c650d924..b2739f6b45a 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -12,13 +12,12 @@ 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 { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, TERMINAL_PANEL_ID, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; import Severity from 'vs/base/common/severity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; -import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -43,12 +42,12 @@ export class TerminalService extends BrowserTerminalService implements ITerminal @IConfigurationService private readonly _configurationService: IConfigurationService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IQuickInputService private readonly _quickInputService: IQuickInputService, - @INotificationService private readonly _notificationService: INotificationService, - @IDialogService private readonly _dialogService: IDialogService, + @INotificationService notificationService: INotificationService, + @IDialogService dialogService: IDialogService, @IExtensionService private readonly _extensionService: IExtensionService, @IWindowService private readonly _windowService: IWindowService, ) { - super(contextKeyService, panelService, partService, lifecycleService, storageService); + super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService); this._terminalTabs = []; this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper); @@ -112,39 +111,6 @@ export class TerminalService extends BrowserTerminalService implements ITerminal }); } - public focusFindWidget(): Promise { - return this.showPanel(false).then(() => { - const panel = this._panelService.getActivePanel() as TerminalPanel; - panel.focusFindWidget(); - this._findWidgetVisible.set(true); - }); - } - - public hideFindWidget(): void { - const panel = this._panelService.getActivePanel() as TerminalPanel; - if (panel && panel.getId() === TERMINAL_PANEL_ID) { - panel.hideFindWidget(); - this._findWidgetVisible.reset(); - panel.focus(); - } - } - - public findNext(): void { - const panel = this._panelService.getActivePanel() as TerminalPanel; - if (panel && panel.getId() === TERMINAL_PANEL_ID) { - panel.showFindWidget(); - panel.getFindWidget().find(false); - } - } - - public findPrevious(): void { - const panel = this._panelService.getActivePanel() as TerminalPanel; - if (panel && panel.getId() === TERMINAL_PANEL_ID) { - panel.showFindWidget(); - panel.getFindWidget().find(true); - } - } - private _suggestShellChange(wasNewTerminalAction?: boolean): void { // Only suggest on Windows since $SHELL works great for macOS/Linux if (!platform.isWindows) { @@ -277,29 +243,6 @@ export class TerminalService extends BrowserTerminalService implements ITerminal }); } - public getActiveOrCreateInstance(wasNewTerminalAction?: boolean): ITerminalInstance { - const activeInstance = this.getActiveInstance(); - return activeInstance ? activeInstance : this.createTerminal(undefined, wasNewTerminalAction); - } - - protected _showTerminalCloseConfirmation(): Promise { - let message; - if (this.terminalInstances.length === 1) { - message = nls.localize('terminalService.terminalCloseConfirmationSingular', "There is an active terminal session, do you want to kill it?"); - } else { - message = nls.localize('terminalService.terminalCloseConfirmationPlural', "There are {0} active terminal sessions, do you want to kill them?", this.terminalInstances.length); - } - - return this._dialogService.confirm({ - message, - type: 'warning', - }).then(res => !res.confirmed); - } - - protected _showNotEnoughSpaceToast(): void { - this._notificationService.info(nls.localize('terminal.minWidth', "Not enough space to split terminal.")); - } - public setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void { this._configHelper.panelContainer = panelContainer; this._terminalContainer = terminalContainer; From 1d1dbdc494a7e7821ea77c0bae5f57cd7a5c9f96 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 17:55:20 -0800 Subject: [PATCH 152/290] Move TerminalConfigHelper, electron-browser->browser Part of #69115 --- src/tsconfig.strictNullChecks.json | 2 +- .../terminalConfigHelper.ts | 8 +-- .../contrib/terminal/common/terminal.ts | 6 ++ .../terminal/common/terminalService.ts | 2 +- .../electron-browser/terminalInstance.ts | 2 +- .../electron-browser/terminalService.ts | 7 +- .../contrib/terminal/node/terminal.ts | 9 +-- .../terminalConfigHelper.test.ts | 69 ++++++++++--------- 8 files changed, 57 insertions(+), 48 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/terminalConfigHelper.ts (97%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 41f71cf9d5c..c0381030c46 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -279,6 +279,7 @@ "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", "./vs/workbench/contrib/terminal/browser/terminalActions.ts", + "./vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", "./vs/workbench/contrib/terminal/browser/terminalPanel.ts", @@ -291,7 +292,6 @@ "./vs/workbench/contrib/terminal/common/terminalEnvironment.ts", "./vs/workbench/contrib/terminal/common/terminalMenu.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", - "./vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts similarity index 97% rename from src/vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts rename to src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index fd82c1a61fb..91a780466ad 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -10,9 +10,8 @@ import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/ed import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import Severity from 'vs/base/common/severity'; -import { isFedora, isUbuntu } from 'vs/workbench/contrib/terminal/node/terminal'; import { Terminal as XTermTerminal } from 'vscode-xterm'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -31,6 +30,7 @@ export class TerminalConfigHelper implements ITerminalConfigHelper { public config: ITerminalConfiguration; public constructor( + private readonly _linuxDistro: LinuxDistro, @IConfigurationService private readonly _configurationService: IConfigurationService, @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, @INotificationService private readonly _notificationService: INotificationService, @@ -118,10 +118,10 @@ export class TerminalConfigHelper implements ITerminalConfigHelper { // Work around bad font on Fedora/Ubuntu if (!this.config.fontFamily) { - if (isFedora) { + if (this._linuxDistro === LinuxDistro.Fedora) { fontFamily = '\'DejaVu Sans Mono\', monospace'; } - if (isUbuntu) { + if (this._linuxDistro === LinuxDistro.Ubuntu) { fontFamily = '\'Ubuntu Mono\', monospace'; // Ubuntu mono is somehow smaller, so set fontSize a bit larger to get the same perceived size. diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 57217bb480c..a31e4c2c714 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -687,4 +687,10 @@ export interface ITerminalProcessExtHostRequest { activeWorkspaceRootUri: URI; cols: number; rows: number; +} + +export enum LinuxDistro { + Fedora, + Ubuntu, + Unknown } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 1999fd8a6ec..88b917fbf52 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -23,7 +23,7 @@ export abstract class TerminalService implements ITerminalService { protected _terminalFocusContextKey: IContextKey; protected _findWidgetVisible: IContextKey; protected _terminalContainer: HTMLElement; - protected _terminalTabs: ITerminalTab[]; + protected _terminalTabs: ITerminalTab[] = []; protected get _terminalInstances(): ITerminalInstance[] { return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index 22f9378da7b..7341a54add6 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -30,7 +30,7 @@ import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/ter import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; -import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; +import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/electron-browser/terminalProcessManager'; import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/node/terminalCommandTracker'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index b2739f6b45a..483d22ccf89 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -14,10 +14,10 @@ import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; -import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; +import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import Severity from 'vs/base/common/severity'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getDefaultShell, linuxDistro } from 'vs/workbench/contrib/terminal/node/terminal'; import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -49,8 +49,7 @@ export class TerminalService extends BrowserTerminalService implements ITerminal ) { super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService); - this._terminalTabs = []; - this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper); + this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper, linuxDistro); ipc.on('vscode:openFiles', (_event: any, request: IOpenFileRequest) => { // if the request to open files is coming in from the integrated terminal (identified though // the termProgram variable) and we are instructed to wait for editors close, wait for the diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index 73b41c24e5d..96b165c2614 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -8,6 +8,7 @@ import * as platform from 'vs/base/common/platform'; import * as processes from 'vs/base/node/processes'; import { readFile, fileExists } from 'vs/base/node/pfs'; import { Event } from 'vs/base/common/event'; +import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; /** * An interface representing a raw terminal child process, this contains a subset of the @@ -78,6 +79,7 @@ function getTerminalDefaultShellWindows(): string { return _TERMINAL_DEFAULT_SHELL_WINDOWS; } +let detectedDistro = LinuxDistro.Unknown; if (platform.isLinux) { const file = '/etc/os-release'; fileExists(file).then(exists => { @@ -87,13 +89,12 @@ if (platform.isLinux) { readFile(file).then(b => { const contents = b.toString(); if (/NAME="?Fedora"?/.test(contents)) { - isFedora = true; + detectedDistro = LinuxDistro.Fedora; } else if (/NAME="?Ubuntu"?/.test(contents)) { - isUbuntu = true; + detectedDistro = LinuxDistro.Ubuntu; } }); }); } -export let isFedora = false; -export let isUbuntu = false; \ No newline at end of file +export const linuxDistro = detectedDistro; diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts index 4ee63fee360..e0110601c82 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/electron-browser/terminalConfigHelper'; +import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; -import { isFedora, isUbuntu } from 'vs/workbench/contrib/terminal/node/terminal'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; suite('Workbench - TerminalConfigHelper', () => { let fixture: HTMLElement; @@ -21,22 +21,24 @@ suite('Workbench - TerminalConfigHelper', () => { configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: 'bar' } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontFamily, 'bar', 'terminal.integrated.fontFamily should be selected over editor.fontFamily'); configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } }); // Recreate config helper as onDidChangeConfiguration isn't implemented in TestConfigurationService - configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + configHelper = new TerminalConfigHelper(LinuxDistro.Fedora, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; - if (isFedora) { - assert.equal(configHelper.getFont().fontFamily, '\'DejaVu Sans Mono\', monospace', 'Fedora should have its font overridden when terminal.integrated.fontFamily not set'); - } else if (isUbuntu) { - assert.equal(configHelper.getFont().fontFamily, '\'Ubuntu Mono\', monospace', 'Ubuntu should have its font overridden when terminal.integrated.fontFamily not set'); - } else { - assert.equal(configHelper.getFont().fontFamily, 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set'); - } + assert.equal(configHelper.getFont().fontFamily, '\'DejaVu Sans Mono\', monospace', 'Fedora should have its font overridden when terminal.integrated.fontFamily not set'); + + configHelper = new TerminalConfigHelper(LinuxDistro.Ubuntu, configurationService, null!, null!, null!); + configHelper.panelContainer = fixture; + assert.equal(configHelper.getFont().fontFamily, '\'Ubuntu Mono\', monospace', 'Ubuntu should have its font overridden when terminal.integrated.fontFamily not set'); + + configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); + configHelper.panelContainer = fixture; + assert.equal(configHelper.getFont().fontFamily, 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set'); }); test('TerminalConfigHelper - getFont fontSize', function () { @@ -52,7 +54,7 @@ suite('Workbench - TerminalConfigHelper', () => { fontSize: 10 } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontSize, 10, 'terminal.integrated.fontSize should be selected over editor.fontSize'); @@ -65,13 +67,14 @@ suite('Workbench - TerminalConfigHelper', () => { fontSize: 0 } }); - configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + configHelper = new TerminalConfigHelper(LinuxDistro.Ubuntu, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; - if (isUbuntu) { - assert.equal(configHelper.getFont().fontSize, 8, 'The minimum terminal font size (with adjustment) should be used when terminal.integrated.fontSize less than it'); - } else { - assert.equal(configHelper.getFont().fontSize, 6, 'The minimum terminal font size should be used when terminal.integrated.fontSize less than it'); - } + assert.equal(configHelper.getFont().fontSize, 8, 'The minimum terminal font size (with adjustment) should be used when terminal.integrated.fontSize less than it'); + + configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); + configHelper.panelContainer = fixture; + assert.equal(configHelper.getFont().fontSize, 6, 'The minimum terminal font size should be used when terminal.integrated.fontSize less than it'); + configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); @@ -81,7 +84,7 @@ suite('Workbench - TerminalConfigHelper', () => { fontSize: 1500 } }); - configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontSize, 25, 'The maximum terminal font size should be used when terminal.integrated.fontSize more than it'); @@ -94,13 +97,13 @@ suite('Workbench - TerminalConfigHelper', () => { fontSize: null } }); - configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + configHelper = new TerminalConfigHelper(LinuxDistro.Ubuntu, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; - if (isUbuntu) { - assert.equal(configHelper.getFont().fontSize, EDITOR_FONT_DEFAULTS.fontSize + 2, 'The default editor font size (with adjustment) should be used when terminal.integrated.fontSize is not set'); - } else { - assert.equal(configHelper.getFont().fontSize, EDITOR_FONT_DEFAULTS.fontSize, 'The default editor font size should be used when terminal.integrated.fontSize is not set'); - } + assert.equal(configHelper.getFont().fontSize, EDITOR_FONT_DEFAULTS.fontSize + 2, 'The default editor font size (with adjustment) should be used when terminal.integrated.fontSize is not set'); + + configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); + configHelper.panelContainer = fixture; + assert.equal(configHelper.getFont().fontSize, EDITOR_FONT_DEFAULTS.fontSize, 'The default editor font size should be used when terminal.integrated.fontSize is not set'); }); test('TerminalConfigHelper - getFont lineHeight', function () { @@ -116,7 +119,7 @@ suite('Workbench - TerminalConfigHelper', () => { lineHeight: 2 } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().lineHeight, 2, 'terminal.integrated.lineHeight should be selected over editor.lineHeight'); @@ -130,7 +133,7 @@ suite('Workbench - TerminalConfigHelper', () => { lineHeight: 0 } }); - configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().lineHeight, 1, 'editor.lineHeight should be 1 when terminal.integrated.lineHeight not set'); }); @@ -143,7 +146,7 @@ suite('Workbench - TerminalConfigHelper', () => { } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.configFontIsMonospace(), true, 'monospace is monospaced'); }); @@ -155,7 +158,7 @@ suite('Workbench - TerminalConfigHelper', () => { fontFamily: 'sans-serif' } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.configFontIsMonospace(), false, 'sans-serif is not monospaced'); }); @@ -167,7 +170,7 @@ suite('Workbench - TerminalConfigHelper', () => { fontFamily: 'serif' } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.configFontIsMonospace(), false, 'serif is not monospaced'); }); @@ -183,7 +186,7 @@ suite('Workbench - TerminalConfigHelper', () => { } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.configFontIsMonospace(), true, 'monospace is monospaced'); }); @@ -199,7 +202,7 @@ suite('Workbench - TerminalConfigHelper', () => { } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.configFontIsMonospace(), false, 'sans-serif is not monospaced'); }); @@ -215,7 +218,7 @@ suite('Workbench - TerminalConfigHelper', () => { } }); - let configHelper = new TerminalConfigHelper(configurationService, null!, null!, null!); + let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.configFontIsMonospace(), false, 'serif is not monospaced'); }); From b5dcee0a3185de2e019cc8127cbc5f91ab2b1b29 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 18:01:47 -0800 Subject: [PATCH 153/290] Move terminal CSS and images to browser Part of #69115 --- .../media/configure-inverse.svg | 0 .../{electron-browser => browser}/media/configure.svg | 0 .../{electron-browser => browser}/media/kill-inverse.svg | 0 .../terminal/{electron-browser => browser}/media/kill.svg | 0 .../{electron-browser => browser}/media/new-inverse.svg | 0 .../terminal/{electron-browser => browser}/media/new.svg | 0 .../{electron-browser => browser}/media/scrollbar.css | 0 .../media/split-horizontal-inverse.svg | 0 .../media/split-horizontal.svg | 0 .../{electron-browser => browser}/media/split-inverse.svg | 0 .../{electron-browser => browser}/media/split.svg | 0 .../{electron-browser => browser}/media/terminal.css | 0 .../{electron-browser => browser}/media/widgets.css | 0 .../{electron-browser => browser}/media/xterm.css | 0 .../terminal/electron-browser/terminal.contribution.ts | 8 ++++---- 15 files changed, 4 insertions(+), 4 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/configure-inverse.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/configure.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/kill-inverse.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/kill.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/new-inverse.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/new.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/scrollbar.css (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/split-horizontal-inverse.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/split-horizontal.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/split-inverse.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/split.svg (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/terminal.css (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/widgets.css (100%) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/media/xterm.css (100%) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/configure-inverse.svg b/src/vs/workbench/contrib/terminal/browser/media/configure-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/configure-inverse.svg rename to src/vs/workbench/contrib/terminal/browser/media/configure-inverse.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/configure.svg b/src/vs/workbench/contrib/terminal/browser/media/configure.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/configure.svg rename to src/vs/workbench/contrib/terminal/browser/media/configure.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/kill-inverse.svg b/src/vs/workbench/contrib/terminal/browser/media/kill-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/kill-inverse.svg rename to src/vs/workbench/contrib/terminal/browser/media/kill-inverse.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/kill.svg b/src/vs/workbench/contrib/terminal/browser/media/kill.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/kill.svg rename to src/vs/workbench/contrib/terminal/browser/media/kill.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/new-inverse.svg b/src/vs/workbench/contrib/terminal/browser/media/new-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/new-inverse.svg rename to src/vs/workbench/contrib/terminal/browser/media/new-inverse.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/new.svg b/src/vs/workbench/contrib/terminal/browser/media/new.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/new.svg rename to src/vs/workbench/contrib/terminal/browser/media/new.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/scrollbar.css b/src/vs/workbench/contrib/terminal/browser/media/scrollbar.css similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/scrollbar.css rename to src/vs/workbench/contrib/terminal/browser/media/scrollbar.css diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/split-horizontal-inverse.svg b/src/vs/workbench/contrib/terminal/browser/media/split-horizontal-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/split-horizontal-inverse.svg rename to src/vs/workbench/contrib/terminal/browser/media/split-horizontal-inverse.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/split-horizontal.svg b/src/vs/workbench/contrib/terminal/browser/media/split-horizontal.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/split-horizontal.svg rename to src/vs/workbench/contrib/terminal/browser/media/split-horizontal.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/split-inverse.svg b/src/vs/workbench/contrib/terminal/browser/media/split-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/split-inverse.svg rename to src/vs/workbench/contrib/terminal/browser/media/split-inverse.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/split.svg b/src/vs/workbench/contrib/terminal/browser/media/split.svg similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/split.svg rename to src/vs/workbench/contrib/terminal/browser/media/split.svg diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/terminal.css b/src/vs/workbench/contrib/terminal/browser/media/terminal.css similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/terminal.css rename to src/vs/workbench/contrib/terminal/browser/media/terminal.css diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/widgets.css b/src/vs/workbench/contrib/terminal/browser/media/widgets.css similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/widgets.css rename to src/vs/workbench/contrib/terminal/browser/media/widgets.css diff --git a/src/vs/workbench/contrib/terminal/electron-browser/media/xterm.css b/src/vs/workbench/contrib/terminal/browser/media/xterm.css similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/media/xterm.css rename to src/vs/workbench/contrib/terminal/browser/media/xterm.css diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index e703212b0b4..e278b7ee47e 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/scrollbar'; -import 'vs/css!./media/terminal'; -import 'vs/css!./media/xterm'; -import 'vs/css!./media/widgets'; +import 'vs/css!../browser/media/scrollbar'; +import 'vs/css!../browser/media/terminal'; +import 'vs/css!../browser/media/xterm'; +import 'vs/css!../browser/media/widgets'; import * as nls from 'vs/nls'; import * as panel from 'vs/workbench/browser/panel'; import * as platform from 'vs/base/common/platform'; From 00f5bdb0ba79ad1d7a93815afde7486640df708e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 18:04:05 -0800 Subject: [PATCH 154/290] Move terminalCommandTracker, node->browser Part of #69115 --- src/tsconfig.strictNullChecks.json | 4 ++-- .../terminal/{node => browser}/terminalCommandTracker.ts | 0 .../contrib/terminal/electron-browser/terminalInstance.ts | 2 +- .../{node => electron-browser}/terminalCommandTracker.test.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/vs/workbench/contrib/terminal/{node => browser}/terminalCommandTracker.ts (100%) rename src/vs/workbench/contrib/terminal/test/{node => electron-browser}/terminalCommandTracker.test.ts (99%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index c0381030c46..e3974e6fdcc 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -279,6 +279,7 @@ "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", "./vs/workbench/contrib/terminal/browser/terminalActions.ts", + "./vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts", "./vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", @@ -295,14 +296,13 @@ "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", - "./vs/workbench/contrib/terminal/node/terminalCommandTracker.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", "./vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts", "./vs/workbench/contrib/terminal/node/windowsShellHelper.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalColorRegistry.test.ts", + "./vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts", - "./vs/workbench/contrib/terminal/test/node/terminalCommandTracker.test.ts", "./vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts", "./vs/workbench/contrib/themes/browser/themes.contribution.ts", "./vs/workbench/contrib/themes/test/electron-browser/themes.test.contribution.ts", diff --git a/src/vs/workbench/contrib/terminal/node/terminalCommandTracker.ts b/src/vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts similarity index 100% rename from src/vs/workbench/contrib/terminal/node/terminalCommandTracker.ts rename to src/vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index 7341a54add6..dced8d25d78 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -33,7 +33,7 @@ import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/termin import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/electron-browser/terminalProcessManager'; -import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/node/terminalCommandTracker'; +import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { ISearchOptions, Terminal as XTermTerminal } from 'vscode-xterm'; diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalCommandTracker.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts similarity index 99% rename from src/vs/workbench/contrib/terminal/test/node/terminalCommandTracker.test.ts rename to src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts index 324781f164c..ec94ff8a518 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalCommandTracker.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import { Terminal, TerminalCore } from 'vscode-xterm'; -import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/node/terminalCommandTracker'; +import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker'; import { isWindows } from 'vs/base/common/platform'; interface TestTerminalCore extends TerminalCore { From 415c08825d9b3cdd7530ccf4e37c3b19af231888 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 18:20:50 -0800 Subject: [PATCH 155/290] Move a lot of terminalService to common/browser --- .../terminal/browser/terminalService.ts | 107 ++++++++++++++- .../terminal/common/terminalService.ts | 30 ++++- .../electron-browser/terminalService.ts | 124 ++---------------- 3 files changed, 140 insertions(+), 121 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 7bf4664b9e6..051667c8a67 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -3,16 +3,23 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ITerminalService, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal'; +import * as nls from 'vs/nls'; +import * as platform from 'vs/base/common/platform'; +import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, IShellLaunchConfig, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as CommonTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { INotificationService } from 'vs/platform/notification/common/notification'; +import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IFileService } from 'vs/platform/files/common/files'; export abstract class TerminalService extends CommonTerminalService implements ITerminalService { @@ -23,9 +30,99 @@ export abstract class TerminalService extends CommonTerminalService implements I @ILifecycleService lifecycleService: ILifecycleService, @IStorageService storageService: IStorageService, @INotificationService notificationService: INotificationService, - @IDialogService dialogService: IDialogService + @IDialogService dialogService: IDialogService, + @IInstantiationService protected readonly _instantiationService: IInstantiationService, + @IWindowService private _windowService: IWindowService, + @IExtensionService extensionService: IExtensionService, + @IFileService fileService: IFileService ) { - super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService); + super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService); + } + + protected abstract _getDefaultShell(p: platform.Platform): string; + + public createTerminal(shell: IShellLaunchConfig = {}, wasNewTerminalAction?: boolean): ITerminalInstance { + const terminalTab = this._instantiationService.createInstance(TerminalTab, + this._terminalFocusContextKey, + this.configHelper, + this._terminalContainer, + shell); + this._terminalTabs.push(terminalTab); + const instance = terminalTab.terminalInstances[0]; + terminalTab.addDisposable(terminalTab.onDisposed(this._onTabDisposed.fire, this._onTabDisposed)); + terminalTab.addDisposable(terminalTab.onInstancesChanged(this._onInstancesChanged.fire, this._onInstancesChanged)); + this._initInstanceListeners(instance); + if (this.terminalInstances.length === 1) { + // It's the first instance so it should be made active automatically + this.setActiveInstanceByIndex(0); + } + this._onInstancesChanged.fire(); + this._suggestShellChange(wasNewTerminalAction); + return instance; + } + + private _suggestShellChange(wasNewTerminalAction?: boolean): void { + // Only suggest on Windows since $SHELL works great for macOS/Linux + if (!platform.isWindows) { + return; + } + + if (this._windowService.getConfiguration().remoteAuthority) { + // Don't suggest if the opened workspace is remote + return; + } + + // Only suggest when the terminal instance is being created by an explicit user action to + // launch a terminal, as opposed to something like tasks, debug, panel restore, etc. + if (!wasNewTerminalAction) { + return; + } + + if (this._windowService.getConfiguration().remoteAuthority) { + // Don't suggest if the opened workspace is remote + return; + } + + // Don't suggest if the user has explicitly opted out + const neverSuggest = this._storageService.getBoolean(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, StorageScope.GLOBAL, false); + if (neverSuggest) { + return; + } + + // Never suggest if the setting is non-default already (ie. they set the setting manually) + if (this.configHelper.config.shell.windows !== this._getDefaultShell(platform.Platform.Windows)) { + this._storageService.store(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, true, StorageScope.GLOBAL); + return; + } + + this._notificationService.prompt( + Severity.Info, + nls.localize('terminal.integrated.chooseWindowsShellInfo', "You can change the default terminal shell by selecting the customize button."), + [{ + label: nls.localize('customize', "Customize"), + run: () => { + this.selectDefaultWindowsShell().then(shell => { + if (!shell) { + return Promise.resolve(null); + } + // Launch a new instance with the newly selected shell + const instance = this.createTerminal({ + executable: shell, + args: this.configHelper.config.shellArgs.windows + }); + if (instance) { + this.setActiveInstance(instance); + } + return Promise.resolve(null); + }); + } + }, + { + label: nls.localize('never again', "Don't Show Again"), + isSecondary: true, + run: () => this._storageService.store(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, true, StorageScope.GLOBAL) + }] + ); } public focusFindWidget(): Promise { diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 88b917fbf52..3d3a3baac49 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -15,6 +15,8 @@ import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { IFileService } from 'vs/platform/files/common/files'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -65,7 +67,9 @@ export abstract class TerminalService implements ITerminalService { @ILifecycleService lifecycleService: ILifecycleService, @IStorageService protected readonly _storageService: IStorageService, @INotificationService protected readonly _notificationService: INotificationService, - @IDialogService private readonly _dialogService: IDialogService + @IDialogService private readonly _dialogService: IDialogService, + @IExtensionService private readonly _extensionService: IExtensionService, + @IFileService private readonly _fileService: IFileService ) { this._activeTabIndex = 0; this._isShuttingDown = false; @@ -97,7 +101,6 @@ export abstract class TerminalService implements ITerminalService { public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; - public abstract requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; public createTerminalRenderer(name: string): ITerminalInstance { return this.createTerminal({ name, isRendererOnly: true }); @@ -108,6 +111,16 @@ export abstract class TerminalService implements ITerminalService { return activeInstance ? activeInstance : this.createTerminal(undefined, wasNewTerminalAction); } + public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void { + // Ensure extension host is ready before requesting a process + this._extensionService.whenInstalledExtensionsRegistered().then(() => { + // TODO: MainThreadTerminalService is not ready at this point, fix this + setTimeout(() => { + this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows }); + }, 500); + }); + } + private _onBeforeShutdown(): boolean | Promise { if (this.terminalInstances.length === 0) { // No terminal instances, don't veto @@ -398,4 +411,17 @@ export abstract class TerminalService implements ITerminalService { protected _showNotEnoughSpaceToast(): void { this._notificationService.info(nls.localize('terminal.minWidth', "Not enough space to split terminal.")); } + + protected _validateShellPaths(label: string, potentialPaths: string[]): Promise<[string, string] | null> { + if (potentialPaths.length === 0) { + return Promise.resolve(null); + } + const current = potentialPaths.shift(); + return this._fileService.existsFile(URI.file(current!)).then(exists => { + if (!exists) { + return this._validateShellPaths(label, potentialPaths); + } + return [label, current] as [string, string]; + }); + } } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index 483d22ccf89..95f089ef3fd 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -12,22 +12,20 @@ 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 { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; -import Severity from 'vs/base/common/severity'; -import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; +import { IStorageService } from 'vs/platform/storage/common/storage'; import { getDefaultShell, linuxDistro } from 'vs/workbench/contrib/terminal/node/terminal'; -import { TerminalTab } from 'vs/workbench/contrib/terminal/browser/terminalTab'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ipcRenderer as ipc } from 'electron'; import { IOpenFileRequest, IWindowService } from 'vs/platform/windows/common/windows'; import { TerminalInstance } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstance'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { URI } from 'vs/base/common/uri'; import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; import { coalesce } from 'vs/base/common/arrays'; +import { IFileService } from 'vs/platform/files/common/files'; export class TerminalService extends BrowserTerminalService implements ITerminalService { private _configHelper: TerminalConfigHelper; @@ -40,14 +38,15 @@ export class TerminalService extends BrowserTerminalService implements ITerminal @IStorageService storageService: IStorageService, @ILifecycleService lifecycleService: ILifecycleService, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IInstantiationService instantiationService: IInstantiationService, @IQuickInputService private readonly _quickInputService: IQuickInputService, @INotificationService notificationService: INotificationService, @IDialogService dialogService: IDialogService, - @IExtensionService private readonly _extensionService: IExtensionService, - @IWindowService private readonly _windowService: IWindowService, + @IExtensionService extensionService: IExtensionService, + @IWindowService windowService: IWindowService, + @IFileService fileService: IFileService ) { - super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService); + super(contextKeyService, panelService, partService, lifecycleService, storageService, notificationService, dialogService, instantiationService, windowService, extensionService, fileService); this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper, linuxDistro); ipc.on('vscode:openFiles', (_event: any, request: IOpenFileRequest) => { @@ -74,104 +73,14 @@ export class TerminalService extends BrowserTerminalService implements ITerminal }); } - public createTerminal(shell: IShellLaunchConfig = {}, wasNewTerminalAction?: boolean): ITerminalInstance { - const terminalTab = this._instantiationService.createInstance(TerminalTab, - this._terminalFocusContextKey, - this._configHelper, - this._terminalContainer, - shell); - this._terminalTabs.push(terminalTab); - const instance = terminalTab.terminalInstances[0]; - terminalTab.addDisposable(terminalTab.onDisposed(this._onTabDisposed.fire, this._onTabDisposed)); - terminalTab.addDisposable(terminalTab.onInstancesChanged(this._onInstancesChanged.fire, this._onInstancesChanged)); - this._initInstanceListeners(instance); - if (this.terminalInstances.length === 1) { - // It's the first instance so it should be made active automatically - this.setActiveInstanceByIndex(0); - } - this._onInstancesChanged.fire(); - this._suggestShellChange(wasNewTerminalAction); - return instance; - } - public createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance { const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig); this._onInstanceCreated.fire(instance); return instance; } - public requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void { - // Ensure extension host is ready before requesting a process - this._extensionService.whenInstalledExtensionsRegistered().then(() => { - // TODO: MainThreadTerminalService is not ready at this point, fix this - setTimeout(() => { - this._onInstanceRequestExtHostProcess.fire({ proxy, shellLaunchConfig, activeWorkspaceRootUri, cols, rows }); - }, 500); - }); - } - - private _suggestShellChange(wasNewTerminalAction?: boolean): void { - // Only suggest on Windows since $SHELL works great for macOS/Linux - if (!platform.isWindows) { - return; - } - - if (this._windowService.getConfiguration().remoteAuthority) { - // Don't suggest if the opened workspace is remote - return; - } - - // Only suggest when the terminal instance is being created by an explicit user action to - // launch a terminal, as opposed to something like tasks, debug, panel restore, etc. - if (!wasNewTerminalAction) { - return; - } - - if (this._windowService.getConfiguration().remoteAuthority) { - // Don't suggest if the opened workspace is remote - return; - } - - // Don't suggest if the user has explicitly opted out - const neverSuggest = this._storageService.getBoolean(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, StorageScope.GLOBAL, false); - if (neverSuggest) { - return; - } - - // Never suggest if the setting is non-default already (ie. they set the setting manually) - if (this._configHelper.config.shell.windows !== getDefaultShell(platform.Platform.Windows)) { - this._storageService.store(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, true, StorageScope.GLOBAL); - return; - } - - this._notificationService.prompt( - Severity.Info, - nls.localize('terminal.integrated.chooseWindowsShellInfo', "You can change the default terminal shell by selecting the customize button."), - [{ - label: nls.localize('customize', "Customize"), - run: () => { - this.selectDefaultWindowsShell().then(shell => { - if (!shell) { - return Promise.resolve(null); - } - // Launch a new instance with the newly selected shell - const instance = this.createTerminal({ - executable: shell, - args: this._configHelper.config.shellArgs.windows - }); - if (instance) { - this.setActiveInstance(instance); - } - return Promise.resolve(null); - }); - } - }, - { - label: nls.localize('never again', "Don't Show Again"), - isSecondary: true, - run: () => this._storageService.store(NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, true, StorageScope.GLOBAL) - }] - ); + protected _getDefaultShell(p: platform.Platform): string { + return getDefaultShell(p); } public selectDefaultWindowsShell(): Promise { @@ -229,19 +138,6 @@ export class TerminalService extends BrowserTerminalService implements ITerminal }); } - private _validateShellPaths(label: string, potentialPaths: string[]): Promise<[string, string] | null> { - if (potentialPaths.length === 0) { - return Promise.resolve(null); - } - const current = potentialPaths.shift(); - return pfs.fileExists(current!).then(exists => { - if (!exists) { - return this._validateShellPaths(label, potentialPaths); - } - return [label, current] as [string, string]; - }); - } - public setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void { this._configHelper.panelContainer = panelContainer; this._terminalContainer = terminalContainer; From d9af6b90a069fb18fc458e49046e0a57e812329d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 19:18:01 -0800 Subject: [PATCH 156/290] Remove execFile dep in terminal instance, unify 2 path prep functions --- .../terminal/browser/terminalFindWidget.css | 4 --- .../contrib/terminal/browser/terminalPanel.ts | 7 ++-- .../terminal/common/terminalEnvironment.ts | 29 +++++----------- .../electron-browser/terminalInstance.ts | 34 +++---------------- .../electron-browser/terminalService.ts | 4 +-- .../contrib/terminal/node/terminal.ts | 26 ++++++++++++++ .../test/node/terminalEnvironment.test.ts | 10 ------ 7 files changed, 46 insertions(+), 68 deletions(-) delete mode 100644 src/vs/workbench/contrib/terminal/browser/terminalFindWidget.css diff --git a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.css b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.css deleted file mode 100644 index a4a092d8349..00000000000 --- a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.css +++ /dev/null @@ -1,4 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index 60286fd0e37..67310672847 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -6,7 +6,6 @@ import * as dom from 'vs/base/browser/dom'; import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; -import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Action, IAction } from 'vs/base/common/actions'; import { IActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -281,7 +280,7 @@ export class TerminalPanel extends Panel { event.stopPropagation(); } })); - this._register(dom.addDisposableListener(this._parentDomElement, dom.EventType.DROP, (e: DragEvent) => { + this._register(dom.addDisposableListener(this._parentDomElement, dom.EventType.DROP, async (e: DragEvent) => { if (e.target === this._parentDomElement || dom.isAncestor(e.target as HTMLElement, this._parentDomElement)) { if (!e.dataTransfer) { return; @@ -303,7 +302,9 @@ export class TerminalPanel extends Panel { const terminal = this._terminalService.getActiveInstance(); if (terminal) { - terminal.sendText(terminalEnvironment.preparePathForTerminal(path), false); + return terminal.preparePathForTerminalAsync(path).then(preparedPath => { + terminal.sendText(preparedPath, false); + }); } } })); diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index cf8e7fab850..5480374bba8 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -132,26 +132,15 @@ function _sanitizeCwd(cwd: string): string { return cwd; } -/** - * Adds quotes to a path if it contains whitespaces - */ -export function preparePathForTerminal(path: string): string { - if (platform.isWindows) { - if (/\s+/.test(path)) { - return `"${path}"`; - } - return path; +export function escapeNonWindowsPath(path: string): string { + let newPath = path; + if (newPath.indexOf('\\') !== 0) { + newPath = newPath.replace(/\\/g, '\\\\'); } - path = path.replace(/(%5C|\\)/g, '\\\\'); - const charsToEscape = [ - ' ', '\'', '"', '?', ':', ';', '!', '*', '(', ')', '{', '}', '[', ']' - ]; - for (let i = 0; i < path.length; i++) { - const indexOfChar = charsToEscape.indexOf(path.charAt(i)); - if (indexOfChar >= 0) { - path = `${path.substring(0, i)}\\${path.charAt(i)}${path.substring(i + 1)}`; - i++; // Skip char due to escape char being added - } + if (!newPath && (newPath.indexOf('"') !== -1)) { + newPath = '\'' + newPath + '\''; + } else if (newPath.indexOf(' ') !== -1) { + newPath = newPath.replace(/ /g, '\\ '); } - return path; + return newPath; } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index dced8d25d78..7fe8f6286f0 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { execFile } from 'child_process'; -import * as os from 'os'; import * as path from 'vs/base/common/path'; import * as dom from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; @@ -38,6 +36,8 @@ import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsSh import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { ISearchOptions, Terminal as XTermTerminal } from 'vscode-xterm'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; +import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { getWslPath, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; // How long in milliseconds should an average frame take to render for a notification to appear // which suggests the fallback DOM-based renderer @@ -829,10 +829,8 @@ export class TerminalInstance implements ITerminalInstance { if (platform.isWindows) { // 17063 is the build number where wsl path was introduced. // Update Windows uriPath to be executed in WSL. - if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (TerminalInstance.getWindowsBuildNumber() >= 17063)) { - execFile('bash.exe', ['-c', 'echo $(wslpath ' + this._escapeNonWindowsPath(originalPath) + ')'], {}, (error, stdout, stderr) => { - c(this._escapeNonWindowsPath(stdout.trim())); - }); + if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (getWindowsBuildNumber() >= 17063)) { + c(getWslPath(originalPath)); return; } else if (hasSpace) { c('"' + originalPath + '"'); @@ -841,32 +839,10 @@ export class TerminalInstance implements ITerminalInstance { } return; } - c(this._escapeNonWindowsPath(originalPath)); + c(escapeNonWindowsPath(originalPath)); }); } - private _escapeNonWindowsPath(path: string): string { - let newPath = path; - if (newPath.indexOf('\\') !== 0) { - newPath = newPath.replace(/\\/g, '\\\\'); - } - if (!newPath && (newPath.indexOf('"') !== -1)) { - newPath = '\'' + newPath + '\''; - } else if (newPath.indexOf(' ') !== -1) { - newPath = newPath.replace(/ /g, '\\ '); - } - return newPath; - } - - public static getWindowsBuildNumber(): number { - const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release()); - let buildNumber: number = 0; - if (osVersion && osVersion.length === 4) { - buildNumber = parseInt(osVersion[3]); - } - return buildNumber; - } - public setVisible(visible: boolean): void { this._isVisible = visible; if (this._wrapperElement) { diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index 95f089ef3fd..86451a2b64f 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -16,7 +16,7 @@ import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfi import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { getDefaultShell, linuxDistro } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getDefaultShell, linuxDistro, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ipcRenderer as ipc } from 'electron'; @@ -108,7 +108,7 @@ export class TerminalService extends BrowserTerminalService implements ITerminal let useWSLexe = false; - if (TerminalInstance.getWindowsBuildNumber() >= 16299) { + if (getWindowsBuildNumber() >= 16299) { useWSLexe = true; } diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index 96b165c2614..a7b76673023 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -9,6 +9,8 @@ import * as processes from 'vs/base/node/processes'; import { readFile, fileExists } from 'vs/base/node/pfs'; import { Event } from 'vs/base/common/event'; import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { execFile } from 'child_process'; +import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; /** * An interface representing a raw terminal child process, this contains a subset of the @@ -98,3 +100,27 @@ if (platform.isLinux) { } export const linuxDistro = detectedDistro; + +export function getWindowsBuildNumber(): number { + const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release()); + let buildNumber: number = 0; + if (osVersion && osVersion.length === 4) { + buildNumber = parseInt(osVersion[3]); + } + return buildNumber; +} + +/** + * Converts a path to a path on WSL using the wslpath utility. + * @param path The original path. + */ +export function getWslPath(path: string): Promise { + if (getWindowsBuildNumber() < 17063) { + throw new Error('wslpath does not exist on Windows build < 17063'); + } + return new Promise(c => { + execFile('bash.exe', ['-c', 'echo $(wslpath ' + escapeNonWindowsPath(path) + ')'], {}, (error, stdout, stderr) => { + c(escapeNonWindowsPath(stdout.trim())); + }); + }); +} diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 6153a741193..58a8af973ec 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -128,14 +128,4 @@ suite('Workbench - TerminalEnvironment', () => { assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', Uri.file('/bar'), '/foo'), '/bar'); }); }); - - test('preparePathForTerminal', () => { - if (platform.isWindows) { - assert.equal(terminalEnvironment.preparePathForTerminal('C:\\foo'), 'C:\\foo'); - assert.equal(terminalEnvironment.preparePathForTerminal('C:\\foo bar'), '"C:\\foo bar"'); - return; - } - assert.equal(terminalEnvironment.preparePathForTerminal('/a/\\foo bar"\'? ;\'?? :'), '/a/\\\\foo\\ bar\\"\\\'\\?\\ \\;\\\'\\?\\?\\ \\ \\:'); - assert.equal(terminalEnvironment.preparePathForTerminal('/\\\'"?:;!*(){}[]'), '/\\\\\\\'\\"\\?\\:\\;\\!\\*\\(\\)\\{\\}\\[\\]'); - }); }); From 877f0905acceb2299720d640bd781f624688aa0c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 19:20:07 -0800 Subject: [PATCH 157/290] Move terminalProcessManager to node --- src/tsconfig.strictNullChecks.json | 2 +- .../contrib/terminal/electron-browser/terminalInstance.ts | 2 +- .../{electron-browser => node}/terminalProcessManager.ts | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => node}/terminalProcessManager.ts (100%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index e3974e6fdcc..4db865ea10a 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -294,10 +294,10 @@ "./vs/workbench/contrib/terminal/common/terminalMenu.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", - "./vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", "./vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts", + "./vs/workbench/contrib/terminal/node/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/windowsShellHelper.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalColorRegistry.test.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts", diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index 7fe8f6286f0..62242b6373e 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -30,7 +30,7 @@ import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGR import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; -import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/electron-browser/terminalProcessManager'; +import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/node/terminalProcessManager'; import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/terminalProcessManager.ts rename to src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts From 23fbca34b08707f2d050c3a0326acd0808415679 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 19:51:18 -0800 Subject: [PATCH 158/290] Break node dependency in TerminalInstance --- .../contrib/terminal/browser/terminal.ts | 18 +++++ .../terminal/browser/terminalActions.ts | 2 +- .../contrib/terminal/browser/terminalPanel.ts | 2 +- .../contrib/terminal/common/terminal.ts | 30 +++++---- .../terminal/common/terminalService.ts | 1 + .../electron-browser/terminal.contribution.ts | 3 + .../electron-browser/terminalInstance.ts | 66 ++----------------- .../terminalInstanceService.ts | 50 ++++++++++++++ .../electron-browser/terminalService.ts | 42 +++++++++++- .../terminal/node/windowsShellHelper.ts | 4 +- 10 files changed, 141 insertions(+), 77 deletions(-) create mode 100644 src/vs/workbench/contrib/terminal/browser/terminal.ts create mode 100644 src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts new file mode 100644 index 00000000000..6fec000ba2d --- /dev/null +++ b/src/vs/workbench/contrib/terminal/browser/terminal.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. + *--------------------------------------------------------------------------------------------*/ + +import { Terminal as XTermTerminal } from 'vscode-xterm'; +import { ITerminalInstance, IWindowsShellHelper, ITerminalProcessManager, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; + +export const ITerminalInstanceService = createDecorator('terminalInstanceService'); + +export interface ITerminalInstanceService { + _serviceBrand: any; + + getXtermConstructor(): Promise; + createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; + createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager; +} diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index ea11c54029c..663829a2683 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -696,7 +696,7 @@ export class RunActiveFileInTerminalAction extends Action { return Promise.resolve(undefined); } - return instance.preparePathForTerminalAsync(uri.fsPath).then(path => { + return this.terminalService.preparePathForTerminalAsync(uri.fsPath, instance.shellLaunchConfig.executable, instance.title).then(path => { instance.sendText(path, true); return this.terminalService.showPanel(); }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts index 67310672847..b248acd1af3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalPanel.ts @@ -302,7 +302,7 @@ export class TerminalPanel extends Panel { const terminal = this._terminalService.getActiveInstance(); if (terminal) { - return terminal.preparePathForTerminalAsync(path).then(preparedPath => { + return this._terminalService.preparePathForTerminalAsync(path, terminal.shellLaunchConfig.executable, terminal.title).then(preparedPath => { terminal.sendText(preparedPath, false); }); } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index a31e4c2c714..c10fdf3a012 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -13,8 +13,6 @@ import { FindReplaceState } from 'vs/editor/contrib/find/findState'; export const TERMINAL_PANEL_ID = 'workbench.panel.terminal'; -export const TERMINAL_SERVICE_ID = 'terminalService'; - /** A context key that is set when there is at least one opened integrated terminal. */ export const KEYBINDING_CONTEXT_TERMINAL_IS_OPEN = new RawContextKey('terminalIsOpen', false); /** A context key that is set when the integrated terminal has focus. */ @@ -47,7 +45,7 @@ export const NEVER_MEASURE_RENDER_TIME_STORAGE_KEY = 'terminal.integrated.neverM // trying to create the corressponding object on the ext host. export const EXT_HOST_CREATION_DELAY = 100; -export const ITerminalService = createDecorator(TERMINAL_SERVICE_ID); +export const ITerminalService = createDecorator('terminalService'); export const TerminalCursorStyle = { BLOCK: 'block', @@ -255,6 +253,17 @@ export interface ITerminalService { selectDefaultWindowsShell(): Promise; setWorkspaceShellAllowed(isAllowed: boolean): void; + /** + * Takes a path and returns the properly escaped path to send to the terminal. + * On Windows, this included trying to prepare the path for WSL if needed. + * + * @param executable The executable off the shellLaunchConfig + * @param title The terminal's title + * @param path The path to be escaped and formatted. + * @returns An escaped version of the path to be execuded in the terminal. + */ + preparePathForTerminalAsync(path: string, executable: string | undefined, title: string): Promise; + requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number): void; } @@ -525,15 +534,6 @@ export interface ITerminalInstance { */ sendText(text: string, addNewLine: boolean): void; - /** - * Takes a path and returns the properly escaped path to send to the terminal. - * On Windows, this included trying to prepare the path for WSL if needed. - * - * @param path The path to be escaped and formatted. - * @returns An escaped version of the path to be execuded in the terminal. - */ - preparePathForTerminalAsync(path: string): Promise; - /** * Write text directly to the terminal, skipping the process if it exists. * @param text The text to write. @@ -693,4 +693,8 @@ export enum LinuxDistro { Fedora, Ubuntu, Unknown -} \ No newline at end of file +} + +export interface IWindowsShellHelper extends IDisposable { + getShellName(): Promise; +} diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 3d3a3baac49..859f4208b95 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -101,6 +101,7 @@ export abstract class TerminalService implements ITerminalService { public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; + public abstract preparePathForTerminalAsync(path: string, executable: string, title: string): Promise; public createTerminalRenderer(name: string): ITerminalInstance { return this.createTerminal({ name, isRendererOnly: true }); diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index e278b7ee47e..a3e9ce8ad5f 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -33,6 +33,8 @@ import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/ter import { setupTerminalCommands, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminalMenu'; import { DEFAULT_COMMANDS_TO_SKIP_SHELL } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstance'; +import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService'; +import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; const quickOpenRegistry = (Registry.as(QuickOpenExtensions.Quickopen)); @@ -291,6 +293,7 @@ configurationRegistry.registerConfiguration({ }); registerSingleton(ITerminalService, TerminalService, true); +registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); (Registry.as(panel.Extensions.Panels)).registerPanel(new panel.PanelDescriptor( TerminalPanel, diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts index 62242b6373e..08845402186 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts @@ -25,19 +25,16 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/terminalWidgetManager'; -import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IShellLaunchConfig, ITerminalDimensions, ITerminalInstance, ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_PANEL_ID, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { ansiColorIdentifiers, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkHandler } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; -import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/node/terminalProcessManager'; import { TerminalCommandTracker } from 'vs/workbench/contrib/terminal/browser/terminalCommandTracker'; -import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { ISearchOptions, Terminal as XTermTerminal } from 'vscode-xterm'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; -import { getWslPath, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; +import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; // How long in milliseconds should an average frame take to render for a notification to appear // which suggests the fallback DOM-based renderer @@ -151,8 +148,6 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [ 'workbench.action.toggleMaximizedPanel' ]; -let Terminal: typeof XTermTerminal; - export class TerminalInstance implements ITerminalInstance { private static readonly EOL_REGEX = /\r?\n/g; @@ -175,7 +170,7 @@ export class TerminalInstance implements ITerminalInstance { private _cols: number; private _rows: number; private _dimensionsOverride: ITerminalDimensions; - private _windowsShellHelper: WindowsShellHelper | undefined; + private _windowsShellHelper: IWindowsShellHelper | undefined; private _xtermReadyPromise: Promise; private _titleReadyPromise: Promise; private _titleReadyComplete: (title: string) => any; @@ -240,6 +235,7 @@ export class TerminalInstance implements ITerminalInstance { private readonly _configHelper: TerminalConfigHelper, private _container: HTMLElement, private _shellLaunchConfig: IShellLaunchConfig, + @ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService, @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IKeybindingService private readonly _keybindingService: IKeybindingService, @INotificationService private readonly _notificationService: INotificationService, @@ -398,17 +394,7 @@ export class TerminalInstance implements ITerminalInstance { * Create xterm.js instance and attach data listeners. */ protected async _createXterm(): Promise { - if (!Terminal) { - Terminal = (await import('vscode-xterm')).Terminal; - // Enable xterm.js addons - Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/search/search')); - Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/webLinks/webLinks')); - Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/winptyCompat/winptyCompat')); - // Localize strings - Terminal.strings.blankLine = nls.localize('terminal.integrated.a11yBlankLine', 'Blank line'); - Terminal.strings.promptLabel = nls.localize('terminal.integrated.a11yPromptLabel', 'Terminal input'); - Terminal.strings.tooMuchOutput = nls.localize('terminal.integrated.a11yTooMuchOutput', 'Too much output to announce, navigate to rows manually to read'); - } + const Terminal = await this._terminalInstanceService.getXtermConstructor(); const font = this._configHelper.getFont(undefined, true); const config = this._configHelper.config; this._xterm = new Terminal({ @@ -805,44 +791,6 @@ export class TerminalInstance implements ITerminalInstance { } } - public preparePathForTerminalAsync(originalPath: string): Promise { - return new Promise(c => { - const exe = this.shellLaunchConfig.executable; - if (!exe) { - c(originalPath); - return; - } - - const hasSpace = originalPath.indexOf(' ') !== -1; - - const pathBasename = path.basename(exe, '.exe'); - const isPowerShell = pathBasename === 'pwsh' || - this.title === 'pwsh' || - pathBasename === 'powershell' || - this.title === 'powershell'; - - if (isPowerShell && (hasSpace || originalPath.indexOf('\'') !== -1)) { - c(`& '${originalPath.replace(/'/g, '\'\'')}'`); - return; - } - - if (platform.isWindows) { - // 17063 is the build number where wsl path was introduced. - // Update Windows uriPath to be executed in WSL. - if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (getWindowsBuildNumber() >= 17063)) { - c(getWslPath(originalPath)); - return; - } else if (hasSpace) { - c('"' + originalPath + '"'); - } else { - c(originalPath); - } - return; - } - c(escapeNonWindowsPath(originalPath)); - }); - } - public setVisible(visible: boolean): void { this._isVisible = visible; if (this._wrapperElement) { @@ -907,7 +855,7 @@ export class TerminalInstance implements ITerminalInstance { } protected _createProcess(): void { - this._processManager = this._instantiationService.createInstance(TerminalProcessManager, this._id, this._configHelper); + this._processManager = this._terminalInstanceService.createTerminalProcessManager(this._id, this._configHelper); this._processManager.onProcessReady(() => this._onProcessIdReady.fire(this)); this._processManager.onProcessExit(exitCode => this._onProcessExit(exitCode)); this._processManager.onProcessData(data => this._onData.fire(data)); @@ -924,7 +872,7 @@ export class TerminalInstance implements ITerminalInstance { this._processManager.ptyProcessReady.then(() => { this._xtermReadyPromise.then(() => { if (!this._isDisposed) { - this._windowsShellHelper = new WindowsShellHelper(this._processManager!.shellProcessId, this, this._xterm); + this._terminalInstanceService.createWindowsShellHelper(this._processManager!.shellProcessId, this, this._xterm); } }); }); diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts new file mode 100644 index 00000000000..727e5ab6201 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.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 nls from 'vs/nls'; +import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { Terminal as XTermTerminal } from 'vscode-xterm'; +import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/node/terminalProcessManager'; + +let Terminal: typeof XTermTerminal; + +/** + * A service used by TerminalInstance that allows it to break its dependency on electron-browser and + * node layers, while at the same time avoiding a cyclic dependency on ITerminalService. + */ +export class TerminalInstanceService implements ITerminalInstanceService { + public _serviceBrand: any; + + constructor( + @IInstantiationService private readonly _instantiationService: IInstantiationService, + ) { + } + + async getXtermConstructor(): Promise { + if (!Terminal) { + Terminal = (await import('vscode-xterm')).Terminal; + // Enable xterm.js addons + Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/search/search')); + Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/webLinks/webLinks')); + Terminal.applyAddon(require.__$__nodeRequire('vscode-xterm/lib/addons/winptyCompat/winptyCompat')); + // Localize strings + Terminal.strings.blankLine = nls.localize('terminal.integrated.a11yBlankLine', 'Blank line'); + Terminal.strings.promptLabel = nls.localize('terminal.integrated.a11yPromptLabel', 'Terminal input'); + Terminal.strings.tooMuchOutput = nls.localize('terminal.integrated.a11yTooMuchOutput', 'Too much output to announce, navigate to rows manually to read'); + } + return Terminal; + } + + createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper { + return new WindowsShellHelper(shellProcessId, instance, xterm); + } + + createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager { + return this._instantiationService.createInstance(TerminalProcessManager, id, configHelper); + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index 86451a2b64f..44011e664d2 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -16,7 +16,7 @@ import { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfi import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { getDefaultShell, linuxDistro, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getDefaultShell, linuxDistro, getWindowsBuildNumber, getWslPath } from 'vs/workbench/contrib/terminal/node/terminal'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ipcRenderer as ipc } from 'electron'; @@ -26,6 +26,8 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; import { coalesce } from 'vs/base/common/arrays'; import { IFileService } from 'vs/platform/files/common/files'; +import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { basename } from 'vs/base/common/path'; export class TerminalService extends BrowserTerminalService implements ITerminalService { private _configHelper: TerminalConfigHelper; @@ -143,4 +145,42 @@ export class TerminalService extends BrowserTerminalService implements ITerminal this._terminalContainer = terminalContainer; this._terminalTabs.forEach(tab => tab.attachToElement(this._terminalContainer)); } + + public preparePathForTerminalAsync(originalPath: string, executable: string, title: string): Promise { + return new Promise(c => { + const exe = executable; + if (!exe) { + c(originalPath); + return; + } + + const hasSpace = originalPath.indexOf(' ') !== -1; + + const pathBasename = basename(exe, '.exe'); + const isPowerShell = pathBasename === 'pwsh' || + title === 'pwsh' || + pathBasename === 'powershell' || + title === 'powershell'; + + if (isPowerShell && (hasSpace || originalPath.indexOf('\'') !== -1)) { + c(`& '${originalPath.replace(/'/g, '\'\'')}'`); + return; + } + + if (platform.isWindows) { + // 17063 is the build number where wsl path was introduced. + // Update Windows uriPath to be executed in WSL. + if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (getWindowsBuildNumber() >= 17063)) { + c(getWslPath(originalPath)); + return; + } else if (hasSpace) { + c('"' + originalPath + '"'); + } else { + c(originalPath); + } + return; + } + c(escapeNonWindowsPath(originalPath)); + }); + } } diff --git a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts index 80233f87d4d..d841d023695 100644 --- a/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts +++ b/src/vs/workbench/contrib/terminal/node/windowsShellHelper.ts @@ -5,7 +5,7 @@ import * as platform from 'vs/base/common/platform'; import { Emitter, Event } from 'vs/base/common/event'; -import { ITerminalInstance } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { Terminal as XTermTerminal } from 'vscode-xterm'; import WindowsProcessTreeType = require('windows-process-tree'); @@ -24,7 +24,7 @@ const SHELL_EXECUTABLES = [ let windowsProcessTree: typeof WindowsProcessTreeType; -export class WindowsShellHelper { +export class WindowsShellHelper implements IWindowsShellHelper { private _onCheckShell: Emitter | undefined>; private _isDisposed: boolean; private _currentRequest: Promise | null; From b5a06ebb62ba322549cf2c1f1c318a6d69ebeefa Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 19:52:20 -0800 Subject: [PATCH 159/290] Move terminalInstance, electron-browser->browser Part of #69115 --- src/tsconfig.strictNullChecks.json | 2 +- .../terminal/{electron-browser => browser}/terminalInstance.ts | 0 .../contrib/terminal/electron-browser/terminal.contribution.ts | 2 +- .../contrib/terminal/electron-browser/terminalService.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/vs/workbench/contrib/terminal/{electron-browser => browser}/terminalInstance.ts (100%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 4db865ea10a..b1be79b7e9f 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -282,6 +282,7 @@ "./vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts", "./vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts", "./vs/workbench/contrib/terminal/browser/terminalFindWidget.ts", + "./vs/workbench/contrib/terminal/browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", "./vs/workbench/contrib/terminal/browser/terminalPanel.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", @@ -293,7 +294,6 @@ "./vs/workbench/contrib/terminal/common/terminalEnvironment.ts", "./vs/workbench/contrib/terminal/common/terminalMenu.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", - "./vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", "./vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts", diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts similarity index 100% rename from src/vs/workbench/contrib/terminal/electron-browser/terminalInstance.ts rename to src/vs/workbench/contrib/terminal/browser/terminalInstance.ts diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index a3e9ce8ad5f..d4cec6691ce 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -32,7 +32,7 @@ import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPan import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; import { setupTerminalCommands, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminalMenu'; -import { DEFAULT_COMMANDS_TO_SKIP_SHELL } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstance'; +import { DEFAULT_COMMANDS_TO_SKIP_SHELL } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index 44011e664d2..2db2dcb3272 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -21,7 +21,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ipcRenderer as ipc } from 'electron'; import { IOpenFileRequest, IWindowService } from 'vs/platform/windows/common/windows'; -import { TerminalInstance } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstance'; +import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; import { coalesce } from 'vs/base/common/arrays'; From 03f23ddbc6fb37fcaba2877281c2593d05f24065 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 19:55:42 -0800 Subject: [PATCH 160/290] Remove duplicate getWindowsBuildNumber definitions --- .../tasks/electron-browser/terminalTaskSystem.ts | 13 ++----------- .../contrib/terminal/node/terminalProcess.ts | 13 ++----------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts index bfaaf9c091a..025c9479cab 100644 --- a/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/electron-browser/terminalTaskSystem.ts @@ -9,7 +9,6 @@ import * as Objects from 'vs/base/common/objects'; import * as Types from 'vs/base/common/types'; import * as Platform from 'vs/base/common/platform'; import * as Async from 'vs/base/common/async'; -import * as os from 'os'; import { IStringDictionary, values } from 'vs/base/common/collections'; import { LinkedMap, Touch } from 'vs/base/common/map'; import Severity from 'vs/base/common/severity'; @@ -42,6 +41,7 @@ import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { URI } from 'vs/base/common/uri'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { Schemas } from 'vs/base/common/network'; +import { getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; interface TerminalData { terminal: ITerminalInstance; @@ -745,7 +745,7 @@ export class TerminalTaskSystem implements ITaskSystem { if (!shellSpecified) { toAdd.push('-Command'); } - } else if ((basename === 'bash.exe') || (basename === 'zsh.exe') || ((basename === 'wsl.exe') && (this.getWindowsBuildNumber() < 17763))) { // See https://github.com/Microsoft/vscode/issues/67855 + } else if ((basename === 'bash.exe') || (basename === 'zsh.exe') || ((basename === 'wsl.exe') && (getWindowsBuildNumber() < 17763))) { // See https://github.com/Microsoft/vscode/issues/67855 windowsShellArgs = false; if (!shellSpecified) { toAdd.push('-c'); @@ -1213,15 +1213,6 @@ export class TerminalTaskSystem implements ITaskSystem { return result; } - private getWindowsBuildNumber(): number { - const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release()); - let buildNumber: number = 0; - if (osVersion && osVersion.length === 4) { - buildNumber = parseInt(osVersion[3]); - } - return buildNumber; - } - private registerLinkMatchers(terminal: ITerminalInstance, problemMatchers: ProblemMatcher[]): number[] { let result: number[] = []; /* diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index fbebae679ee..4aa6a76b158 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -9,7 +9,7 @@ import * as platform from 'vs/base/common/platform'; import * as pty from 'node-pty'; import * as fs from 'fs'; import { Event, Emitter } from 'vs/base/common/event'; -import { ITerminalChildProcess } from 'vs/workbench/contrib/terminal/node/terminal'; +import { ITerminalChildProcess, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; import { IDisposable } from 'vs/base/common/lifecycle'; import { IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import { exec } from 'child_process'; @@ -51,7 +51,7 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { } this._initialCwd = cwd; - const useConpty = windowsEnableConpty && process.platform === 'win32' && this._getWindowsBuildNumber() >= 18309; + const useConpty = windowsEnableConpty && process.platform === 'win32' && getWindowsBuildNumber() >= 18309; const options: pty.IPtyForkOptions = { name: shellName, cwd, @@ -106,15 +106,6 @@ export class TerminalProcess implements ITerminalChildProcess, IDisposable { this._onProcessTitleChanged.dispose(); } - private _getWindowsBuildNumber(): number { - const osVersion = (/(\d+)\.(\d+)\.(\d+)/g).exec(os.release()); - let buildNumber: number = 0; - if (osVersion && osVersion.length === 4) { - buildNumber = parseInt(osVersion[3]); - } - return buildNumber; - } - private _setupTitlePolling() { // Send initial timeout async to give event listeners a chance to init setTimeout(() => { From 6d5ab922e68f689e05b39556ef9fbb1220f21db6 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 19:59:25 -0800 Subject: [PATCH 161/290] Move terminalProcessExtHostProxy, node->common --- src/tsconfig.strictNullChecks.json | 2 +- .../contrib/terminal/common/terminal.ts | 24 ++++++++++++++++++ .../terminalProcessExtHostProxy.ts | 3 +-- .../contrib/terminal/node/terminal.ts | 25 ------------------- .../contrib/terminal/node/terminalProcess.ts | 4 +-- .../terminal/node/terminalProcessManager.ts | 5 ++-- 6 files changed, 30 insertions(+), 33 deletions(-) rename src/vs/workbench/contrib/terminal/{node => common}/terminalProcessExtHostProxy.ts (96%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index b1be79b7e9f..13f40695a3c 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -293,10 +293,10 @@ "./vs/workbench/contrib/terminal/common/terminalCommands.ts", "./vs/workbench/contrib/terminal/common/terminalEnvironment.ts", "./vs/workbench/contrib/terminal/common/terminalMenu.ts", + "./vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", - "./vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts", "./vs/workbench/contrib/terminal/node/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/windowsShellHelper.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalColorRegistry.test.ts", diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index c10fdf3a012..ec0303a0ea3 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -698,3 +698,27 @@ export enum LinuxDistro { export interface IWindowsShellHelper extends IDisposable { getShellName(): Promise; } + +/** + * An interface representing a raw terminal child process, this contains a subset of the + * child_process.ChildProcess node.js interface. + */ +export interface ITerminalChildProcess { + onProcessData: Event; + onProcessExit: Event; + onProcessIdReady: Event; + onProcessTitleChanged: Event; + + /** + * Shutdown the terminal process. + * + * @param immediate When true the process will be killed immediately, otherwise the process will + * be given some time to make sure no additional data comes through. + */ + shutdown(immediate: boolean): void; + input(data: string): void; + resize(cols: number, rows: number): void; + + getInitialCwd(): Promise; + getCwd(): Promise; +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts similarity index 96% rename from src/vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts rename to src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts index 5eb61629e48..84131aa9edd 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ITerminalChildProcess } from 'vs/workbench/contrib/terminal/node/terminal'; import { Event, Emitter } from 'vs/base/common/event'; -import { ITerminalService, ITerminalProcessExtHostProxy, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, ITerminalProcessExtHostProxy, IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal'; import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index a7b76673023..6200b9bf734 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -7,35 +7,10 @@ import * as os from 'os'; import * as platform from 'vs/base/common/platform'; import * as processes from 'vs/base/node/processes'; import { readFile, fileExists } from 'vs/base/node/pfs'; -import { Event } from 'vs/base/common/event'; import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import { execFile } from 'child_process'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; -/** - * An interface representing a raw terminal child process, this contains a subset of the - * child_process.ChildProcess node.js interface. - */ -export interface ITerminalChildProcess { - onProcessData: Event; - onProcessExit: Event; - onProcessIdReady: Event; - onProcessTitleChanged: Event; - - /** - * Shutdown the terminal process. - * - * @param immediate When true the process will be killed immediately, otherwise the process will - * be given some time to make sure no additional data comes through. - */ - shutdown(immediate: boolean): void; - input(data: string): void; - resize(cols: number, rows: number): void; - - getInitialCwd(): Promise; - getCwd(): Promise; -} - export function getDefaultShell(p: platform.Platform): string { if (p === platform.Platform.Windows) { if (platform.isWindows) { diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index 4aa6a76b158..3d40e7ed804 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -9,9 +9,9 @@ import * as platform from 'vs/base/common/platform'; import * as pty from 'node-pty'; import * as fs from 'fs'; import { Event, Emitter } from 'vs/base/common/event'; -import { ITerminalChildProcess, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal'; import { exec } from 'child_process'; export class TerminalProcess implements ITerminalChildProcess, IDisposable { diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts index 0a9923779e8..d46fcf801fc 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts @@ -6,12 +6,11 @@ import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal'; import { ILogService } from 'vs/platform/log/common/log'; import { Emitter, Event } from 'vs/base/common/event'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; -import { ITerminalChildProcess } from 'vs/workbench/contrib/terminal/node/terminal'; -import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/node/terminalProcessExtHostProxy'; +import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; From 437f7f67cb1f8d867a82445e3bdf97f545222675 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 20:10:07 -0800 Subject: [PATCH 162/290] Move TerminalProcessManager, node->browser --- src/tsconfig.strictNullChecks.json | 2 +- src/vs/base/common/processes.ts | 29 ++++++++++++++++ src/vs/base/node/processes.ts | 27 --------------- src/vs/base/test/common/processes.test.ts | 33 +++++++++++++++++++ .../test/node/processes/processes.test.ts | 25 -------------- .../api/node/extHostTerminalService.ts | 2 +- .../contrib/terminal/browser/terminal.ts | 4 ++- .../terminalProcessManager.ts | 9 ++--- .../terminalInstanceService.ts | 21 ++++++++---- 9 files changed, 86 insertions(+), 66 deletions(-) create mode 100644 src/vs/base/test/common/processes.test.ts rename src/vs/workbench/contrib/terminal/{node => browser}/terminalProcessManager.ts (96%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 13f40695a3c..8d70756d2f6 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -285,6 +285,7 @@ "./vs/workbench/contrib/terminal/browser/terminalInstance.ts", "./vs/workbench/contrib/terminal/browser/terminalLinkHandler.ts", "./vs/workbench/contrib/terminal/browser/terminalPanel.ts", + "./vs/workbench/contrib/terminal/browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", "./vs/workbench/contrib/terminal/browser/terminalTab.ts", "./vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts", @@ -297,7 +298,6 @@ "./vs/workbench/contrib/terminal/common/terminalService.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", - "./vs/workbench/contrib/terminal/node/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/node/windowsShellHelper.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalColorRegistry.test.ts", "./vs/workbench/contrib/terminal/test/electron-browser/terminalCommandTracker.test.ts", diff --git a/src/vs/base/common/processes.ts b/src/vs/base/common/processes.ts index 7eef74d894f..b42d8e25605 100644 --- a/src/vs/base/common/processes.ts +++ b/src/vs/base/common/processes.ts @@ -3,6 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { IProcessEnvironment } from 'vs/base/common/platform'; + /** * Options to be passed to the external program or shell. */ @@ -84,3 +86,30 @@ export const enum TerminateResponseCode { AccessDenied = 2, ProcessNotFound = 3, } + +/** + * Sanitizes a VS Code process environment by removing all Electron/VS Code-related values. + */ +export function sanitizeProcessEnvironment(env: IProcessEnvironment, ...preserve: string[]): void { + const set = preserve.reduce((set, key) => { + set[key] = true; + return set; + }, {} as Record); + const keysToRemove = [ + /^ELECTRON_.+$/, + /^GOOGLE_API_KEY$/, + /^VSCODE_.+$/, + /^SNAP(|_.*)$/ + ]; + const envKeys = Object.keys(env); + envKeys + .filter(key => !set[key]) + .forEach(envKey => { + for (let i = 0; i < keysToRemove.length; i++) { + if (envKey.search(keysToRemove[i]) !== -1) { + delete env[envKey]; + break; + } + } + }); +} diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index dfaa9042499..9836e6ccfbb 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -72,33 +72,6 @@ export function getWindowsShell(): string { return process.env['comspec'] || 'cmd.exe'; } -/** - * Sanitizes a VS Code process environment by removing all Electron/VS Code-related values. - */ -export function sanitizeProcessEnvironment(env: Platform.IProcessEnvironment, ...preserve: string[]): void { - const set = preserve.reduce((set, key) => { - set[key] = true; - return set; - }, {} as Record); - const keysToRemove = [ - /^ELECTRON_.+$/, - /^GOOGLE_API_KEY$/, - /^VSCODE_.+$/, - /^SNAP(|_.*)$/ - ]; - const envKeys = Object.keys(env); - envKeys - .filter(key => !set[key]) - .forEach(envKey => { - for (let i = 0; i < keysToRemove.length; i++) { - if (envKey.search(keysToRemove[i]) !== -1) { - delete env[envKey]; - break; - } - } - }); -} - export abstract class AbstractProcess { private cmd: string; private args: string[]; diff --git a/src/vs/base/test/common/processes.test.ts b/src/vs/base/test/common/processes.test.ts new file mode 100644 index 00000000000..cd54b6fd724 --- /dev/null +++ b/src/vs/base/test/common/processes.test.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as processes from 'vs/base/common/processes'; + +suite('Processes', () => { + test('sanitizeProcessEnvironment', () => { + let env = { + FOO: 'bar', + ELECTRON_ENABLE_STACK_DUMPING: 'x', + ELECTRON_ENABLE_LOGGING: 'x', + ELECTRON_NO_ASAR: 'x', + ELECTRON_NO_ATTACH_CONSOLE: 'x', + ELECTRON_RUN_AS_NODE: 'x', + GOOGLE_API_KEY: 'x', + VSCODE_CLI: 'x', + VSCODE_DEV: 'x', + VSCODE_IPC_HOOK: 'x', + VSCODE_LOGS: 'x', + VSCODE_NLS_CONFIG: 'x', + VSCODE_PORTABLE: 'x', + VSCODE_PID: 'x', + VSCODE_NODE_CACHED_DATA_DIR: 'x', + VSCODE_NEW_VAR: 'x' + }; + processes.sanitizeProcessEnvironment(env); + assert.equal(env['FOO'], 'bar'); + assert.equal(Object.keys(env).length, 1); + }); +}); diff --git a/src/vs/base/test/node/processes/processes.test.ts b/src/vs/base/test/node/processes/processes.test.ts index 10199cf5bf3..76719506d6e 100644 --- a/src/vs/base/test/node/processes/processes.test.ts +++ b/src/vs/base/test/node/processes/processes.test.ts @@ -84,29 +84,4 @@ suite('Processes', () => { } }); }); - - - test('sanitizeProcessEnvironment', () => { - let env = { - FOO: 'bar', - ELECTRON_ENABLE_STACK_DUMPING: 'x', - ELECTRON_ENABLE_LOGGING: 'x', - ELECTRON_NO_ASAR: 'x', - ELECTRON_NO_ATTACH_CONSOLE: 'x', - ELECTRON_RUN_AS_NODE: 'x', - GOOGLE_API_KEY: 'x', - VSCODE_CLI: 'x', - VSCODE_DEV: 'x', - VSCODE_IPC_HOOK: 'x', - VSCODE_LOGS: 'x', - VSCODE_NLS_CONFIG: 'x', - VSCODE_PORTABLE: 'x', - VSCODE_PID: 'x', - VSCODE_NODE_CACHED_DATA_DIR: 'x', - VSCODE_NEW_VAR: 'x' - }; - processes.sanitizeProcessEnvironment(env); - assert.equal(env['FOO'], 'bar'); - assert.equal(Object.keys(env).length, 1); - }); }); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 6f80fc77c38..070d8874c22 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -16,7 +16,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { timeout } from 'vs/base/common/async'; -import { sanitizeProcessEnvironment } from 'vs/base/node/processes'; +import { sanitizeProcessEnvironment } from 'vs/base/common/processes'; const RENDERER_NO_PROCESS_ID = -1; diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 6fec000ba2d..23114676b64 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import { Terminal as XTermTerminal } from 'vscode-xterm'; -import { ITerminalInstance, IWindowsShellHelper, ITerminalProcessManager, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper, ITerminalProcessManager, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IProcessEnvironment } from 'vs/base/common/platform'; export const ITerminalInstanceService = createDecorator('terminalInstanceService'); @@ -15,4 +16,5 @@ export interface ITerminalInstanceService { getXtermConstructor(): Promise; createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager; + createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; } diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts similarity index 96% rename from src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts rename to src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index d46fcf801fc..18d6d58d78b 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -12,16 +12,16 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IWindowService } from 'vs/platform/windows/common/windows'; import { Schemas } from 'vs/base/common/network'; import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; -import { sanitizeProcessEnvironment } from 'vs/base/node/processes'; +import { sanitizeProcessEnvironment } from 'vs/base/common/processes'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IProductService } from 'vs/platform/product/common/product'; +import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -63,7 +63,8 @@ export class TerminalProcessManager implements ITerminalProcessManager { @IWindowService private readonly _windowService: IWindowService, @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, - @IProductService private readonly _productService: IProductService + @IProductService private readonly _productService: IProductService, + @ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService ) { this.ptyProcessReady = new Promise(c => { this.onProcessReady(() => { @@ -148,7 +149,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { } this._logService.debug(`Terminal process launching`, shellLaunchConfig, initialCwd, cols, rows, env); - this._process = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty); + this._process = this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, this._configHelper.config.windowsEnableConpty); } this.processState = ProcessState.LAUNCHING; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 727e5ab6201..d9d128e5f92 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -6,16 +6,19 @@ import * as nls from 'vs/nls'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { Terminal as XTermTerminal } from 'vscode-xterm'; -import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalProcessManager, IShellLaunchConfig, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/node/terminalProcessManager'; +import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager'; +import { IProcessEnvironment } from 'vs/base/common/platform'; +import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; let Terminal: typeof XTermTerminal; /** - * A service used by TerminalInstance that allows it to break its dependency on electron-browser and - * node layers, while at the same time avoiding a cyclic dependency on ITerminalService. + * A service used by TerminalInstance (and components owned by it) that allows it to break its + * dependency on electron-browser and node layers, while at the same time avoiding a cyclic + * dependency on ITerminalService. */ export class TerminalInstanceService implements ITerminalInstanceService { public _serviceBrand: any; @@ -25,7 +28,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { ) { } - async getXtermConstructor(): Promise { + public async getXtermConstructor(): Promise { if (!Terminal) { Terminal = (await import('vscode-xterm')).Terminal; // Enable xterm.js addons @@ -40,11 +43,15 @@ export class TerminalInstanceService implements ITerminalInstanceService { return Terminal; } - createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper { + public createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper { return new WindowsShellHelper(shellProcessId, instance, xterm); } - createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager { + public createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager { return this._instantiationService.createInstance(TerminalProcessManager, id, configHelper); } + + public createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess { + return new TerminalProcess(shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty); + } } \ No newline at end of file From ff5ae22403cdf705734d7822c89affca78564688 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 20:22:09 -0800 Subject: [PATCH 163/290] Remove more from electron-browser/terminalService --- .../contrib/terminal/browser/terminal.ts | 4 ++ .../terminal/browser/terminalConfigHelper.ts | 5 +- .../terminal/browser/terminalService.ts | 19 +++++- .../terminal/common/terminalService.ts | 45 ++++++++++++- .../electron-browser/terminalService.ts | 67 +++++-------------- .../contrib/terminal/node/terminal.ts | 17 ----- 6 files changed, 85 insertions(+), 72 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 23114676b64..ff7f6b95f5b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -18,3 +18,7 @@ export interface ITerminalInstanceService { createTerminalProcessManager(id: number, configHelper: ITerminalConfigHelper): ITerminalProcessManager; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; } + +export interface IBrowserTerminalConfigHelper extends ITerminalConfigHelper { + panelContainer: HTMLElement; +} diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index 91a780466ad..f4f0476caa0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -10,10 +10,11 @@ import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/ed import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { ITerminalConfiguration, ITerminalConfigHelper, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalConfiguration, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import Severity from 'vs/base/common/severity'; import { Terminal as XTermTerminal } from 'vscode-xterm'; import { INotificationService } from 'vs/platform/notification/common/notification'; +import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; const MINIMUM_FONT_SIZE = 6; const MAXIMUM_FONT_SIZE = 25; @@ -22,7 +23,7 @@ const MAXIMUM_FONT_SIZE = 25; * Encapsulates terminal configuration logic, the primary purpose of this file is so that platform * specific test cases can be written. */ -export class TerminalConfigHelper implements ITerminalConfigHelper { +export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { public panelContainer: HTMLElement; private _charMeasureElement: HTMLElement; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 051667c8a67..28a01868122 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -5,9 +5,9 @@ import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; -import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, IShellLaunchConfig, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, IShellLaunchConfig, NEVER_SUGGEST_SELECT_WINDOWS_SHELL_STORAGE_KEY, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as CommonTerminalService } from 'vs/workbench/contrib/terminal/common/terminalService'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; @@ -20,8 +20,11 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IWindowService } from 'vs/platform/windows/common/windows'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; +import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; +import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; export abstract class TerminalService extends CommonTerminalService implements ITerminalService { + protected _configHelper: IBrowserTerminalConfigHelper; constructor( @IContextKeyService contextKeyService: IContextKeyService, @@ -41,6 +44,12 @@ export abstract class TerminalService extends CommonTerminalService implements I protected abstract _getDefaultShell(p: platform.Platform): string; + public createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance { + const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig); + this._onInstanceCreated.fire(instance); + return instance; + } + public createTerminal(shell: IShellLaunchConfig = {}, wasNewTerminalAction?: boolean): ITerminalInstance { const terminalTab = this._instantiationService.createInstance(TerminalTab, this._terminalFocusContextKey, @@ -157,4 +166,10 @@ export abstract class TerminalService extends CommonTerminalService implements I panel.getFindWidget().find(true); } } + + public setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void { + this._configHelper.panelContainer = panelContainer; + this._terminalContainer = terminalContainer; + this._terminalTabs.forEach(tab => tab.attachToElement(this._terminalContainer)); + } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 859f4208b95..b2d81641a84 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -17,6 +17,9 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; +import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { isWindows } from 'vs/base/common/platform'; +import { basename } from 'vs/base/common/path'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -97,11 +100,13 @@ export abstract class TerminalService implements ITerminalService { this.onInstancesChanged(() => updateTerminalContextKeys()); } + protected abstract _getWslPath(path: string): Promise; + protected abstract _getWindowsBuildNumber(): number; + public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance; public abstract createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance; public abstract selectDefaultWindowsShell(): Promise; public abstract setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; - public abstract preparePathForTerminalAsync(path: string, executable: string, title: string): Promise; public createTerminalRenderer(name: string): ITerminalInstance { return this.createTerminal({ name, isRendererOnly: true }); @@ -425,4 +430,42 @@ export abstract class TerminalService implements ITerminalService { return [label, current] as [string, string]; }); } + + public preparePathForTerminalAsync(originalPath: string, executable: string, title: string): Promise { + return new Promise(c => { + const exe = executable; + if (!exe) { + c(originalPath); + return; + } + + const hasSpace = originalPath.indexOf(' ') !== -1; + + const pathBasename = basename(exe, '.exe'); + const isPowerShell = pathBasename === 'pwsh' || + title === 'pwsh' || + pathBasename === 'powershell' || + title === 'powershell'; + + if (isPowerShell && (hasSpace || originalPath.indexOf('\'') !== -1)) { + c(`& '${originalPath.replace(/'/g, '\'\'')}'`); + return; + } + + if (isWindows) { + // 17063 is the build number where wsl path was introduced. + // Update Windows uriPath to be executed in WSL. + if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (this._getWindowsBuildNumber() >= 17063)) { + c(this._getWslPath(originalPath)); + return; + } else if (hasSpace) { + c('"' + originalPath + '"'); + } else { + c(originalPath); + } + return; + } + c(escapeNonWindowsPath(originalPath)); + }); + } } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts index 2db2dcb3272..34dc08eec10 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalService.ts @@ -6,31 +6,29 @@ import * as nls from 'vs/nls'; import * as pfs from 'vs/base/node/pfs'; import * as platform from 'vs/base/common/platform'; -import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; 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 { ITerminalInstance, ITerminalService, IShellLaunchConfig, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalService as BrowserTerminalService } from 'vs/workbench/contrib/terminal/browser/terminalService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { getDefaultShell, linuxDistro, getWindowsBuildNumber, getWslPath } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getDefaultShell, linuxDistro, getWindowsBuildNumber } from 'vs/workbench/contrib/terminal/node/terminal'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ipcRenderer as ipc } from 'electron'; import { IOpenFileRequest, IWindowService } from 'vs/platform/windows/common/windows'; -import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IQuickInputService, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; import { coalesce } from 'vs/base/common/arrays'; import { IFileService } from 'vs/platform/files/common/files'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; -import { basename } from 'vs/base/common/path'; +import { execFile } from 'child_process'; export class TerminalService extends BrowserTerminalService implements ITerminalService { - private _configHelper: TerminalConfigHelper; public get configHelper(): ITerminalConfigHelper { return this._configHelper; } constructor( @@ -75,12 +73,6 @@ export class TerminalService extends BrowserTerminalService implements ITerminal }); } - public createInstance(terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, container: HTMLElement | undefined, shellLaunchConfig: IShellLaunchConfig, doCreateProcess: boolean): ITerminalInstance { - const instance = this._instantiationService.createInstance(TerminalInstance, terminalFocusContextKey, configHelper, container, shellLaunchConfig); - this._onInstanceCreated.fire(instance); - return instance; - } - protected _getDefaultShell(p: platform.Platform): string { return getDefaultShell(p); } @@ -140,47 +132,22 @@ export class TerminalService extends BrowserTerminalService implements ITerminal }); } - public setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void { - this._configHelper.panelContainer = panelContainer; - this._terminalContainer = terminalContainer; - this._terminalTabs.forEach(tab => tab.attachToElement(this._terminalContainer)); + protected _getWindowsBuildNumber(): number { + return getWindowsBuildNumber(); } - public preparePathForTerminalAsync(originalPath: string, executable: string, title: string): Promise { + /** + * Converts a path to a path on WSL using the wslpath utility. + * @param path The original path. + */ + protected _getWslPath(path: string): Promise { + if (getWindowsBuildNumber() < 17063) { + throw new Error('wslpath does not exist on Windows build < 17063'); + } return new Promise(c => { - const exe = executable; - if (!exe) { - c(originalPath); - return; - } - - const hasSpace = originalPath.indexOf(' ') !== -1; - - const pathBasename = basename(exe, '.exe'); - const isPowerShell = pathBasename === 'pwsh' || - title === 'pwsh' || - pathBasename === 'powershell' || - title === 'powershell'; - - if (isPowerShell && (hasSpace || originalPath.indexOf('\'') !== -1)) { - c(`& '${originalPath.replace(/'/g, '\'\'')}'`); - return; - } - - if (platform.isWindows) { - // 17063 is the build number where wsl path was introduced. - // Update Windows uriPath to be executed in WSL. - if (((exe.indexOf('wsl') !== -1) || ((exe.indexOf('bash.exe') !== -1) && (exe.indexOf('git') === -1))) && (getWindowsBuildNumber() >= 17063)) { - c(getWslPath(originalPath)); - return; - } else if (hasSpace) { - c('"' + originalPath + '"'); - } else { - c(originalPath); - } - return; - } - c(escapeNonWindowsPath(originalPath)); + execFile('bash.exe', ['-c', 'echo $(wslpath ' + escapeNonWindowsPath(path) + ')'], {}, (error, stdout, stderr) => { + c(escapeNonWindowsPath(stdout.trim())); + }); }); } } diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index 6200b9bf734..493fad0b833 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -8,8 +8,6 @@ import * as platform from 'vs/base/common/platform'; import * as processes from 'vs/base/node/processes'; import { readFile, fileExists } from 'vs/base/node/pfs'; import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; -import { execFile } from 'child_process'; -import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; export function getDefaultShell(p: platform.Platform): string { if (p === platform.Platform.Windows) { @@ -84,18 +82,3 @@ export function getWindowsBuildNumber(): number { } return buildNumber; } - -/** - * Converts a path to a path on WSL using the wslpath utility. - * @param path The original path. - */ -export function getWslPath(path: string): Promise { - if (getWindowsBuildNumber() < 17063) { - throw new Error('wslpath does not exist on Windows build < 17063'); - } - return new Promise(c => { - execFile('bash.exe', ['-c', 'echo $(wslpath ' + escapeNonWindowsPath(path) + ')'], {}, (error, stdout, stderr) => { - c(escapeNonWindowsPath(stdout.trim())); - }); - }); -} From 3a10272f1e43a8c4548d7f31704595a3831b2e41 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 4 Mar 2019 20:39:47 -0800 Subject: [PATCH 164/290] Create browser/terminal.contribution.ts --- .../terminal/browser/terminal.contribution.ts | 519 ++++++++++++++++++ .../terminal/browser/terminalFindWidget.ts | 1 - .../electron-browser/terminal.contribution.ts | 511 +---------------- src/vs/workbench/workbench.main.ts | 1 + 4 files changed, 526 insertions(+), 506 deletions(-) create mode 100644 src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts new file mode 100644 index 00000000000..a420a5355b3 --- /dev/null +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -0,0 +1,519 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import * as platform from 'vs/base/common/platform'; +import 'vs/css!./media/scrollbar'; +import 'vs/css!./media/terminal'; +import 'vs/css!./media/widgets'; +import 'vs/css!./media/xterm'; +import * as nls from 'vs/nls'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { CommandsRegistry } from 'vs/platform/commands/common/commands'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ActionBarExtensions, IActionBarRegistry, Scope } from 'vs/workbench/browser/actions'; +import * as panel from 'vs/workbench/browser/panel'; +import { getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; +import { Extensions as QuickOpenExtensions, IQuickOpenRegistry, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; +import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; +import { AllowWorkspaceShellTerminalCommand, ClearSelectionTerminalAction, ClearTerminalAction, CopyTerminalSelectionAction, CreateNewInActiveWorkspaceTerminalAction, CreateNewTerminalAction, DeleteToLineStartTerminalAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, DisallowWorkspaceShellTerminalCommand, FindNext, FindPrevious, FocusActiveTerminalAction, FocusNextPaneTerminalAction, FocusNextTerminalAction, FocusPreviousPaneTerminalAction, FocusPreviousTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, KillTerminalAction, MoveToLineEndTerminalAction, MoveToLineStartTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, RenameTerminalAction, ResizePaneDownTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, RunActiveFileInTerminalAction, RunSelectedTextInTerminalAction, ScrollDownPageTerminalAction, ScrollDownTerminalAction, ScrollToBottomTerminalAction, ScrollToNextCommandAction, ScrollToPreviousCommandAction, ScrollToTopTerminalAction, ScrollUpPageTerminalAction, ScrollUpTerminalAction, SelectAllTerminalAction, SelectDefaultShellWindowsTerminalAction, SelectToNextCommandAction, SelectToNextLineAction, SelectToPreviousCommandAction, SelectToPreviousLineAction, SendSequenceTerminalCommand, SplitInActiveWorkspaceTerminalAction, SplitTerminalAction, TerminalPasteAction, TERMINAL_PICKER_PREFIX, ToggleCaseSensitiveCommand, ToggleEscapeSequenceLoggingAction, ToggleRegexCommand, ToggleTerminalAction, ToggleWholeWordCommand } from 'vs/workbench/contrib/terminal/browser/terminalActions'; +import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; +import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; +import { KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, TerminalCursorStyle } from 'vs/workbench/contrib/terminal/common/terminal'; +import { registerColors } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; +import { setupTerminalCommands, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; +import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminalMenu'; +import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; +import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; +import { DEFAULT_COMMANDS_TO_SKIP_SHELL } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; + +const quickOpenRegistry = (Registry.as(QuickOpenExtensions.Quickopen)); + +const inTerminalsPicker = 'inTerminalPicker'; + +quickOpenRegistry.registerQuickOpenHandler( + new QuickOpenHandlerDescriptor( + TerminalPickerHandler, + TerminalPickerHandler.ID, + TERMINAL_PICKER_PREFIX, + inTerminalsPicker, + nls.localize('quickOpen.terminal', "Show All Opened Terminals") + ) +); + +const quickOpenNavigateNextInTerminalPickerId = 'workbench.action.quickOpenNavigateNextInTerminalPicker'; +CommandsRegistry.registerCommand( + { id: quickOpenNavigateNextInTerminalPickerId, handler: getQuickNavigateHandler(quickOpenNavigateNextInTerminalPickerId, true) }); + +const quickOpenNavigatePreviousInTerminalPickerId = 'workbench.action.quickOpenNavigatePreviousInTerminalPicker'; +CommandsRegistry.registerCommand( + { id: quickOpenNavigatePreviousInTerminalPickerId, handler: getQuickNavigateHandler(quickOpenNavigatePreviousInTerminalPickerId, false) }); + + +const configurationRegistry = Registry.as(Extensions.Configuration); +configurationRegistry.registerConfiguration({ + id: 'terminal', + order: 100, + title: nls.localize('terminalIntegratedConfigurationTitle', "Integrated Terminal"), + type: 'object', + properties: { + 'terminal.integrated.shellArgs.linux': { + 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' + }, + default: [] + }, + 'terminal.integrated.shellArgs.osx': { + 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' + }, + // Unlike on Linux, ~/.profile is not sourced when logging into a macOS session. This + // is the reason terminals on macOS typically run login shells by default which set up + // the environment. See http://unix.stackexchange.com/a/119675/115410 + default: ['-l'] + }, + 'terminal.integrated.shellArgs.windows': { + 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)."), + 'anyOf': [ + { + type: 'array', + items: { + type: 'string', + 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: 'string', + markdownDescription: nls.localize('terminal.integrated.shellArgs.windows.string', "The command line arguments in [command-line format](https://msdn.microsoft.com/en-au/08dfcab2-eb6e-49a4-80eb-87d4076c98c6) to use when on the Windows terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).") + } + ], + default: [] + }, + 'terminal.integrated.macOptionIsMeta': { + description: nls.localize('terminal.integrated.macOptionIsMeta', "Controls whether to treat the option key as the meta key in the terminal on macOS."), + type: 'boolean', + default: false + }, + 'terminal.integrated.macOptionClickForcesSelection': { + description: nls.localize('terminal.integrated.macOptionClickForcesSelection', "Controls whether to force selection when using Option+click on macOS. This will force a regular (line) selection and disallow the use of column selection mode. This enables copying and pasting using the regular terminal selection, for example, when mouse mode is enabled in tmux."), + type: 'boolean', + default: false + }, + 'terminal.integrated.copyOnSelection': { + description: nls.localize('terminal.integrated.copyOnSelection', "Controls whether text selected in the terminal will be copied to the clipboard."), + type: 'boolean', + default: false + }, + 'terminal.integrated.drawBoldTextInBrightColors': { + description: nls.localize('terminal.integrated.drawBoldTextInBrightColors', "Controls whether bold text in the terminal will always use the \"bright\" ANSI color variant."), + type: 'boolean', + default: true + }, + 'terminal.integrated.fontFamily': { + 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 + // 'terminal.integrated.fontLigatures': { + // 'description': nls.localize('terminal.integrated.fontLigatures', "Controls whether font ligatures are enabled in the terminal."), + // 'type': 'boolean', + // 'default': false + // }, + 'terminal.integrated.fontSize': { + description: nls.localize('terminal.integrated.fontSize', "Controls the font size in pixels of the terminal."), + type: 'number', + default: EDITOR_FONT_DEFAULTS.fontSize + }, + 'terminal.integrated.letterSpacing': { + description: nls.localize('terminal.integrated.letterSpacing', "Controls the letter spacing of the terminal, this is an integer value which represents the amount of additional pixels to add between characters."), + type: 'number', + default: DEFAULT_LETTER_SPACING + }, + 'terminal.integrated.lineHeight': { + description: nls.localize('terminal.integrated.lineHeight', "Controls the line height of the terminal, this number is multiplied by the terminal font size to get the actual line-height in pixels."), + type: 'number', + default: DEFAULT_LINE_HEIGHT + }, + 'terminal.integrated.fontWeight': { + type: 'string', + enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], + description: nls.localize('terminal.integrated.fontWeight', "The font weight to use within the terminal for non-bold text."), + default: 'normal' + }, + 'terminal.integrated.fontWeightBold': { + type: 'string', + enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], + description: nls.localize('terminal.integrated.fontWeightBold', "The font weight to use within the terminal for bold text."), + default: 'bold' + }, + 'terminal.integrated.cursorBlinking': { + description: nls.localize('terminal.integrated.cursorBlinking', "Controls whether the terminal cursor blinks."), + type: 'boolean', + default: false + }, + 'terminal.integrated.cursorStyle': { + description: nls.localize('terminal.integrated.cursorStyle', "Controls the style of terminal cursor."), + enum: [TerminalCursorStyle.BLOCK, TerminalCursorStyle.LINE, TerminalCursorStyle.UNDERLINE], + default: TerminalCursorStyle.BLOCK + }, + 'terminal.integrated.scrollback': { + description: nls.localize('terminal.integrated.scrollback', "Controls the maximum amount of lines the terminal keeps in its buffer."), + type: 'number', + default: 1000 + }, + 'terminal.integrated.setLocaleVariables': { + markdownDescription: nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal."), + type: 'boolean', + default: true + }, + 'terminal.integrated.rendererType': { + type: 'string', + enum: ['auto', 'canvas', 'dom'], + enumDescriptions: [ + nls.localize('terminal.integrated.rendererType.auto', "Let VS Code guess which renderer to use."), + nls.localize('terminal.integrated.rendererType.canvas', "Use the standard GPU/canvas-based renderer"), + 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.") + }, + 'terminal.integrated.rightClickBehavior': { + type: 'string', + enum: ['default', 'copyPaste', 'selectWord'], + enumDescriptions: [ + nls.localize('terminal.integrated.rightClickBehavior.default', "Show the context menu."), + nls.localize('terminal.integrated.rightClickBehavior.copyPaste', "Copy when there is a selection, otherwise paste."), + nls.localize('terminal.integrated.rightClickBehavior.selectWord', "Select the word under the cursor and show the context menu.") + ], + default: platform.isMacintosh ? 'selectWord' : platform.isWindows ? 'copyPaste' : 'default', + description: nls.localize('terminal.integrated.rightClickBehavior', "Controls how terminal reacts to right click.") + }, + 'terminal.integrated.cwd': { + description: nls.localize('terminal.integrated.cwd', "An explicit start path where the terminal will be launched, this is used as the current working directory (cwd) for the shell process. This may be particularly useful in workspace settings if the root directory is not a convenient cwd."), + type: 'string', + default: undefined + }, + 'terminal.integrated.confirmOnExit': { + description: nls.localize('terminal.integrated.confirmOnExit', "Controls whether to confirm on exit if there are active terminal sessions."), + type: 'boolean', + default: false + }, + 'terminal.integrated.enableBell': { + description: nls.localize('terminal.integrated.enableBell', "Controls whether the terminal bell is enabled."), + type: 'boolean', + default: false + }, + 'terminal.integrated.commandsToSkipShell': { + description: nls.localize('terminal.integrated.commandsToSkipShell', "A set of command IDs whose keybindings will not be sent to the shell and instead always be handled by Code. This allows the use of keybindings that would normally be consumed by the shell to act the same as when the terminal is not focused, for example ctrl+p to launch Quick Open.\nDefault Skipped Commands:\n\n{0}", DEFAULT_COMMANDS_TO_SKIP_SHELL.sort().map(command => `- ${command}`).join('\n')), + type: 'array', + items: { + type: 'string' + }, + default: [] + }, + 'terminal.integrated.env.osx': { + 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'] + }, + default: {} + }, + 'terminal.integrated.env.linux': { + 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'] + }, + default: {} + }, + 'terminal.integrated.env.windows': { + 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'] + }, + default: {} + }, + 'terminal.integrated.showExitAlert': { + 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.splitCwd': { + description: nls.localize('terminal.integrated.splitCwd', "Controls the working directory a split terminal starts with."), + type: 'string', + enum: ['workspaceRoot', 'initial', 'inherited'], + enumDescriptions: [ + nls.localize('terminal.integrated.splitCwd.workspaceRoot', "A new split terminal will use the workspace root as the working directory. In a multi-root workspace a choice for which root folder to use is offered."), + nls.localize('terminal.integrated.splitCwd.initial', "A new split terminal will use the working directory that the parent terminal started with."), + nls.localize('terminal.integrated.splitCwd.inherited', "On macOS and Linux, a new split terminal will use the working directory of the parent terminal. On Windows, this behaves the same as initial."), + ], + default: 'inherited' + }, + 'terminal.integrated.windowsEnableConpty': { + description: nls.localize('terminal.integrated.windowsEnableConpty', "Whether to use ConPTY for Windows terminal process communication (requires Windows 10 build number 18309+). Winpty will be used if this is false."), + type: 'boolean', + default: false + } + } +}); + +const registry = Registry.as(ActionExtensions.WorkbenchActions); +registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenTermAction, QuickOpenTermAction.ID, QuickOpenTermAction.LABEL), 'Terminal: Switch Active Terminal', nls.localize('terminal', "Terminal")); +const actionBarRegistry = Registry.as(ActionBarExtensions.Actionbar); +actionBarRegistry.registerActionBarContributor(Scope.VIEWER, QuickOpenActionTermContributor); + +(Registry.as(panel.Extensions.Panels)).registerPanel(new panel.PanelDescriptor( + TerminalPanel, + TERMINAL_PANEL_ID, + nls.localize('terminal', "Terminal"), + 'terminal', + 40, + TERMINAL_COMMAND_ID.TOGGLE +)); + +// On mac cmd+` is reserved to cycle between windows, that's why the keybindings use WinCtrl +const category = nls.localize('terminalCategory', "Terminal"); +const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), 'Terminal: Kill the Active Terminal Instance', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.KEY_C, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C } +}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FOCUS)), 'Terminal: Copy Selection', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_BACKTICK, + mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_BACKTICK } +}), 'Terminal: Create New Integrated Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearSelectionTerminalAction, ClearSelectionTerminalAction.ID, ClearSelectionTerminalAction.LABEL, { + primary: KeyCode.Escape, + linux: { primary: KeyCode.Escape } +}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE)), 'Terminal: Escape selection', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewInActiveWorkspaceTerminalAction, CreateNewInActiveWorkspaceTerminalAction.ID, CreateNewInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Create New Integrated Terminal (In Active Workspace)', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusActiveTerminalAction, FocusActiveTerminalAction.ID, FocusActiveTerminalAction.LABEL), 'Terminal: Focus Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextTerminalAction, FocusNextTerminalAction.ID, FocusNextTerminalAction.LABEL), 'Terminal: Focus Next Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousTerminalAction, FocusPreviousTerminalAction.ID, FocusPreviousTerminalAction.LABEL), 'Terminal: Focus Previous Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.KEY_V, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V }, + // Don't apply to Mac since cmd+v works + mac: { primary: 0 } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Paste into Active Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL, { + // Don't use ctrl+a by default as that would override the common go to start + // of prompt shell binding + primary: 0, + // Technically this doesn't need to be here as it will fall back to this + // behavior anyway when handed to xterm.js, having this handled by VS Code + // makes it easier for users to see how it works though. + mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_A } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select All', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunSelectedTextInTerminalAction, RunSelectedTextInTerminalAction.ID, RunSelectedTextInTerminalAction.LABEL), 'Terminal: Run Selected Text In Active Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunActiveFileInTerminalAction, RunActiveFileInTerminalAction.ID, RunActiveFileInTerminalAction.LABEL), 'Terminal: Run Active File In Active Terminal', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.US_BACKTICK, + mac: { primary: KeyMod.WinCtrl | KeyCode.US_BACKTICK } +}), 'View: Toggle Integrated Terminal', nls.localize('viewCategory', "View")); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollDownTerminalAction, ScrollDownTerminalAction.ID, ScrollDownTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Down (Line)', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollDownPageTerminalAction, ScrollDownPageTerminalAction.ID, ScrollDownPageTerminalAction.LABEL, { + primary: KeyMod.Shift | KeyCode.PageDown, + mac: { primary: KeyCode.PageDown } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Down (Page)', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToBottomTerminalAction, ScrollToBottomTerminalAction.ID, ScrollToBottomTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.End, + linux: { primary: KeyMod.Shift | KeyCode.End } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll to Bottom', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollUpTerminalAction, ScrollUpTerminalAction.ID, ScrollUpTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }, +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Up (Line)', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollUpPageTerminalAction, ScrollUpPageTerminalAction.ID, ScrollUpPageTerminalAction.LABEL, { + primary: KeyMod.Shift | KeyCode.PageUp, + mac: { primary: KeyCode.PageUp } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Up (Page)', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToTopTerminalAction, ScrollToTopTerminalAction.ID, ScrollToTopTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.Home, + linux: { primary: KeyMod.Shift | KeyCode.Home } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll to Top', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAction, ClearTerminalAction.ID, ClearTerminalAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_K } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingWeight.WorkbenchContrib + 1), 'Terminal: Clear', category); +if (platform.isWindows) { + actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category); +} +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowWorkspaceShellTerminalCommand, AllowWorkspaceShellTerminalCommand.ID, AllowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Allow Workspace Shell Configuration', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand.ID, DisallowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Disallow Workspace Shell Configuration', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAction, RenameTerminalAction.ID, RenameTerminalAction.LABEL), 'Terminal: Rename', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.KEY_F +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Find Widget', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.KEY_F +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Focus Find Widget', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(HideTerminalFindWidgetAction, HideTerminalFindWidgetAction.ID, HideTerminalFindWidgetAction.LABEL, { + primary: KeyCode.Escape, + secondary: [KeyMod.Shift | KeyCode.Escape] +}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE)), 'Terminal: Hide Find Widget', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordLeftTerminalAction, DeleteWordLeftTerminalAction.ID, DeleteWordLeftTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.Backspace, + mac: { primary: KeyMod.Alt | KeyCode.Backspace } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Left', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordRightTerminalAction, DeleteWordRightTerminalAction.ID, DeleteWordRightTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.Delete, + mac: { primary: KeyMod.Alt | KeyCode.Delete } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Right', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteToLineStartTerminalAction, DeleteToLineStartTerminalAction.ID, DeleteToLineStartTerminalAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete To Line Start', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(MoveToLineStartTerminalAction, MoveToLineStartTerminalAction.ID, MoveToLineStartTerminalAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.LeftArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Move To Line Start', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(MoveToLineEndTerminalAction, MoveToLineEndTerminalAction.ID, MoveToLineEndTerminalAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.RightArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Move To Line End', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SplitTerminalAction, SplitTerminalAction.ID, SplitTerminalAction.LABEL, { + primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH, + secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_5], + mac: { + primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH, + secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_5] + } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Split', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SplitInActiveWorkspaceTerminalAction, SplitInActiveWorkspaceTerminalAction.ID, SplitInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Split Terminal (In Active Workspace)', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousPaneTerminalAction, FocusPreviousPaneTerminalAction.ID, FocusPreviousPaneTerminalAction.LABEL, { + primary: KeyMod.Alt | KeyCode.LeftArrow, + secondary: [KeyMod.Alt | KeyCode.UpArrow], + mac: { + primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.LeftArrow, + secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.UpArrow] + } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Previous Pane', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextPaneTerminalAction, FocusNextPaneTerminalAction.ID, FocusNextPaneTerminalAction.LABEL, { + primary: KeyMod.Alt | KeyCode.RightArrow, + secondary: [KeyMod.Alt | KeyCode.DownArrow], + mac: { + primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.RightArrow, + secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.DownArrow] + } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Next Pane', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneLeftTerminalAction, ResizePaneLeftTerminalAction.ID, ResizePaneLeftTerminalAction.LABEL, { + primary: 0, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow }, + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Left', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneRightTerminalAction, ResizePaneRightTerminalAction.ID, ResizePaneRightTerminalAction.LABEL, { + primary: 0, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow }, + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Right', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneUpTerminalAction, ResizePaneUpTerminalAction.ID, ResizePaneUpTerminalAction.LABEL, { + primary: 0, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }, + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.UpArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Up', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneDownTerminalAction, ResizePaneDownTerminalAction.ID, ResizePaneDownTerminalAction.LABEL, { + primary: 0, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow }, + mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.DownArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Down', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToPreviousCommandAction, ScrollToPreviousCommandAction.ID, ScrollToPreviousCommandAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.UpArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll To Previous Command', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToNextCommandAction, ScrollToNextCommandAction.ID, ScrollToNextCommandAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyCode.DownArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll To Next Command', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousCommandAction, SelectToPreviousCommandAction.ID, SelectToPreviousCommandAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select To Previous Command', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToNextCommandAction, SelectToNextCommandAction.ID, SelectToNextCommandAction.LABEL, { + primary: 0, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select To Next Command', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousLineAction, SelectToPreviousLineAction.ID, SelectToPreviousLineAction.LABEL), 'Terminal: Select To Previous Line', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToNextLineAction, SelectToNextLineAction.ID, SelectToNextLineAction.LABEL), 'Terminal: Select To Next Line', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleEscapeSequenceLoggingAction, ToggleEscapeSequenceLoggingAction.ID, ToggleEscapeSequenceLoggingAction.LABEL), 'Terminal: Toggle Escape Sequence Logging', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleRegexCommand, ToggleRegexCommand.ID, ToggleRegexCommand.LABEL, { + primary: KeyMod.Alt | KeyCode.KEY_R, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R } +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find by regex'); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleRegexCommand, ToggleRegexCommand.ID_TERMINAL_FOCUS, ToggleRegexCommand.LABEL, { + primary: KeyMod.Alt | KeyCode.KEY_R, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find by regex', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleWholeWordCommand, ToggleWholeWordCommand.ID, ToggleWholeWordCommand.LABEL, { + primary: KeyMod.Alt | KeyCode.KEY_W, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W } +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find whole word'); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleWholeWordCommand, ToggleWholeWordCommand.ID_TERMINAL_FOCUS, ToggleWholeWordCommand.LABEL, { + primary: KeyMod.Alt | KeyCode.KEY_W, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find whole word', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID, ToggleCaseSensitiveCommand.LABEL, { + primary: KeyMod.Alt | KeyCode.KEY_C, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C } +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find match case'); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID_TERMINAL_FOCUS, ToggleCaseSensitiveCommand.LABEL, { + primary: KeyMod.Alt | KeyCode.KEY_C, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find match case', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindNext, FindNext.ID_TERMINAL_FOCUS, FindNext.LABEL, { + primary: KeyCode.F3, + mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_G, secondary: [KeyCode.F3] } +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Find next', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindNext, FindNext.ID, FindNext.LABEL, { + primary: KeyCode.F3, + mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_G, secondary: [KeyCode.F3] } +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find next'); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, FindPrevious.ID_TERMINAL_FOCUS, FindPrevious.LABEL, { + primary: KeyMod.Shift | KeyCode.F3, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G, secondary: [KeyMod.Shift | KeyCode.F3] }, +}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Find previous', category); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, FindPrevious.ID, FindPrevious.LABEL, { + primary: KeyMod.Shift | KeyCode.F3, + mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G, secondary: [KeyMod.Shift | KeyCode.F3] }, +}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find previous'); + + +const sendSequenceTerminalCommand = new SendSequenceTerminalCommand({ + id: SendSequenceTerminalCommand.ID, + precondition: null, + description: { + description: `Send Custom Sequence To Terminal`, + args: [{ + name: 'args', + schema: { + 'type': 'object', + 'required': ['text'], + 'properties': { + 'text': { + 'type': 'string' + } + }, + } + }] + } +}); +sendSequenceTerminalCommand.register(); + +setupTerminalCommands(); +setupTerminalMenu(); + +registerColors(); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts index e5a54d0ba74..db30d122c39 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalFindWidget.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./terminalFindWidget'; import { SimpleFindWidget } from 'vs/editor/contrib/find/simpleFindWidget'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_INPUT_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED } from 'vs/workbench/contrib/terminal/common/terminal'; diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index d4cec6691ce..a55b93caa40 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -3,66 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!../browser/media/scrollbar'; -import 'vs/css!../browser/media/terminal'; -import 'vs/css!../browser/media/xterm'; -import 'vs/css!../browser/media/widgets'; -import * as nls from 'vs/nls'; -import * as panel from 'vs/workbench/browser/panel'; import * as platform from 'vs/base/common/platform'; +import * as nls from 'vs/nls'; import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; -import { ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_PANEL_ID, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TerminalCursorStyle, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE, DEFAULT_LINE_HEIGHT, DEFAULT_LETTER_SPACING, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED } from 'vs/workbench/contrib/terminal/common/terminal'; -import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; -import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; -import { ClearSelectionTerminalAction, CreateNewTerminalAction, CreateNewInActiveWorkspaceTerminalAction, FocusActiveTerminalAction, FocusNextTerminalAction, FocusPreviousTerminalAction, SelectDefaultShellWindowsTerminalAction, RunSelectedTextInTerminalAction, RunActiveFileInTerminalAction, ScrollDownTerminalAction, ScrollDownPageTerminalAction, ScrollToBottomTerminalAction, ScrollUpTerminalAction, ScrollUpPageTerminalAction, ScrollToTopTerminalAction, TerminalPasteAction, ClearTerminalAction, AllowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand, RenameTerminalAction, FocusTerminalFindWidgetAction, HideTerminalFindWidgetAction, DeleteWordLeftTerminalAction, DeleteWordRightTerminalAction, QuickOpenActionTermContributor, QuickOpenTermAction, MoveToLineStartTerminalAction, MoveToLineEndTerminalAction, SplitTerminalAction, SplitInActiveWorkspaceTerminalAction, FocusPreviousPaneTerminalAction, FocusNextPaneTerminalAction, ResizePaneLeftTerminalAction, ResizePaneRightTerminalAction, ResizePaneUpTerminalAction, ResizePaneDownTerminalAction, ScrollToPreviousCommandAction, ScrollToNextCommandAction, SelectToPreviousCommandAction, SelectToNextCommandAction, SelectToPreviousLineAction, SelectToNextLineAction, ToggleEscapeSequenceLoggingAction, SendSequenceTerminalCommand, ToggleRegexCommand, ToggleWholeWordCommand, ToggleCaseSensitiveCommand, FindNext, FindPrevious, DeleteToLineStartTerminalAction, TERMINAL_PICKER_PREFIX, KillTerminalAction, CopyTerminalSelectionAction, SelectAllTerminalAction, ToggleTerminalAction } from 'vs/workbench/contrib/terminal/browser/terminalActions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { TerminalService } from 'vs/workbench/contrib/terminal/electron-browser/terminalService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; -import { registerColors } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; -import { getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; -import { IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; -import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbench/browser/actions'; -import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { TerminalPanel } from 'vs/workbench/contrib/terminal/browser/terminalPanel'; -import { TerminalPickerHandler } from 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; -import { setupTerminalCommands, TERMINAL_COMMAND_ID } from 'vs/workbench/contrib/terminal/common/terminalCommands'; -import { setupTerminalMenu } from 'vs/workbench/contrib/terminal/common/terminalMenu'; -import { DEFAULT_COMMANDS_TO_SKIP_SHELL } from 'vs/workbench/contrib/terminal/browser/terminalInstance'; -import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService'; +import { Registry } from 'vs/platform/registry/common/platform'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; - -const quickOpenRegistry = (Registry.as(QuickOpenExtensions.Quickopen)); - -const inTerminalsPicker = 'inTerminalPicker'; - -quickOpenRegistry.registerQuickOpenHandler( - new QuickOpenHandlerDescriptor( - TerminalPickerHandler, - TerminalPickerHandler.ID, - TERMINAL_PICKER_PREFIX, - inTerminalsPicker, - nls.localize('quickOpen.terminal', "Show All Opened Terminals") - ) -); - -const quickOpenNavigateNextInTerminalPickerId = 'workbench.action.quickOpenNavigateNextInTerminalPicker'; -CommandsRegistry.registerCommand( - { id: quickOpenNavigateNextInTerminalPickerId, handler: getQuickNavigateHandler(quickOpenNavigateNextInTerminalPickerId, true) }); - -const quickOpenNavigatePreviousInTerminalPickerId = 'workbench.action.quickOpenNavigatePreviousInTerminalPicker'; -CommandsRegistry.registerCommand( - { id: quickOpenNavigatePreviousInTerminalPickerId, handler: getQuickNavigateHandler(quickOpenNavigatePreviousInTerminalPickerId, false) }); - - -const registry = Registry.as(ActionExtensions.WorkbenchActions); -registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenTermAction, QuickOpenTermAction.ID, QuickOpenTermAction.LABEL), 'Terminal: Switch Active Terminal', nls.localize('terminal', "Terminal")); -const actionBarRegistry = Registry.as(ActionBarExtensions.Actionbar); -actionBarRegistry.registerActionBarContributor(Scope.VIEWER, QuickOpenActionTermContributor); +import { ITerminalService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService'; +import { TerminalService } from 'vs/workbench/contrib/terminal/electron-browser/terminalService'; +import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; const configurationRegistry = Registry.as(Extensions.Configuration); configurationRegistry.registerConfiguration({ @@ -76,467 +26,18 @@ configurationRegistry.registerConfiguration({ type: 'string', default: getDefaultShell(platform.Platform.Linux) }, - 'terminal.integrated.shellArgs.linux': { - 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' - }, - default: [] - }, 'terminal.integrated.shell.osx': { 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: getDefaultShell(platform.Platform.Mac) }, - 'terminal.integrated.shellArgs.osx': { - 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' - }, - // Unlike on Linux, ~/.profile is not sourced when logging into a macOS session. This - // is the reason terminals on macOS typically run login shells by default which set up - // the environment. See http://unix.stackexchange.com/a/119675/115410 - default: ['-l'] - }, 'terminal.integrated.shell.windows': { 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: getDefaultShell(platform.Platform.Windows) - }, - 'terminal.integrated.shellArgs.windows': { - 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)."), - 'anyOf': [ - { - type: 'array', - items: { - type: 'string', - 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: 'string', - markdownDescription: nls.localize('terminal.integrated.shellArgs.windows.string', "The command line arguments in [command-line format](https://msdn.microsoft.com/en-au/08dfcab2-eb6e-49a4-80eb-87d4076c98c6) to use when on the Windows terminal. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).") - } - ], - default: [] - }, - 'terminal.integrated.macOptionIsMeta': { - description: nls.localize('terminal.integrated.macOptionIsMeta', "Controls whether to treat the option key as the meta key in the terminal on macOS."), - type: 'boolean', - default: false - }, - 'terminal.integrated.macOptionClickForcesSelection': { - description: nls.localize('terminal.integrated.macOptionClickForcesSelection', "Controls whether to force selection when using Option+click on macOS. This will force a regular (line) selection and disallow the use of column selection mode. This enables copying and pasting using the regular terminal selection, for example, when mouse mode is enabled in tmux."), - type: 'boolean', - default: false - }, - 'terminal.integrated.copyOnSelection': { - description: nls.localize('terminal.integrated.copyOnSelection', "Controls whether text selected in the terminal will be copied to the clipboard."), - type: 'boolean', - default: false - }, - 'terminal.integrated.drawBoldTextInBrightColors': { - description: nls.localize('terminal.integrated.drawBoldTextInBrightColors', "Controls whether bold text in the terminal will always use the \"bright\" ANSI color variant."), - type: 'boolean', - default: true - }, - 'terminal.integrated.fontFamily': { - 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 - // 'terminal.integrated.fontLigatures': { - // 'description': nls.localize('terminal.integrated.fontLigatures', "Controls whether font ligatures are enabled in the terminal."), - // 'type': 'boolean', - // 'default': false - // }, - 'terminal.integrated.fontSize': { - description: nls.localize('terminal.integrated.fontSize', "Controls the font size in pixels of the terminal."), - type: 'number', - default: EDITOR_FONT_DEFAULTS.fontSize - }, - 'terminal.integrated.letterSpacing': { - description: nls.localize('terminal.integrated.letterSpacing', "Controls the letter spacing of the terminal, this is an integer value which represents the amount of additional pixels to add between characters."), - type: 'number', - default: DEFAULT_LETTER_SPACING - }, - 'terminal.integrated.lineHeight': { - description: nls.localize('terminal.integrated.lineHeight', "Controls the line height of the terminal, this number is multiplied by the terminal font size to get the actual line-height in pixels."), - type: 'number', - default: DEFAULT_LINE_HEIGHT - }, - 'terminal.integrated.fontWeight': { - type: 'string', - enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], - description: nls.localize('terminal.integrated.fontWeight', "The font weight to use within the terminal for non-bold text."), - default: 'normal' - }, - 'terminal.integrated.fontWeightBold': { - type: 'string', - enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], - description: nls.localize('terminal.integrated.fontWeightBold', "The font weight to use within the terminal for bold text."), - default: 'bold' - }, - 'terminal.integrated.cursorBlinking': { - description: nls.localize('terminal.integrated.cursorBlinking', "Controls whether the terminal cursor blinks."), - type: 'boolean', - default: false - }, - 'terminal.integrated.cursorStyle': { - description: nls.localize('terminal.integrated.cursorStyle', "Controls the style of terminal cursor."), - enum: [TerminalCursorStyle.BLOCK, TerminalCursorStyle.LINE, TerminalCursorStyle.UNDERLINE], - default: TerminalCursorStyle.BLOCK - }, - 'terminal.integrated.scrollback': { - description: nls.localize('terminal.integrated.scrollback', "Controls the maximum amount of lines the terminal keeps in its buffer."), - type: 'number', - default: 1000 - }, - 'terminal.integrated.setLocaleVariables': { - markdownDescription: nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal."), - type: 'boolean', - default: true - }, - 'terminal.integrated.rendererType': { - type: 'string', - enum: ['auto', 'canvas', 'dom'], - enumDescriptions: [ - nls.localize('terminal.integrated.rendererType.auto', "Let VS Code guess which renderer to use."), - nls.localize('terminal.integrated.rendererType.canvas', "Use the standard GPU/canvas-based renderer"), - 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.") - }, - 'terminal.integrated.rightClickBehavior': { - type: 'string', - enum: ['default', 'copyPaste', 'selectWord'], - enumDescriptions: [ - nls.localize('terminal.integrated.rightClickBehavior.default', "Show the context menu."), - nls.localize('terminal.integrated.rightClickBehavior.copyPaste', "Copy when there is a selection, otherwise paste."), - nls.localize('terminal.integrated.rightClickBehavior.selectWord', "Select the word under the cursor and show the context menu.") - ], - default: platform.isMacintosh ? 'selectWord' : platform.isWindows ? 'copyPaste' : 'default', - description: nls.localize('terminal.integrated.rightClickBehavior', "Controls how terminal reacts to right click.") - }, - 'terminal.integrated.cwd': { - description: nls.localize('terminal.integrated.cwd', "An explicit start path where the terminal will be launched, this is used as the current working directory (cwd) for the shell process. This may be particularly useful in workspace settings if the root directory is not a convenient cwd."), - type: 'string', - default: undefined - }, - 'terminal.integrated.confirmOnExit': { - description: nls.localize('terminal.integrated.confirmOnExit', "Controls whether to confirm on exit if there are active terminal sessions."), - type: 'boolean', - default: false - }, - 'terminal.integrated.enableBell': { - description: nls.localize('terminal.integrated.enableBell', "Controls whether the terminal bell is enabled."), - type: 'boolean', - default: false - }, - 'terminal.integrated.commandsToSkipShell': { - description: nls.localize('terminal.integrated.commandsToSkipShell', "A set of command IDs whose keybindings will not be sent to the shell and instead always be handled by Code. This allows the use of keybindings that would normally be consumed by the shell to act the same as when the terminal is not focused, for example ctrl+p to launch Quick Open.\nDefault Skipped Commands:\n\n{0}", DEFAULT_COMMANDS_TO_SKIP_SHELL.sort().map(command => `- ${command}`).join('\n')), - type: 'array', - items: { - type: 'string' - }, - default: [] - }, - 'terminal.integrated.env.osx': { - 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'] - }, - default: {} - }, - 'terminal.integrated.env.linux': { - 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'] - }, - default: {} - }, - 'terminal.integrated.env.windows': { - 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'] - }, - default: {} - }, - 'terminal.integrated.showExitAlert': { - 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.splitCwd': { - description: nls.localize('terminal.integrated.splitCwd', "Controls the working directory a split terminal starts with."), - type: 'string', - enum: ['workspaceRoot', 'initial', 'inherited'], - enumDescriptions: [ - nls.localize('terminal.integrated.splitCwd.workspaceRoot', "A new split terminal will use the workspace root as the working directory. In a multi-root workspace a choice for which root folder to use is offered."), - nls.localize('terminal.integrated.splitCwd.initial', "A new split terminal will use the working directory that the parent terminal started with."), - nls.localize('terminal.integrated.splitCwd.inherited', "On macOS and Linux, a new split terminal will use the working directory of the parent terminal. On Windows, this behaves the same as initial."), - ], - default: 'inherited' - }, - 'terminal.integrated.windowsEnableConpty': { - description: nls.localize('terminal.integrated.windowsEnableConpty', "Whether to use ConPTY for Windows terminal process communication (requires Windows 10 build number 18309+). Winpty will be used if this is false."), - type: 'boolean', - default: false } } }); registerSingleton(ITerminalService, TerminalService, true); registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); - -(Registry.as(panel.Extensions.Panels)).registerPanel(new panel.PanelDescriptor( - TerminalPanel, - TERMINAL_PANEL_ID, - nls.localize('terminal', "Terminal"), - 'terminal', - 40, - TERMINAL_COMMAND_ID.TOGGLE -)); - -// On mac cmd+` is reserved to cycle between windows, that's why the keybindings use WinCtrl -const category = nls.localize('terminalCategory', "Terminal"); -const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(KillTerminalAction, KillTerminalAction.ID, KillTerminalAction.LABEL), 'Terminal: Kill the Active Terminal Instance', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CopyTerminalSelectionAction, CopyTerminalSelectionAction.ID, CopyTerminalSelectionAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.KEY_C, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_C } -}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FOCUS)), 'Terminal: Copy Selection', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewTerminalAction, CreateNewTerminalAction.ID, CreateNewTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.US_BACKTICK, - mac: { primary: KeyMod.WinCtrl | KeyMod.Shift | KeyCode.US_BACKTICK } -}), 'Terminal: Create New Integrated Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearSelectionTerminalAction, ClearSelectionTerminalAction.ID, ClearSelectionTerminalAction.LABEL, { - primary: KeyCode.Escape, - linux: { primary: KeyCode.Escape } -}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_NOT_VISIBLE)), 'Terminal: Escape selection', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(CreateNewInActiveWorkspaceTerminalAction, CreateNewInActiveWorkspaceTerminalAction.ID, CreateNewInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Create New Integrated Terminal (In Active Workspace)', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusActiveTerminalAction, FocusActiveTerminalAction.ID, FocusActiveTerminalAction.LABEL), 'Terminal: Focus Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextTerminalAction, FocusNextTerminalAction.ID, FocusNextTerminalAction.LABEL), 'Terminal: Focus Next Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousTerminalAction, FocusPreviousTerminalAction.ID, FocusPreviousTerminalAction.LABEL), 'Terminal: Focus Previous Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TerminalPasteAction, TerminalPasteAction.ID, TerminalPasteAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.KEY_V, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_V }, - // Don't apply to Mac since cmd+v works - mac: { primary: 0 } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Paste into Active Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectAllTerminalAction, SelectAllTerminalAction.ID, SelectAllTerminalAction.LABEL, { - // Don't use ctrl+a by default as that would override the common go to start - // of prompt shell binding - primary: 0, - // Technically this doesn't need to be here as it will fall back to this - // behavior anyway when handed to xterm.js, having this handled by VS Code - // makes it easier for users to see how it works though. - mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_A } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select All', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunSelectedTextInTerminalAction, RunSelectedTextInTerminalAction.ID, RunSelectedTextInTerminalAction.LABEL), 'Terminal: Run Selected Text In Active Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RunActiveFileInTerminalAction, RunActiveFileInTerminalAction.ID, RunActiveFileInTerminalAction.LABEL), 'Terminal: Run Active File In Active Terminal', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.US_BACKTICK, - mac: { primary: KeyMod.WinCtrl | KeyCode.US_BACKTICK } -}), 'View: Toggle Integrated Terminal', nls.localize('viewCategory', "View")); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollDownTerminalAction, ScrollDownTerminalAction.ID, ScrollDownTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageDown, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Down (Line)', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollDownPageTerminalAction, ScrollDownPageTerminalAction.ID, ScrollDownPageTerminalAction.LABEL, { - primary: KeyMod.Shift | KeyCode.PageDown, - mac: { primary: KeyCode.PageDown } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Down (Page)', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToBottomTerminalAction, ScrollToBottomTerminalAction.ID, ScrollToBottomTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.End, - linux: { primary: KeyMod.Shift | KeyCode.End } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll to Bottom', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollUpTerminalAction, ScrollUpTerminalAction.ID, ScrollUpTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.PageUp, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }, -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Up (Line)', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollUpPageTerminalAction, ScrollUpPageTerminalAction.ID, ScrollUpPageTerminalAction.LABEL, { - primary: KeyMod.Shift | KeyCode.PageUp, - mac: { primary: KeyCode.PageUp } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll Up (Page)', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToTopTerminalAction, ScrollToTopTerminalAction.ID, ScrollToTopTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.Home, - linux: { primary: KeyMod.Shift | KeyCode.Home } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll to Top', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAction, ClearTerminalAction.ID, ClearTerminalAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_K } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingWeight.WorkbenchContrib + 1), 'Terminal: Clear', category); -if (platform.isWindows) { - actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category); -} -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowWorkspaceShellTerminalCommand, AllowWorkspaceShellTerminalCommand.ID, AllowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Allow Workspace Shell Configuration', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand.ID, DisallowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Disallow Workspace Shell Configuration', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAction, RenameTerminalAction.ID, RenameTerminalAction.LABEL), 'Terminal: Rename', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.KEY_F -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Find Widget', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusTerminalFindWidgetAction, FocusTerminalFindWidgetAction.ID, FocusTerminalFindWidgetAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.KEY_F -}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Focus Find Widget', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(HideTerminalFindWidgetAction, HideTerminalFindWidgetAction.ID, HideTerminalFindWidgetAction.LABEL, { - primary: KeyCode.Escape, - secondary: [KeyMod.Shift | KeyCode.Escape] -}, ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE)), 'Terminal: Hide Find Widget', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordLeftTerminalAction, DeleteWordLeftTerminalAction.ID, DeleteWordLeftTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.Backspace, - mac: { primary: KeyMod.Alt | KeyCode.Backspace } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Left', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteWordRightTerminalAction, DeleteWordRightTerminalAction.ID, DeleteWordRightTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.Delete, - mac: { primary: KeyMod.Alt | KeyCode.Delete } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete Word Right', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DeleteToLineStartTerminalAction, DeleteToLineStartTerminalAction.ID, DeleteToLineStartTerminalAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.Backspace } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Delete To Line Start', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(MoveToLineStartTerminalAction, MoveToLineStartTerminalAction.ID, MoveToLineStartTerminalAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.LeftArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Move To Line Start', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(MoveToLineEndTerminalAction, MoveToLineEndTerminalAction.ID, MoveToLineEndTerminalAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.RightArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Move To Line End', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SplitTerminalAction, SplitTerminalAction.ID, SplitTerminalAction.LABEL, { - primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH, - secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_5], - mac: { - primary: KeyMod.CtrlCmd | KeyCode.US_BACKSLASH, - secondary: [KeyMod.WinCtrl | KeyMod.Shift | KeyCode.KEY_5] - } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Split', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SplitInActiveWorkspaceTerminalAction, SplitInActiveWorkspaceTerminalAction.ID, SplitInActiveWorkspaceTerminalAction.LABEL), 'Terminal: Split Terminal (In Active Workspace)', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPreviousPaneTerminalAction, FocusPreviousPaneTerminalAction.ID, FocusPreviousPaneTerminalAction.LABEL, { - primary: KeyMod.Alt | KeyCode.LeftArrow, - secondary: [KeyMod.Alt | KeyCode.UpArrow], - mac: { - primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.LeftArrow, - secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.UpArrow] - } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Previous Pane', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusNextPaneTerminalAction, FocusNextPaneTerminalAction.ID, FocusNextPaneTerminalAction.LABEL, { - primary: KeyMod.Alt | KeyCode.RightArrow, - secondary: [KeyMod.Alt | KeyCode.DownArrow], - mac: { - primary: KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.RightArrow, - secondary: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.DownArrow] - } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Focus Next Pane', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneLeftTerminalAction, ResizePaneLeftTerminalAction.ID, ResizePaneLeftTerminalAction.LABEL, { - primary: 0, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow }, - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.LeftArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Left', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneRightTerminalAction, ResizePaneRightTerminalAction.ID, ResizePaneRightTerminalAction.LABEL, { - primary: 0, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow }, - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.RightArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Right', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneUpTerminalAction, ResizePaneUpTerminalAction.ID, ResizePaneUpTerminalAction.LABEL, { - primary: 0, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow }, - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.UpArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Up', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ResizePaneDownTerminalAction, ResizePaneDownTerminalAction.ID, ResizePaneDownTerminalAction.LABEL, { - primary: 0, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow }, - mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.DownArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Resize Pane Down', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToPreviousCommandAction, ScrollToPreviousCommandAction.ID, ScrollToPreviousCommandAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.UpArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll To Previous Command', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ScrollToNextCommandAction, ScrollToNextCommandAction.ID, ScrollToNextCommandAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyCode.DownArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Scroll To Next Command', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousCommandAction, SelectToPreviousCommandAction.ID, SelectToPreviousCommandAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.UpArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select To Previous Command', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToNextCommandAction, SelectToNextCommandAction.ID, SelectToNextCommandAction.LABEL, { - primary: 0, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.DownArrow } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Select To Next Command', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToPreviousLineAction, SelectToPreviousLineAction.ID, SelectToPreviousLineAction.LABEL), 'Terminal: Select To Previous Line', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectToNextLineAction, SelectToNextLineAction.ID, SelectToNextLineAction.LABEL), 'Terminal: Select To Next Line', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleEscapeSequenceLoggingAction, ToggleEscapeSequenceLoggingAction.ID, ToggleEscapeSequenceLoggingAction.LABEL), 'Terminal: Toggle Escape Sequence Logging', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleRegexCommand, ToggleRegexCommand.ID, ToggleRegexCommand.LABEL, { - primary: KeyMod.Alt | KeyCode.KEY_R, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R } -}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find by regex'); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleRegexCommand, ToggleRegexCommand.ID_TERMINAL_FOCUS, ToggleRegexCommand.LABEL, { - primary: KeyMod.Alt | KeyCode.KEY_R, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_R } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find by regex', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleWholeWordCommand, ToggleWholeWordCommand.ID, ToggleWholeWordCommand.LABEL, { - primary: KeyMod.Alt | KeyCode.KEY_W, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W } -}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find whole word'); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleWholeWordCommand, ToggleWholeWordCommand.ID_TERMINAL_FOCUS, ToggleWholeWordCommand.LABEL, { - primary: KeyMod.Alt | KeyCode.KEY_W, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_W } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find whole word', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID, ToggleCaseSensitiveCommand.LABEL, { - primary: KeyMod.Alt | KeyCode.KEY_C, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C } -}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Toggle find match case'); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleCaseSensitiveCommand, ToggleCaseSensitiveCommand.ID_TERMINAL_FOCUS, ToggleCaseSensitiveCommand.LABEL, { - primary: KeyMod.Alt | KeyCode.KEY_C, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_C } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Toggle find match case', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindNext, FindNext.ID_TERMINAL_FOCUS, FindNext.LABEL, { - primary: KeyCode.F3, - mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_G, secondary: [KeyCode.F3] } -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Find next', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindNext, FindNext.ID, FindNext.LABEL, { - primary: KeyCode.F3, - mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_G, secondary: [KeyCode.F3] } -}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find next'); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, FindPrevious.ID_TERMINAL_FOCUS, FindPrevious.LABEL, { - primary: KeyMod.Shift | KeyCode.F3, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G, secondary: [KeyMod.Shift | KeyCode.F3] }, -}, KEYBINDING_CONTEXT_TERMINAL_FOCUS), 'Terminal: Find previous', category); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FindPrevious, FindPrevious.ID, FindPrevious.LABEL, { - primary: KeyMod.Shift | KeyCode.F3, - mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_G, secondary: [KeyMod.Shift | KeyCode.F3] }, -}, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_FOCUSED), 'Terminal: Find previous'); - - -const sendSequenceTerminalCommand = new SendSequenceTerminalCommand({ - id: SendSequenceTerminalCommand.ID, - precondition: null, - description: { - description: `Send Custom Sequence To Terminal`, - args: [{ - name: 'args', - schema: { - 'type': 'object', - 'required': ['text'], - 'properties': { - 'text': { - 'type': 'string' - } - }, - } - }] - } -}); -sendSequenceTerminalCommand.register(); - -setupTerminalCommands(); -setupTerminalMenu(); - -registerColors(); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 84ed6ce8f02..69bf6bcd8ce 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -152,6 +152,7 @@ import 'vs/workbench/contrib/output/electron-browser/output.contribution'; import 'vs/workbench/contrib/output/browser/outputPanel'; // Terminal +import 'vs/workbench/contrib/terminal/browser/terminal.contribution'; import 'vs/workbench/contrib/terminal/electron-browser/terminal.contribution'; import 'vs/workbench/contrib/terminal/browser/terminalQuickOpen'; import 'vs/workbench/contrib/terminal/browser/terminalPanel'; From 31f6902afdc791513bb57f3fc4d9cf5aac2f7b8e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 09:42:23 +0100 Subject: [PATCH 165/290] exploration - auto release after build --- build/azure-pipelines/common/publish.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build/azure-pipelines/common/publish.ts b/build/azure-pipelines/common/publish.ts index 2095c2d2532..ef17c3fd685 100644 --- a/build/azure-pipelines/common/publish.ts +++ b/build/azure-pipelines/common/publish.ts @@ -152,9 +152,13 @@ async function publish(commit: string, quality: string, platform: string, type: const queuedBy = process.env['BUILD_QUEUEDBY']!; const sourceBranch = process.env['BUILD_SOURCEBRANCH']!; - const isReleased = quality === 'insider' - && /^master$|^refs\/heads\/master$/.test(sourceBranch) - && /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy); + const isReleased = ( + // Insiders: nightly build from master + (quality === 'insider' && /^master$|^refs\/heads\/master$/.test(sourceBranch) && /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy)) || + + // Exploration: any build from electron-4.0.x branch + (quality === 'exploration' && /^electron-4.0.x$|^refs\/heads\/electron-4.0.x$/.test(sourceBranch)) + ); console.log('Publishing...'); console.log('Quality:', quality); From 3f68665c306be9a04decb12f2bbbc51b5317190a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 09:39:45 +0100 Subject: [PATCH 166/290] strict null - contrib/outline --- src/tsconfig.strictNullChecks.json | 2 +- src/vs/workbench/contrib/outline/browser/outlinePanel.ts | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 8d70756d2f6..1c3308561b0 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -16,6 +16,7 @@ "./vs/workbench/contrib/emmet/**/*", "./vs/workbench/contrib/externalTerminal/**/*", "./vs/workbench/contrib/snippets/**/*.ts", + "./vs/workbench/contrib/outline/**/*.ts", "./vs/workbench/contrib/welcome/**/*.ts", "./vs/workbench/contrib/issue/**/*", "./vs/workbench/contrib/tasks/**/*.ts", @@ -277,7 +278,6 @@ "./vs/workbench/contrib/stats/test/workspaceStats.test.ts", "./vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts", "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", - "./vs/workbench/contrib/terminal/browser/terminalActions.ts", "./vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts", "./vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts", diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index 86d3df7c5ea..d6d2c3f39fc 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -47,6 +47,7 @@ import { OutlineDataSource, OutlineItemComparator, OutlineSortOrder, OutlineVirt import { IDataTreeViewState } from 'vs/base/browser/ui/tree/dataTree'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { basename } from 'vs/base/common/resources'; +import { IDataSource } from 'vs/base/browser/ui/tree/tree'; class RequestState { @@ -320,7 +321,7 @@ export class OutlinePanel extends ViewletPanel { treeContainer, new OutlineVirtualDelegate(), [new OutlineGroupRenderer(), this._treeRenderer], - this._treeDataSource, + this._treeDataSource as IDataSource, { expandOnlyOnTwistieClick: true, multipleSelectionSupport: false, @@ -342,7 +343,7 @@ export class OutlinePanel extends ViewletPanel { // feature: filter on type - keep tree and menu in sync this.disposables.push(this._tree.onDidUpdateOptions(e => { - this._outlineViewState.filterOnType = e.filterOnType; + this._outlineViewState.filterOnType = Boolean(e.filterOnType); })); // feature: expand all nodes when filtering (not when finding) @@ -355,7 +356,7 @@ export class OutlinePanel extends ViewletPanel { viewState = this._tree.getViewState(); this._tree.expandAll(); } else if (!pattern && viewState) { - this._tree.setInput(this._tree.getInput(), viewState); + this._tree.setInput(this._tree.getInput()!, viewState); viewState = undefined; } })); @@ -426,7 +427,7 @@ export class OutlinePanel extends ViewletPanel { private _showMessage(message: string) { dom.addClass(this._domNode, 'message'); - this._tree.setInput(undefined); + this._tree.setInput(undefined!); this._progressBar.stop().hide(); this._message.innerText = escape(message); } From 105f4f84fbe7770a0abcc13816525bfaf904f5b9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 09:45:28 +0100 Subject: [PATCH 167/290] more strict null --- src/tsconfig.strictNullChecks.json | 15 ++++++--------- .../services/progress/browser/progressService2.ts | 8 +++----- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 1c3308561b0..bd09c3b049a 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -17,12 +17,17 @@ "./vs/workbench/contrib/externalTerminal/**/*", "./vs/workbench/contrib/snippets/**/*.ts", "./vs/workbench/contrib/outline/**/*.ts", + "./vs/workbench/contrib/performance/**/*.ts", "./vs/workbench/contrib/welcome/**/*.ts", "./vs/workbench/contrib/issue/**/*", + "./vs/workbench/contrib/splash/**/*.ts", "./vs/workbench/contrib/tasks/**/*.ts", "./vs/workbench/services/commands/**/*", "./vs/workbench/services/files/node/watcher/**/*", - "./vs/workbench/services/themes/**/*.ts" + "./vs/workbench/services/themes/**/*.ts", + "./vs/workbench/services/bulkEdit/**/*.ts", + "./vs/workbench/services/progress/**/*.ts", + "./vs/workbench/services/timer/**/*.ts" ], "files": [ "./vs/monaco.d.ts", @@ -237,9 +242,6 @@ "./vs/workbench/contrib/output/common/outputLinkComputer.ts", "./vs/workbench/contrib/output/common/outputLinkProvider.ts", "./vs/workbench/contrib/output/node/outputAppender.ts", - "./vs/workbench/contrib/performance/electron-browser/perfviewEditor.ts", - "./vs/workbench/contrib/performance/electron-browser/startupProfiler.ts", - "./vs/workbench/contrib/performance/electron-browser/startupTimings.ts", "./vs/workbench/contrib/preferences/browser/settingsWidgets.ts", "./vs/workbench/contrib/preferences/common/smartSnippetInserter.ts", "./vs/workbench/contrib/preferences/test/common/smartSnippetInserter.test.ts", @@ -272,7 +274,6 @@ "./vs/workbench/contrib/search/test/browser/openFileHandler.test.ts", "./vs/workbench/contrib/search/test/common/searchModel.test.ts", "./vs/workbench/contrib/search/test/common/searchResult.test.ts", - "./vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts", "./vs/workbench/contrib/stats/node/stats.contribution.ts", "./vs/workbench/contrib/stats/node/workspaceStats.ts", "./vs/workbench/contrib/stats/test/workspaceStats.test.ts", @@ -313,7 +314,6 @@ "./vs/workbench/services/backup/common/backup.ts", "./vs/workbench/services/backup/node/backupFileService.ts", "./vs/workbench/services/broadcast/electron-browser/broadcastService.ts", - "./vs/workbench/services/bulkEdit/browser/bulkEditService.ts", "./vs/workbench/services/configuration/common/configuration.ts", "./vs/workbench/services/configuration/common/configurationModels.ts", "./vs/workbench/services/configuration/common/jsonEditing.ts", @@ -373,8 +373,6 @@ "./vs/workbench/services/part/common/partService.ts", "./vs/workbench/services/preferences/common/keybindingsEditorModel.ts", "./vs/workbench/services/preferences/test/common/keybindingsEditorModel.test.ts", - "./vs/workbench/services/progress/browser/progressService.ts", - "./vs/workbench/services/progress/test/progressService.test.ts", "./vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl.ts", "./vs/workbench/services/remote/node/remoteAgentEnvironmentChannel.ts", "./vs/workbench/services/remote/node/remoteAgentService.ts", @@ -409,7 +407,6 @@ "./vs/workbench/services/textfile/common/textFileEditorModelManager.ts", "./vs/workbench/services/textfile/common/textfiles.ts", "./vs/workbench/services/textfile/node/textResourcePropertiesService.ts", - "./vs/workbench/services/timer/electron-browser/timerService.ts", "./vs/workbench/services/title/common/titleService.ts", "./vs/workbench/services/viewlet/browser/viewlet.ts", "./vs/workbench/services/workspace/common/workspaceEditing.ts", diff --git a/src/vs/workbench/services/progress/browser/progressService2.ts b/src/vs/workbench/services/progress/browser/progressService2.ts index f61446ca4b9..d267ae05770 100644 --- a/src/vs/workbench/services/progress/browser/progressService2.ts +++ b/src/vs/workbench/services/progress/browser/progressService2.ts @@ -39,8 +39,7 @@ export class ProgressService2 implements IProgressService2 { if (viewlet) { return this._withViewletProgress(location, task); } - console.warn(`Bad progress location: ${location}`); - return undefined; + return Promise.reject(new Error(`Bad progress location: ${location}`)); } switch (location) { @@ -55,8 +54,7 @@ export class ProgressService2 implements IProgressService2 { case ProgressLocation.Extensions: return this._withViewletProgress('workbench.view.extensions', task); default: - console.warn(`Bad progress location: ${location}`); - return undefined; + return Promise.reject(new Error(`Bad progress location: ${location}`)); } } @@ -269,4 +267,4 @@ export class ProgressService2 implements IProgressService2 { } } -registerSingleton(IProgressService2, ProgressService2, true); \ No newline at end of file +registerSingleton(IProgressService2, ProgressService2, true); From 4e3dcb718bff1a64bc2377e045c1b12eec5cc640 Mon Sep 17 00:00:00 2001 From: "Ryan A. Pavlik" Date: Tue, 5 Mar 2019 02:47:09 -0600 Subject: [PATCH 168/290] Update preferences.contribution.ts (#69807) Fix typo in spelling of Preferences. --- .../electron-browser/preferences.contribution.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/electron-browser/preferences.contribution.ts b/src/vs/workbench/contrib/preferences/electron-browser/preferences.contribution.ts index 6d2d5ab3bc1..e9af73dc862 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/preferences.contribution.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/preferences.contribution.ts @@ -477,7 +477,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: OpenFolderSettingsAction.ID, title: { value: `${category}: ${OpenFolderSettingsAction.LABEL}`, original: 'Preferences: Open Folder Settings' }, - category: nls.localize('preferencesCategory', "Prefernces") + category: nls.localize('preferencesCategory', "Preferences") }, when: WorkbenchStateContext.isEqualTo('workspace') }); @@ -489,7 +489,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { command: { id: OpenWorkspaceSettingsAction.ID, title: { value: `${category}: ${OpenWorkspaceSettingsAction.LABEL}`, original: 'Preferences: Open Workspace Settings' }, - category: nls.localize('preferencesCategory', "Prefernces") + category: nls.localize('preferencesCategory', "Preferences") }, when: WorkbenchStateContext.notEqualsTo('empty') }); @@ -799,4 +799,4 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { title: OPEN_FOLDER_SETTINGS_LABEL }, when: ContextKeyExpr.and(ExplorerRootContext, ExplorerFolderContext) -}); \ No newline at end of file +}); From 10cd21c637ecbe267a2c5cfa53d1ea008790388a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 10:08:56 +0100 Subject: [PATCH 169/290] better error message for #68744 --- src/vs/code/electron-main/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index f89af11d2aa..d3d8f3fa86d 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -216,7 +216,7 @@ function handleStartupDataDirError(environmentService: IEnvironmentService, erro if (error.code === 'EACCES' || error.code === 'EPERM') { showStartupWarningDialog( localize('startupDataDirError', "Unable to write program user data."), - localize('startupDataDirErrorDetail', "Please make sure the directory {0} is writeable.", environmentService.userDataPath) + localize('startupDataDirErrorDetail', "Please make sure the directories {0} and {1} are writeable.", environmentService.userDataPath, environmentService.extensionsPath) ); } } From 1eb6de1daf76b118eb21296afcc4afd248e6fda1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 10:00:20 +0100 Subject: [PATCH 170/290] clean up some todos --- extensions/git/src/decorationProvider.ts | 1 - extensions/git/src/repository.ts | 2 +- src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts | 1 - src/vs/workbench/contrib/outline/browser/outlinePanel.ts | 3 +-- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts index 97a6a41997f..9f17b20ee8e 100644 --- a/extensions/git/src/decorationProvider.ts +++ b/extensions/git/src/decorationProvider.ts @@ -20,7 +20,6 @@ class GitIgnoreDecorationProvider implements DecorationProvider { private disposables: Disposable[] = []; constructor(private model: Model) { - //todo@joh -> events when the ignore status actually changes, not only when the file changes this.onDidChangeDecorations = fireEvent(anyEvent( filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore')), model.onDidOpenRepository, diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 388a1f28043..2fac9e2a39f 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -206,7 +206,7 @@ export class Resource implements SourceControlResourceState { case Status.INDEX_ADDED: case Status.INTENT_TO_ADD: return new ThemeColor('gitDecoration.addedResourceForeground'); - case Status.INDEX_RENAMED: // todo@joh - special color? + case Status.INDEX_RENAMED: case Status.UNTRACKED: return new ThemeColor('gitDecoration.untrackedResourceForeground'); case Status.IGNORED: diff --git a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts index 731a9309798..065e9e61a48 100644 --- a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts @@ -169,7 +169,6 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic return this._mainThreadEditors.$tryApplyWorkspaceEdit({ edits: [resourceEdit] }); } - // TODO@joh bubble this to listener? return Promise.reject(new Error('concurrent_edits')); }); } diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index d6d2c3f39fc..59dbfe4c344 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -335,8 +335,7 @@ export class OutlinePanel extends ViewletPanel { this._disposables.push(this._tree); this._disposables.push(this._outlineViewState.onDidChange(this._onDidChangeUserState, this)); - // todo@joh workaournd for the tree resetting the filter behaviour - // to something globally defined + // override the globally defined behaviour this._tree.updateOptions({ filterOnType: this._outlineViewState.filterOnType }); From de8f1b8025cb20bf03b936102aba1a7ed56163d1 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 10:15:51 +0100 Subject: [PATCH 171/290] reset editor selection when explicitly cancelling snippet mode, #68512 --- .../contrib/snippet/snippetController2.ts | 10 ++++- .../snippet/test/snippetController2.test.ts | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index febc52c54a6..42ff4261198 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -193,7 +193,7 @@ export class SnippetController2 implements IEditorContribution { } } - cancel(): void { + cancel(resetSelection: boolean = false): void { this._inSnippet.reset(); this._hasPrevTabstop.reset(); this._hasNextTabstop.reset(); @@ -201,6 +201,12 @@ export class SnippetController2 implements IEditorContribution { dispose(this._session); this._session = undefined; this._modelVersionId = -1; + if (resetSelection) { + // reset selection to the primary cursor when being asked + // for. this happens when explicitly cancelling snippet mode, + // e.g. when pressing ESC + this._editor.setSelections([this._editor.getSelection()]); + } } prev(): void { @@ -257,7 +263,7 @@ registerEditorCommand(new CommandCtor({ registerEditorCommand(new CommandCtor({ id: 'leaveSnippet', precondition: SnippetController2.InSnippetMode, - handler: ctrl => ctrl.cancel(), + handler: ctrl => ctrl.cancel(true), kbOpts: { weight: KeybindingWeight.EditorContrib + 30, kbExpr: EditorContextKeys.editorTextFocus, diff --git a/src/vs/editor/contrib/snippet/test/snippetController2.test.ts b/src/vs/editor/contrib/snippet/test/snippetController2.test.ts index 668fc0b74b9..95395786fd0 100644 --- a/src/vs/editor/contrib/snippet/test/snippetController2.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetController2.test.ts @@ -361,4 +361,44 @@ suite('SnippetController2', function () { assertSelections(editor, new Selection(1, 7, 1, 7)); assertContextKeys(contextKeys, false, false, false); }); + + test('Cancelling snippet mode should discard added cursors #68512 (soft cancel)', function () { + const ctrl = new SnippetController2(editor, logService, contextKeys); + model.setValue(''); + editor.setSelection(new Selection(1, 1, 1, 1)); + + ctrl.insert('.REGION ${2:FUNCTION_NAME}\nCREATE.FUNCTION ${1:VOID} ${2:FUNCTION_NAME}(${3:})\n\t${4:}\nEND\n.ENDREGION$0'); + assertSelections(editor, new Selection(2, 17, 2, 21)); + + ctrl.next(); + assertSelections(editor, new Selection(1, 9, 1, 22), new Selection(2, 22, 2, 35)); + assertContextKeys(contextKeys, true, true, true); + + editor.setSelections([new Selection(1, 22, 1, 22), new Selection(2, 35, 2, 35)]); + assertContextKeys(contextKeys, true, true, true); + + editor.setSelections([new Selection(2, 1, 2, 1), new Selection(2, 36, 2, 36)]); + assertContextKeys(contextKeys, false, false, false); + assertSelections(editor, new Selection(2, 1, 2, 1), new Selection(2, 36, 2, 36)); + }); + + test('Cancelling snippet mode should discard added cursors #68512 (hard cancel)', function () { + const ctrl = new SnippetController2(editor, logService, contextKeys); + model.setValue(''); + editor.setSelection(new Selection(1, 1, 1, 1)); + + ctrl.insert('.REGION ${2:FUNCTION_NAME}\nCREATE.FUNCTION ${1:VOID} ${2:FUNCTION_NAME}(${3:})\n\t${4:}\nEND\n.ENDREGION$0'); + assertSelections(editor, new Selection(2, 17, 2, 21)); + + ctrl.next(); + assertSelections(editor, new Selection(1, 9, 1, 22), new Selection(2, 22, 2, 35)); + assertContextKeys(contextKeys, true, true, true); + + editor.setSelections([new Selection(1, 22, 1, 22), new Selection(2, 35, 2, 35)]); + assertContextKeys(contextKeys, true, true, true); + + ctrl.cancel(true); + assertContextKeys(contextKeys, false, false, false); + assertSelections(editor, new Selection(1, 22, 1, 22)); + }); }); From 3d3450cc95c5bfbee5e07366ca70969df5d665e8 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Mar 2019 10:26:36 +0100 Subject: [PATCH 172/290] Fix #68546 --- .../node/configurationService.ts | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 1e90cfd6285..b71054c6318 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -9,7 +9,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ResourceMap } from 'vs/base/common/map'; import { equals, deepClone } from 'vs/base/common/objects'; import { Disposable } from 'vs/base/common/lifecycle'; -import { Queue } from 'vs/base/common/async'; +import { Queue, Barrier } from 'vs/base/common/async'; import { 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'; @@ -35,14 +35,14 @@ import { IJSONSchema, IJSONSchemaMap } from 'vs/base/common/jsonSchema'; import { localize } from 'vs/nls'; import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; +import { Schemas } from 'vs/base/common/network'; export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService { public _serviceBrand: any; private workspace: Workspace; - private resolvePromise: Promise; - private resolveCallback: () => void; + private completeWorkspaceBarrier: Barrier; private _configuration: Configuration; private defaultConfiguration: DefaultConfigurationModel; private userConfiguration: UserConfiguration; @@ -70,7 +70,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat constructor(private environmentService: IEnvironmentService, private workspaceSettingsRootFolder: string = FOLDER_CONFIG_FOLDER_NAME) { super(); - this.resolvePromise = new Promise(c => this.resolveCallback = c); + this.completeWorkspaceBarrier = new Barrier(); this.defaultConfiguration = new DefaultConfigurationModel(); this.userConfiguration = this._register(new UserConfiguration(environmentService.appSettingsPath)); this.workspaceConfiguration = this._register(new WorkspaceConfiguration(environmentService)); @@ -86,7 +86,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat // Workspace Context Service Impl public getCompleteWorkspace(): Promise { - return this.resolvePromise.then(() => this.getWorkspace()); + return this.completeWorkspaceBarrier.wait().then(() => this.getWorkspace()); } public getWorkspace(): Workspace { @@ -304,7 +304,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat for (const workspaceFolder of changedWorkspaceFolders) { this.onWorkspaceFolderConfigurationChanged(workspaceFolder); } - this.resolveCallback(); + this.releaseWorkspaceBarrier(); }); } @@ -331,7 +331,11 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat const workspaceConfigPath = workspaceIdentifier.configPath; const workspaceFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), dirname(workspaceConfigPath)); const workspaceId = workspaceIdentifier.id; - return new Workspace(workspaceId, workspaceFolders, workspaceConfigPath); + const workspace = new Workspace(workspaceId, workspaceFolders, workspaceConfigPath); + if (workspace.configuration.scheme === Schemas.file) { + this.releaseWorkspaceBarrier(); // Release barrier as workspace is complete because it is from disk. + } + return workspace; }); } @@ -345,11 +349,21 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat configuredFolders = [{ uri: folder.toString() }]; } - return Promise.resolve(new Workspace(singleFolder.id, toWorkspaceFolders(configuredFolders))); + const workspace = new Workspace(singleFolder.id, toWorkspaceFolders(configuredFolders)); + this.releaseWorkspaceBarrier(); // Release barrier as workspace is complete because it is single folder. + return Promise.resolve(workspace); } private createEmptyWorkspace(emptyWorkspace: IEmptyWorkspaceInitializationPayload): Promise { - return Promise.resolve(new Workspace(emptyWorkspace.id)); + const workspace = new Workspace(emptyWorkspace.id); + this.releaseWorkspaceBarrier(); // Release barrier as workspace is complete because it is an empty workspace. + return Promise.resolve(workspace); + } + + private releaseWorkspaceBarrier(): void { + if (!this.completeWorkspaceBarrier.isOpen()) { + this.completeWorkspaceBarrier.open(); + } } private updateWorkspaceAndInitializeConfiguration(workspace: Workspace, postInitialisationTask: () => void): Promise { From e5d9409ab7b6cfe345af20435db423415f956bba Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 10:26:49 +0100 Subject: [PATCH 173/290] undo aria change --- src/vs/base/browser/ui/aria/aria.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/vs/base/browser/ui/aria/aria.ts b/src/vs/base/browser/ui/aria/aria.ts index d7dad9cba5c..1922450144d 100644 --- a/src/vs/base/browser/ui/aria/aria.ts +++ b/src/vs/base/browser/ui/aria/aria.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./aria'; +import * as nls from 'vs/nls'; import { isMacintosh } from 'vs/base/common/platform'; import * as dom from 'vs/base/browser/dom'; @@ -47,12 +48,29 @@ 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++; + } + else { + prevText = msg; + repeatedTimes = 0; + } + + + 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); target.textContent = msg; From 809297c9cf762dabf296f66775a3d95238c3c15c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 10:31:31 +0100 Subject: [PATCH 174/290] only alert when inserting a suggestion make additional editor, like inserting an import statement, simplify the message that read when selecting an item --- .../editor/contrib/suggest/suggestController.ts | 7 +++++-- src/vs/editor/contrib/suggest/suggestWidget.ts | 16 +++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/contrib/suggest/suggestController.ts b/src/vs/editor/contrib/suggest/suggestController.ts index 20f37c560e0..c471b0fe568 100644 --- a/src/vs/editor/contrib/suggest/suggestController.ts +++ b/src/vs/editor/contrib/suggest/suggestController.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { alert } from 'vs/base/browser/ui/aria/aria'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { onUnexpectedError } from 'vs/base/common/errors'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; @@ -291,8 +292,10 @@ export class SuggestController implements IEditorContribution { } private _alertCompletionItem({ completion: suggestion }: CompletionItem): void { - // A temporary fix for too verbose, unnecesary screen reader alerts. - // Todo: Remove calls to this empty method body. + if (isNonEmptyArray(suggestion.additionalTextEdits)) { + let msg = nls.localize('arai.alert.snippet', "Accepting '{0}' made {1} additional edits", suggestion.label, suggestion.additionalTextEdits.length); + alert(msg); + } } triggerSuggest(onlyFrom?: CompletionItemProvider[]): void { diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index 8de80617e8d..13e51c949d9 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -540,20 +540,10 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate Date: Tue, 5 Mar 2019 10:33:26 +0100 Subject: [PATCH 175/290] debt - IActiveTextEditorModel => IResolvedTextEditorModel --- src/vs/editor/common/services/resolverService.ts | 8 ++++++-- src/vs/editor/standalone/browser/simpleServices.ts | 6 +++--- src/vs/workbench/common/editor/textEditorModel.ts | 4 ++-- .../services/bulkEdit/browser/bulkEditService.ts | 6 +++--- .../services/configuration/node/jsonEditingService.ts | 10 +++++----- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/common/services/resolverService.ts b/src/vs/editor/common/services/resolverService.ts index 2b04d4b1218..ef65b34685e 100644 --- a/src/vs/editor/common/services/resolverService.ts +++ b/src/vs/editor/common/services/resolverService.ts @@ -18,7 +18,7 @@ export interface ITextModelService { * Provided a resource URI, it will return a model reference * which should be disposed once not needed anymore. */ - createModelReference(resource: URI): Promise>; + createModelReference(resource: URI): Promise>; /** * Registers a specific `scheme` content provider. @@ -49,6 +49,10 @@ export interface ITextEditorModel extends IEditorModel { isReadonly(): boolean; } -export interface IActiveTextEditorModel extends ITextEditorModel { +export interface IResolvedTextEditorModel extends ITextEditorModel { + + /** + * Same as ITextEditorModel#textEditorModel, but never null. + */ readonly textEditorModel: ITextModel; } diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 7c6487339f2..c76b38b22df 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -22,7 +22,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEdit, WorkspaceEdit, isResourceTextEdit } from 'vs/editor/common/modes'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { IActiveTextEditorModel, ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService'; +import { IResolvedTextEditorModel, ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService'; import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; import { CommandsRegistry, ICommand, ICommandEvent, ICommandHandler, ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationChangeEvent, IConfigurationData, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -44,7 +44,7 @@ import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFolde import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; -export class SimpleModel implements IActiveTextEditorModel { +export class SimpleModel implements IResolvedTextEditorModel { private model: ITextModel; private readonly _onDispose: Emitter; @@ -98,7 +98,7 @@ export class SimpleEditorModelResolverService implements ITextModelService { this.editor = editor; } - public createModelReference(resource: URI): Promise> { + public createModelReference(resource: URI): Promise> { let model: ITextModel | null = withTypedEditor(this.editor, (editor) => this.findModel(editor, resource), (diffEditor) => this.findModel(diffEditor.getOriginalEditor(), resource) || this.findModel(diffEditor.getModifiedEditor(), resource) diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index b8279be7d5c..4ba0027e985 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -6,7 +6,7 @@ import { ITextModel, ITextBufferFactory } from 'vs/editor/common/model'; import { EditorModel } from 'vs/workbench/common/editor'; import { URI } from 'vs/base/common/uri'; -import { ITextEditorModel, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService'; import { IModelService } from 'vs/editor/common/services/modelService'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -135,7 +135,7 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd return null; } - isResolved(): this is IActiveTextEditorModel { + isResolved(): this is IResolvedTextEditorModel { return !!this.textEditorModelHandle; } diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index 93494c3bbc7..5137f89c2c5 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -13,7 +13,7 @@ import { Range } from 'vs/editor/common/core/range'; import { EndOfLineSequence, IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; import { isResourceFileEdit, isResourceTextEdit, ResourceFileEdit, ResourceTextEdit, WorkspaceEdit } from 'vs/editor/common/modes'; import { IModelService } from 'vs/editor/common/services/modelService'; -import { ITextModelService, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { localize } from 'vs/nls'; import { IFileService } from 'vs/platform/files/common/files'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -53,7 +53,7 @@ class ModelEditTask implements IDisposable { private _expectedModelVersionId: number | undefined; protected _newEol: EndOfLineSequence; - constructor(private readonly _modelReference: IReference) { + constructor(private readonly _modelReference: IReference) { this._model = this._modelReference.object.textEditorModel; this._edits = []; } @@ -115,7 +115,7 @@ class EditorEditTask extends ModelEditTask { private _editor: ICodeEditor; - constructor(modelReference: IReference, editor: ICodeEditor) { + constructor(modelReference: IReference, editor: ICodeEditor) { super(modelReference); this._editor = editor; } diff --git a/src/vs/workbench/services/configuration/node/jsonEditingService.ts b/src/vs/workbench/services/configuration/node/jsonEditingService.ts index e8f1ab3be9b..5c08f612786 100644 --- a/src/vs/workbench/services/configuration/node/jsonEditingService.ts +++ b/src/vs/workbench/services/configuration/node/jsonEditingService.ts @@ -17,7 +17,7 @@ import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IFileService } from 'vs/platform/files/common/files'; -import { ITextModelService, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IJSONEditingService, IJSONValue, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing'; import { ITextModel } from 'vs/editor/common/model'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -84,7 +84,7 @@ export class JSONEditingService implements IJSONEditingService { return setProperty(model.getValue(), [key], value, { tabSize, insertSpaces, eol }); } - private async resolveModelReference(resource: URI): Promise> { + private async resolveModelReference(resource: URI): Promise> { const exists = await this.fileService.existsFile(resource); if (!exists) { await this.fileService.updateContent(resource, '{}', { encoding: encoding.UTF8 }); @@ -98,18 +98,18 @@ export class JSONEditingService implements IJSONEditingService { return parseErrors.length > 0; } - private resolveAndValidate(resource: URI, checkDirty: boolean): Promise> { + private resolveAndValidate(resource: URI, checkDirty: boolean): Promise> { return this.resolveModelReference(resource) .then(reference => { const model = reference.object.textEditorModel; if (this.hasParseErrors(model)) { - return this.reject>(JSONEditingErrorCode.ERROR_INVALID_FILE); + return this.reject>(JSONEditingErrorCode.ERROR_INVALID_FILE); } // Target cannot be dirty if not writing into buffer if (checkDirty && this.textFileService.isDirty(resource)) { - return this.reject>(JSONEditingErrorCode.ERROR_FILE_DIRTY); + return this.reject>(JSONEditingErrorCode.ERROR_FILE_DIRTY); } return reference; }); From e1dac9dee155604f2dc76ab20e53767691eca95e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 10:36:05 +0100 Subject: [PATCH 176/290] files - do not focus explorer when revealing folder (for #69333) --- .../workbench/contrib/files/browser/editors/textFileEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts index 5e1a9623ea0..c5c6bcb72ca 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts @@ -234,7 +234,7 @@ export class TextFileEditor extends BaseTextEditor { // Best we can do is to reveal the folder in the explorer if (this.contextService.isInsideWorkspace(input.getResource())) { - this.viewletService.openViewlet(VIEWLET_ID, true).then(() => { + this.viewletService.openViewlet(VIEWLET_ID).then(() => { this.explorerService.select(input.getResource(), true); }); } From 0bb3bfc4b4ffe6d94cc67fbd712b706d4250f3ff Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 10:38:07 +0100 Subject: [PATCH 177/290] strict null trouble --- src/vs/editor/contrib/snippet/snippetController2.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index 42ff4261198..3f87729b6ab 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -205,7 +205,7 @@ export class SnippetController2 implements IEditorContribution { // reset selection to the primary cursor when being asked // for. this happens when explicitly cancelling snippet mode, // e.g. when pressing ESC - this._editor.setSelections([this._editor.getSelection()]); + this._editor.setSelections([this._editor.getSelection()!]); } } From 4f197a7079bf2ce1346db1739f8b89cd700d079f Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 5 Mar 2019 10:41:16 +0100 Subject: [PATCH 178/290] :lipstick: --- extensions/git/src/commands.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 165895701b6..8e798b0cc77 100755 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -649,17 +649,16 @@ export class CommandCenter { if (!(resource instanceof Resource)) { // can happen when called from a keybinding + console.log('WHAT'); resource = this.getSCMResource(); } if (resource) { - const resources = ([resource, ...resourceStates] as Resource[]) - .filter(r => r.type !== Status.DELETED && r.type !== Status.INDEX_DELETED); - - uris = resources.map(r => r.resourceUri); - } - else { - uris = [(window.activeTextEditor && window.activeTextEditor.document.uri)] as Uri[]; + uris = ([resource, ...resourceStates] as Resource[]) + .filter(r => r.type !== Status.DELETED && r.type !== Status.INDEX_DELETED) + .map(r => r.resourceUri); + } else if (window.activeTextEditor) { + uris = [window.activeTextEditor.document.uri]; } } @@ -668,6 +667,7 @@ export class CommandCenter { } const activeTextEditor = window.activeTextEditor; + for (const uri of uris) { const opts: TextDocumentShowOptions = { preserveFocus, @@ -2120,6 +2120,7 @@ export class CommandCenter { uri = uri ? uri : (window.activeTextEditor && window.activeTextEditor.document.uri); this.outputChannel.appendLine(`git.getSCMResource.uri ${uri && uri.toString()}`); + for (const r of this.model.repositories.map(r => r.root)) { this.outputChannel.appendLine(`repo root ${r}`); } From 8f0c07ac9ea547821461a1f6e90044beffe1a030 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 5 Mar 2019 10:44:22 +0100 Subject: [PATCH 179/290] Get rid of editable map, it should not be a map but just one element fixes #69531 --- .../contrib/files/browser/media/explorerviewlet.css | 4 ++-- .../contrib/files/browser/views/explorerView.ts | 4 ++-- .../workbench/contrib/files/common/explorerService.ts | 11 +++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css b/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css index a0c0f8de7f4..17b272cef79 100644 --- a/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css +++ b/src/vs/workbench/contrib/files/browser/media/explorerviewlet.css @@ -18,8 +18,8 @@ padding-left: 4px; /* align top level twistie with `Explorer` title label */ } -.explorer-viewlet .monaco-list.highlight .explorer-item:not(.explorer-item-edited), -.explorer-viewlet .monaco-list.highlight .monaco-tl-twistie { +.explorer-viewlet .explorer-folders-view.highlight .monaco-list .explorer-item:not(.explorer-item-edited), +.explorer-viewlet .explorer-folders-view.highlight .monaco-list .monaco-tl-twistie { opacity: 0.3; } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 69a8b7bb575..94c206c6ebf 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -176,13 +176,13 @@ export class ExplorerView extends ViewletPanel { if (isEditing) { await this.tree.expand(e.parent); } else { - DOM.removeClass(this.tree.getHTMLElement(), 'highlight'); + DOM.removeClass(treeContainer, 'highlight'); } await this.refresh(e.parent); if (isEditing) { - DOM.addClass(this.tree.getHTMLElement(), 'highlight'); + DOM.addClass(treeContainer, 'highlight'); this.tree.reveal(e); } else { this.tree.domFocus(); diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 980c9b14035..7ce193360b2 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -37,7 +37,7 @@ export class ExplorerService implements IExplorerService { private _onDidSelectItem = new Emitter<{ item?: ExplorerItem, reveal?: boolean }>(); private _onDidCopyItems = new Emitter<{ items: ExplorerItem[], cut: boolean, previouslyCutItems: ExplorerItem[] | undefined }>(); private disposables: IDisposable[] = []; - private editableStats = new Map(); + private editable: { stat: ExplorerItem, data: IEditableData } | undefined; private _sortOrder: SortOrder; private cutItems: ExplorerItem[] | undefined; @@ -112,11 +112,10 @@ export class ExplorerService implements IExplorerService { setEditable(stat: ExplorerItem, data: IEditableData | null): void { if (!data) { - this.editableStats.delete(stat); + this.editable = undefined; } else { - this.editableStats.set(stat, data); + this.editable = { stat, data }; } - this._onDidChangeEditable.fire(stat); } @@ -133,11 +132,11 @@ export class ExplorerService implements IExplorerService { } getEditableData(stat: ExplorerItem): IEditableData | undefined { - return this.editableStats.get(stat); + return this.editable && this.editable.stat === stat ? this.editable.data : undefined; } isEditable(stat: ExplorerItem): boolean { - return this.editableStats.has(stat); + return !!this.editable && this.editable.stat === stat; } select(resource: URI, reveal?: boolean): Promise { From 2b98f571453104e33306cb8637da8faf99d1a678 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 11:01:59 +0100 Subject: [PATCH 180/290] fix #67300 --- .../electron-browser/partsSplash.contribution.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts index b8f8fbbf0a5..79dcaaae6d3 100644 --- a/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts +++ b/src/vs/workbench/contrib/splash/electron-browser/partsSplash.contribution.ts @@ -22,6 +22,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IFileService } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; class PartsSplash { @@ -29,6 +30,7 @@ class PartsSplash { private readonly _disposables: IDisposable[] = []; + private _didChangeTitleBarStyle: boolean; private _lastBaseTheme: string; private _lastBackground?: string; @@ -39,13 +41,18 @@ class PartsSplash { @IEnvironmentService private readonly _envService: IEnvironmentService, @IBroadcastService private readonly _broadcastService: IBroadcastService, @ILifecycleService lifecycleService: ILifecycleService, - @IEditorGroupsService editorGroupsService: IEditorGroupsService + @IEditorGroupsService editorGroupsService: IEditorGroupsService, + @IConfigurationService configService: IConfigurationService, ) { lifecycleService.when(LifecyclePhase.Restored).then(_ => this._removePartsSplash()); Event.debounce(Event.any( onDidChangeFullscreen, editorGroupsService.onDidLayout ), () => { }, 800)(this._savePartsSplash, this, this._disposables); + + configService.onDidChangeConfiguration(e => { + this._didChangeTitleBarStyle = e.affectsConfiguration('window.titleBarStyle'); + }, this, this._disposables); } dispose(): void { @@ -100,7 +107,7 @@ class PartsSplash { } private _shouldSaveLayoutInfo(): boolean { - return !isFullscreen() && !this._envService.isExtensionDevelopment; + return !isFullscreen() && !this._envService.isExtensionDevelopment && !this._didChangeTitleBarStyle; } private _removePartsSplash(): void { From fe2571f087a0f0039a2c767e5e81daf8e1eb0261 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Mar 2019 10:43:03 +0100 Subject: [PATCH 181/290] #68546 Tests --- .../configurationService.test.ts | 64 ++++++++++++++++--- 1 file changed, 56 insertions(+), 8 deletions(-) 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 6d45e9d1c3d..5e78dc69c52 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 @@ -140,10 +140,66 @@ suite('WorkspaceContextService - Folder', () => { test('isCurrentWorkspace() => false', () => { assert.ok(!workspaceContextService.isCurrentWorkspace(URI.file(workspaceResource + 'abc'))); }); + + test('workspace is complete', () => workspaceContextService.getCompleteWorkspace()); }); suite('WorkspaceContextService - Workspace', () => { + let parentResource: string, testObject: WorkspaceService, instantiationService: TestInstantiationService; + + setup(() => { + return setUpWorkspace(['a', 'b']) + .then(({ parentDir, configPath }) => { + + parentResource = parentDir; + + const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); + const workspaceService = new WorkspaceService(environmentService); + + instantiationService = workbenchInstantiationService(); + instantiationService.stub(IWorkspaceContextService, workspaceService); + instantiationService.stub(IConfigurationService, workspaceService); + instantiationService.stub(IEnvironmentService, environmentService); + + return workspaceService.initialize(getWorkspaceIdentifier(configPath)).then(() => { + workspaceService.acquireInstantiationService(instantiationService); + testObject = workspaceService; + }); + }); + }); + + teardown(() => { + if (testObject) { + (testObject).dispose(); + } + if (parentResource) { + return pfs.del(parentResource, os.tmpdir()); + } + return undefined; + }); + + test('workspace folders', () => { + const actual = testObject.getWorkspace().folders; + + assert.equal(actual.length, 2); + assert.equal(path.basename(actual[0].uri.fsPath), 'a'); + assert.equal(path.basename(actual[1].uri.fsPath), 'b'); + }); + + test('getWorkbenchState()', () => { + const actual = testObject.getWorkbenchState(); + + assert.equal(actual, WorkbenchState.WORKSPACE); + }); + + + test('workspace is complete', () => testObject.getCompleteWorkspace()); + +}); + +suite('WorkspaceContextService - Workspace Editing', () => { + let parentResource: string, testObject: WorkspaceService, instantiationService: TestInstantiationService, fileChangeEvent: Emitter = new Emitter(); setup(() => { @@ -186,14 +242,6 @@ suite('WorkspaceContextService - Workspace', () => { return undefined; }); - test('workspace folders', () => { - const actual = testObject.getWorkspace().folders; - - assert.equal(actual.length, 2); - assert.equal(path.basename(actual[0].uri.fsPath), 'a'); - assert.equal(path.basename(actual[1].uri.fsPath), 'b'); - }); - test('add folders', () => { const workspaceDir = path.dirname(testObject.getWorkspace().folders[0].uri.fsPath); return testObject.addFolders([{ uri: URI.file(path.join(workspaceDir, 'd')) }, { uri: URI.file(path.join(workspaceDir, 'c')) }]) From 94f7ae74c556f4c5407bf9bc462e6c4721641245 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 5 Mar 2019 10:47:19 +0100 Subject: [PATCH 182/290] fixes #69529 --- extensions/git/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/git/package.json b/extensions/git/package.json index 834563c3102..f858863dd7b 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -1150,6 +1150,7 @@ "%config.postCommitCommand.sync%" ], "markdownDescription": "%config.postCommitCommand%", + "scope": "resource", "default": "none" }, "git.showInlineOpenFileAction": { From 20a4f36e2517d9b56075d649beed84716ec88088 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 5 Mar 2019 11:15:42 +0100 Subject: [PATCH 183/290] add workbench/contrib/scm to strict null checks fixes #69688 --- src/tsconfig.strictNullChecks.json | 3 +- src/vs/base/browser/ui/list/list.ts | 2 +- src/vs/base/browser/ui/list/listWidget.ts | 13 ++------ .../common/editor/untitledEditorInput.ts | 14 +++----- .../common/editor/untitledEditorModel.ts | 15 ++++++--- .../scm/electron-browser/scmViewlet.ts | 32 +++++++++---------- 6 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index bd09c3b049a..d8bae789a91 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -15,6 +15,7 @@ "./vs/workbench/electron-browser/actions/**/*", "./vs/workbench/contrib/emmet/**/*", "./vs/workbench/contrib/externalTerminal/**/*", + "./vs/workbench/contrib/scm/**/*.ts", "./vs/workbench/contrib/snippets/**/*.ts", "./vs/workbench/contrib/outline/**/*.ts", "./vs/workbench/contrib/performance/**/*.ts", @@ -430,4 +431,4 @@ "./typings/require-monaco.d.ts", "./vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts" ] -} +} \ No newline at end of file diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts index 80dea11ee4a..42097113808 100644 --- a/src/vs/base/browser/ui/list/list.ts +++ b/src/vs/base/browser/ui/list/list.ts @@ -55,7 +55,7 @@ export interface IListContextMenuEvent { browserEvent: UIEvent; element: T | undefined; index: number | undefined; - anchor: HTMLElement | { x: number; y: number; } | undefined; + anchor: HTMLElement | { x: number; y: number; }; } export interface IIdentityProvider { diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index cd7312809c6..197fcb2ab98 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -1127,13 +1127,7 @@ export class List implements ISpliceable, IDisposable { .map(e => new StandardKeyboardEvent(e)) .filter(e => this.didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10)) .filter(e => { e.preventDefault(); e.stopPropagation(); return false; }) - .map(event => { - const index = this.getFocus()[0]; - const element = this.view.element(index); - const anchor = this.view.domElement(index) || undefined; - return { index, element, anchor, browserEvent: event.browserEvent }; - }) - .event; + .event as Event; const fromKeyup = Event.chain(domEvent(this.view.domNode, 'keyup')) .filter(() => { @@ -1141,14 +1135,13 @@ export class List implements ISpliceable, IDisposable { this.didJustPressContextMenuKey = false; return didJustPressContextMenuKey; }) - .filter(() => this.getFocus().length > 0) + .filter(() => this.getFocus().length > 0 && !!this.view.domElement(this.getFocus()[0])) .map(browserEvent => { const index = this.getFocus()[0]; const element = this.view.element(index); - const anchor = this.view.domElement(index) || undefined; + const anchor = this.view.domElement(index) as HTMLElement; return { index, element, anchor, browserEvent }; }) - .filter(({ anchor }) => !!anchor) .event; const fromMouse = Event.chain(this.view.onContextMenu) diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index e1800711ea6..a4fe328d79d 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -121,25 +121,21 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport return this.labelService.getUriLabel(this.resource); } - getTitle(verbosity: Verbosity): string { + getTitle(verbosity: Verbosity): string | null { if (!this.hasAssociatedFilePath) { return this.getName(); } - let title: string | undefined; switch (verbosity) { case Verbosity.SHORT: - title = this.shortTitle; - break; + return this.shortTitle; case Verbosity.MEDIUM: - title = this.mediumTitle; - break; + return this.mediumTitle; case Verbosity.LONG: - title = this.longTitle; - break; + return this.longTitle; } - return title; + return null; } isDirty(): boolean { diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index 70cfc8c48e0..4d14923cc3f 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -95,7 +95,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin return this.textEditorModel.getLanguageIdentifier().language; } - return null; + return this.modeId; } getEncoding(): string { @@ -144,7 +144,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin return this.backupFileService.resolveBackupContent(backupResource); } - return null; + return undefined; }).then(backupTextBufferFactory => { const hasBackup = !!backupTextBufferFactory; @@ -171,17 +171,24 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin // Encoding this.configuredEncoding = this.configurationService.getValue(this.resource, 'files.encoding'); + // We know for a fact there is a text editor model here + const textEditorModel = this.textEditorModel!; + // Listen to content changes - this._register(this.textEditorModel.onDidChangeContent(() => this.onModelContentChanged())); + this._register(textEditorModel.onDidChangeContent(() => this.onModelContentChanged())); // Listen to mode changes - this._register(this.textEditorModel.onDidChangeLanguage(() => this.onConfigurationChange())); // mode change can have impact on config + this._register(textEditorModel.onDidChangeLanguage(() => this.onConfigurationChange())); // mode change can have impact on config return this; }); } private onModelContentChanged(): void { + if (!this.isResolved()) { + return; + } + this.versionId++; // mark the untitled editor as non-dirty once its content becomes empty and we do diff --git a/src/vs/workbench/contrib/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/electron-browser/scmViewlet.ts index 077334bb5ca..39eeddba79a 100644 --- a/src/vs/workbench/contrib/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/electron-browser/scmViewlet.ts @@ -84,11 +84,11 @@ class StatusBarAction extends Action { private commandService: ICommandService ) { super(`statusbaraction{${command.id}}`, command.title, '', true); - this.tooltip = command.tooltip; + this.tooltip = command.tooltip || ''; } run(): Promise { - return this.commandService.executeCommand(this.command.id, ...this.command.arguments); + return this.commandService.executeCommand(this.command.id, ...(this.command.arguments || [])); } } @@ -198,7 +198,7 @@ class ProviderRenderer implements IListRenderer if (icon) { template.decorationIcon.style.display = ''; template.decorationIcon.style.backgroundImage = `url('${icon}')`; - template.decorationIcon.title = resource.decorations.tooltip; + template.decorationIcon.title = resource.decorations.tooltip || ''; } else { template.decorationIcon.style.display = 'none'; template.decorationIcon.style.backgroundImage = ''; } - template.element.setAttribute('data-tooltip', resource.decorations.tooltip); + template.element.setAttribute('data-tooltip', resource.decorations.tooltip || ''); template.elementDisposable = combinedDisposable(disposables); } @@ -821,7 +821,7 @@ export class RepositoryPanel extends ViewletPanel { const validationDelayer = new ThrottledDelayer(200); const validate = () => { - return this.repository.input.validateInput(this.inputBox.value, this.inputBox.inputElement.selectionStart).then(result => { + return this.repository.input.validateInput(this.inputBox.value, this.inputBox.inputElement.selectionStart || 0).then(result => { if (!result) { this.inputBox.inputElement.removeAttribute('aria-invalid'); this.inputBox.hideMessage(); @@ -916,7 +916,7 @@ export class RepositoryPanel extends ViewletPanel { } } - layoutBody(height: number = this.cachedHeight, width: number = this.cachedWidth): void { + layoutBody(height: number | undefined = this.cachedHeight, width: number | undefined = this.cachedWidth): void { if (height === undefined) { return; } @@ -962,9 +962,9 @@ export class RepositoryPanel extends ViewletPanel { return this.menus.getTitleSecondaryActions(); } - getActionItem(action: IAction): IActionItem { + getActionItem(action: IAction): IActionItem | null { if (!(action instanceof MenuItemAction)) { - return undefined; + return null; } return new ContextAwareMenuItemActionItem(action, this.keybindingService, this.notificationService, this.contextMenuService); @@ -1176,9 +1176,9 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle this.onSelectionChange(this.mainPanel.getSelection()); this.mainPanelDisposable = toDisposable(() => { - this.removePanels([this.mainPanel]); + this.removePanels([this.mainPanel!]); selectionChangeDisposable.dispose(); - this.mainPanel.dispose(); + this.mainPanel!.dispose(); }); } else { this.mainPanelDisposable.dispose(); @@ -1203,7 +1203,7 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle super.setVisible(visible); if (!visible) { - this.cachedMainPanelHeight = this.getPanelSize(this.mainPanel); + this.cachedMainPanelHeight = this.mainPanel ? this.getPanelSize(this.mainPanel) : 0; } const start = this.getContributedViewsStartIndex(); @@ -1247,9 +1247,9 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle } } - getActionItem(action: IAction): IActionItem { + getActionItem(action: IAction): IActionItem | null { if (!(action instanceof MenuItemAction)) { - return undefined; + return null; } return new ContextAwareMenuItemActionItem(action, this.keybindingService, this.notificationService, this.contextMenuService); @@ -1318,14 +1318,14 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle this.removePanels(panelsToRemove); // Restore main panel height - if (this.isVisible() && typeof this.cachedMainPanelHeight === 'number') { + if (this.mainPanel && this.isVisible() && typeof this.cachedMainPanelHeight === 'number') { this.resizePanel(this.mainPanel, this.cachedMainPanelHeight); this.cachedMainPanelHeight = undefined; } // Resize all panels equally const height = typeof this.height === 'number' ? this.height : 1000; - const mainPanelHeight = this.getPanelSize(this.mainPanel); + const mainPanelHeight = this.mainPanel ? this.getPanelSize(this.mainPanel) : 0; const size = (height - mainPanelHeight - contributableViewsHeight) / repositories.length; for (const panel of this.repositoryPanels) { this.resizePanel(panel, size); From c145eedcea2ecb213992280b5c760bad50a324c9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 11:27:01 +0100 Subject: [PATCH 184/290] cancel requests when outline provider change, also retrigger request #69147 --- .../contrib/documentSymbols/outlineModel.ts | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineModel.ts b/src/vs/editor/contrib/documentSymbols/outlineModel.ts index 179b23f3a11..759ea82e044 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineModel.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineModel.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { binarySearch, coalesceInPlace } from 'vs/base/common/arrays'; +import { binarySearch, coalesceInPlace, equals } 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'; @@ -266,13 +266,17 @@ export class OutlineModel extends TreeElement { static _create(textModel: ITextModel, token: CancellationToken): Promise { - let result = new OutlineModel(textModel); - let promises = DocumentSymbolProviderRegistry.ordered(textModel).map((provider, index) => { + const chainedCancellation = new CancellationTokenSource(); + token.onCancellationRequested(() => chainedCancellation.cancel()); + + const result = new OutlineModel(textModel); + const provider = DocumentSymbolProviderRegistry.ordered(textModel); + const promises = provider.map((provider, index) => { let id = TreeElement.findId(`provider_${index}`, result); let group = new OutlineGroup(id, result, provider, index); - return Promise.resolve(provider.provideDocumentSymbols(result.textModel, token)).then(result => { + return Promise.resolve(provider.provideDocumentSymbols(result.textModel, chainedCancellation.token)).then(result => { for (const info of result || []) { OutlineModel._makeOutlineElement(info, group); } @@ -289,7 +293,22 @@ export class OutlineModel extends TreeElement { }); }); - return Promise.all(promises).then(() => result._compact()); + const listener = DocumentSymbolProviderRegistry.onDidChange(() => { + const newProvider = DocumentSymbolProviderRegistry.ordered(textModel); + if (!equals(newProvider, provider)) { + chainedCancellation.cancel(); + } + }); + + return Promise.all(promises).then(() => { + if (chainedCancellation.token.isCancellationRequested && !token.isCancellationRequested) { + return OutlineModel._create(textModel, token); + } else { + return result._compact(); + } + }).finally(() => { + listener.dispose(); + }); } private static _makeOutlineElement(info: DocumentSymbol, container: OutlineGroup | OutlineElement): void { From a3ce5141e38a9d0ceb5c11eff9de65be7bc5bc06 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 5 Mar 2019 11:45:52 +0100 Subject: [PATCH 185/290] remove base64 transformation in electron IPC fixes #69338 --- .../electron-browser/ipc.electron-browser.ts | 2 +- .../ipc/electron-main/ipc.electron-main.ts | 8 +++---- src/vs/base/parts/ipc/node/ipc.electron.ts | 22 ++++--------------- 3 files changed, 9 insertions(+), 23 deletions(-) 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 225370373a7..055d6a54130 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 @@ -14,7 +14,7 @@ export class Client extends IPCClient implements IDisposable { private protocol: Protocol; private static createProtocol(): Protocol { - const onMessage = Event.fromNodeEventEmitter(ipcRenderer, 'ipc:message', (_, message: string) => message); + const onMessage = Event.fromNodeEventEmitter(ipcRenderer, 'ipc:message', (_, message: Buffer) => 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 17ae7bb81b6..f7d72041911 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 @@ -11,11 +11,11 @@ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; interface IIPCEvent { event: { sender: Electron.WebContents; }; - message: string; + message: Buffer | null; } -function createScopedOnMessageEvent(senderId: number, eventName: string): Event { - const onMessage = Event.fromNodeEventEmitter(ipcMain, eventName, (event, message: string) => ({ event, message })); +function createScopedOnMessageEvent(senderId: number, eventName: string): Event { + const onMessage = Event.fromNodeEventEmitter(ipcMain, eventName, (event, message) => ({ event, message })); const onMessageFromSender = Event.filter(onMessage, ({ event }) => event.sender.id === senderId); return Event.map(onMessageFromSender, ({ message }) => message); } @@ -38,7 +38,7 @@ export class Server extends IPCServer { const onDidClientReconnect = new Emitter(); Server.Clients.set(id, toDisposable(() => onDidClientReconnect.fire())); - const onMessage = createScopedOnMessageEvent(id, 'ipc:message'); + const onMessage = createScopedOnMessageEvent(id, 'ipc:message') as Event; const onDidClientDisconnect = Event.any(Event.signal(createScopedOnMessageEvent(id, 'ipc:disconnect')), onDidClientReconnect.event); const protocol = new Protocol(webContents, onMessage); diff --git a/src/vs/base/parts/ipc/node/ipc.electron.ts b/src/vs/base/parts/ipc/node/ipc.electron.ts index 831a27377c1..e70289747fc 100644 --- a/src/vs/base/parts/ipc/node/ipc.electron.ts +++ b/src/vs/base/parts/ipc/node/ipc.electron.ts @@ -3,33 +3,20 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/node/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 - */ +import { Event } from 'vs/base/common/event'; export interface Sender { - send(channel: string, msg: string | null): void; + send(channel: string, msg: Buffer | null): void; } export class Protocol implements IMessagePassingProtocol { - private listener: IDisposable; - - private _onMessage = new Emitter(); - get onMessage(): Event { return this._onMessage.event; } - - constructor(private sender: Sender, onMessageEvent: Event) { - onMessageEvent(msg => this._onMessage.fire(Buffer.from(msg, 'base64'))); - } + constructor(private sender: Sender, readonly onMessage: Event) { } send(message: Buffer): void { try { - this.sender.send('ipc:message', message.toString('base64')); + this.sender.send('ipc:message', message); } catch (e) { // systems are going down } @@ -37,6 +24,5 @@ export class Protocol implements IMessagePassingProtocol { dispose(): void { this.sender.send('ipc:disconnect', null); - this.listener = dispose(this.listener); } } \ No newline at end of file From 480e15ca4e755cdae84079df70eab9ca44542ac3 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 5 Mar 2019 11:51:59 +0100 Subject: [PATCH 186/290] fixes #69112 --- src/tsconfig.strictNullChecks.json | 8 ++++---- .../{electron-browser => browser}/dirtydiffDecorator.ts | 0 .../{electron-browser => browser}/media/check-inverse.svg | 0 .../scm/{electron-browser => browser}/media/check.svg | 0 .../media/dirtydiffDecorator.css | 0 .../scm/{electron-browser => browser}/media/icon-dark.svg | 0 .../{electron-browser => browser}/media/icon-light.svg | 0 .../{electron-browser => browser}/media/scmViewlet.css | 0 .../scm/{electron-browser => browser}/scm.contribution.ts | 2 +- .../scm/{electron-browser => browser}/scmActivity.ts | 0 .../contrib/scm/{electron-browser => browser}/scmMenus.ts | 0 .../contrib/scm/{electron-browser => browser}/scmUtil.ts | 0 .../scm/{electron-browser => browser}/scmViewlet.ts | 0 .../test/electron-browser/colorRegistry.releaseTest.ts | 2 +- src/vs/workbench/workbench.main.ts | 4 ++-- 15 files changed, 8 insertions(+), 8 deletions(-) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/dirtydiffDecorator.ts (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/media/check-inverse.svg (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/media/check.svg (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/media/dirtydiffDecorator.css (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/media/icon-dark.svg (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/media/icon-light.svg (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/media/scmViewlet.css (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/scm.contribution.ts (98%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/scmActivity.ts (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/scmMenus.ts (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/scmUtil.ts (100%) rename src/vs/workbench/contrib/scm/{electron-browser => browser}/scmViewlet.ts (100%) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index d8bae789a91..7bed7f931fe 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -255,10 +255,10 @@ "./vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts", "./vs/workbench/contrib/scm/common/scm.ts", "./vs/workbench/contrib/scm/common/scmService.ts", - "./vs/workbench/contrib/scm/electron-browser/dirtydiffDecorator.ts", - "./vs/workbench/contrib/scm/electron-browser/scmActivity.ts", - "./vs/workbench/contrib/scm/electron-browser/scmMenus.ts", - "./vs/workbench/contrib/scm/electron-browser/scmUtil.ts", + "./vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts", + "./vs/workbench/contrib/scm/browser/scmActivity.ts", + "./vs/workbench/contrib/scm/browser/scmMenus.ts", + "./vs/workbench/contrib/scm/browser/scmUtil.ts", "./vs/workbench/contrib/search/browser/openAnythingHandler.ts", "./vs/workbench/contrib/search/browser/openFileHandler.ts", "./vs/workbench/contrib/search/browser/openSymbolHandler.ts", diff --git a/src/vs/workbench/contrib/scm/electron-browser/dirtydiffDecorator.ts b/src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/dirtydiffDecorator.ts rename to src/vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts diff --git a/src/vs/workbench/contrib/scm/electron-browser/media/check-inverse.svg b/src/vs/workbench/contrib/scm/browser/media/check-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/media/check-inverse.svg rename to src/vs/workbench/contrib/scm/browser/media/check-inverse.svg diff --git a/src/vs/workbench/contrib/scm/electron-browser/media/check.svg b/src/vs/workbench/contrib/scm/browser/media/check.svg similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/media/check.svg rename to src/vs/workbench/contrib/scm/browser/media/check.svg diff --git a/src/vs/workbench/contrib/scm/electron-browser/media/dirtydiffDecorator.css b/src/vs/workbench/contrib/scm/browser/media/dirtydiffDecorator.css similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/media/dirtydiffDecorator.css rename to src/vs/workbench/contrib/scm/browser/media/dirtydiffDecorator.css diff --git a/src/vs/workbench/contrib/scm/electron-browser/media/icon-dark.svg b/src/vs/workbench/contrib/scm/browser/media/icon-dark.svg similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/media/icon-dark.svg rename to src/vs/workbench/contrib/scm/browser/media/icon-dark.svg diff --git a/src/vs/workbench/contrib/scm/electron-browser/media/icon-light.svg b/src/vs/workbench/contrib/scm/browser/media/icon-light.svg similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/media/icon-light.svg rename to src/vs/workbench/contrib/scm/browser/media/icon-light.svg diff --git a/src/vs/workbench/contrib/scm/electron-browser/media/scmViewlet.css b/src/vs/workbench/contrib/scm/browser/media/scmViewlet.css similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/media/scmViewlet.css rename to src/vs/workbench/contrib/scm/browser/media/scmViewlet.css diff --git a/src/vs/workbench/contrib/scm/electron-browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts similarity index 98% rename from src/vs/workbench/contrib/scm/electron-browser/scm.contribution.ts rename to src/vs/workbench/contrib/scm/browser/scm.contribution.ts index 70258e96a6a..9172c0ab736 100644 --- a/src/vs/workbench/contrib/scm/electron-browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -14,7 +14,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { StatusUpdater, StatusBarController } from './scmActivity'; -import { SCMViewlet } from 'vs/workbench/contrib/scm/electron-browser/scmViewlet'; +import { SCMViewlet } from 'vs/workbench/contrib/scm/browser/scmViewlet'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; diff --git a/src/vs/workbench/contrib/scm/electron-browser/scmActivity.ts b/src/vs/workbench/contrib/scm/browser/scmActivity.ts similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/scmActivity.ts rename to src/vs/workbench/contrib/scm/browser/scmActivity.ts diff --git a/src/vs/workbench/contrib/scm/electron-browser/scmMenus.ts b/src/vs/workbench/contrib/scm/browser/scmMenus.ts similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/scmMenus.ts rename to src/vs/workbench/contrib/scm/browser/scmMenus.ts diff --git a/src/vs/workbench/contrib/scm/electron-browser/scmUtil.ts b/src/vs/workbench/contrib/scm/browser/scmUtil.ts similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/scmUtil.ts rename to src/vs/workbench/contrib/scm/browser/scmUtil.ts diff --git a/src/vs/workbench/contrib/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts similarity index 100% rename from src/vs/workbench/contrib/scm/electron-browser/scmViewlet.ts rename to src/vs/workbench/contrib/scm/browser/scmViewlet.ts diff --git a/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts b/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts index 096e70ce7d2..1da752ea1f9 100644 --- a/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts +++ b/src/vs/workbench/test/electron-browser/colorRegistry.releaseTest.ts @@ -6,7 +6,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IColorRegistry, Extensions, ColorContribution } from 'vs/platform/theme/common/colorRegistry'; import { editorMarkerNavigationError } from 'vs/editor/contrib/gotoError/gotoErrorWidget'; -import { overviewRulerModifiedForeground } from 'vs/workbench/contrib/scm/electron-browser/dirtydiffDecorator'; +import { overviewRulerModifiedForeground } from 'vs/workbench/contrib/scm/browser/dirtydiffDecorator'; import { STATUS_BAR_DEBUGGING_BACKGROUND } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider'; import { debugExceptionWidgetBackground } from 'vs/workbench/contrib/debug/browser/exceptionWidget'; import { debugToolBarBackground } from 'vs/workbench/contrib/debug/browser/debugToolbar'; diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 69bf6bcd8ce..3487d9ab09a 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -121,8 +121,8 @@ import 'vs/workbench/contrib/search/browser/searchView'; import 'vs/workbench/contrib/search/browser/openAnythingHandler'; // SCM -import 'vs/workbench/contrib/scm/electron-browser/scm.contribution'; -import 'vs/workbench/contrib/scm/electron-browser/scmViewlet'; +import 'vs/workbench/contrib/scm/browser/scm.contribution'; +import 'vs/workbench/contrib/scm/browser/scmViewlet'; // Debug import 'vs/workbench/contrib/debug/electron-browser/debug.contribution'; From 532213ed2650198c35cc52026efa6f59b055a87f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 11:55:46 +0100 Subject: [PATCH 187/290] :lipstick: --- src/vs/workbench/browser/actions.ts | 11 +-- src/vs/workbench/common/contributions.ts | 13 ++-- src/vs/workbench/common/editor.ts | 11 +-- .../workbench/electron-browser/workbench.ts | 71 +++++++++++-------- .../browser/parts/editor/baseEditor.test.ts | 2 +- .../test/common/editor/editorGroups.test.ts | 10 +-- 6 files changed, 67 insertions(+), 51 deletions(-) diff --git a/src/vs/workbench/browser/actions.ts b/src/vs/workbench/browser/actions.ts index c6355e52f00..a31b6947af2 100644 --- a/src/vs/workbench/browser/actions.ts +++ b/src/vs/workbench/browser/actions.ts @@ -7,7 +7,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { Action, IAction } from 'vs/base/common/actions'; import { BaseActionItem, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { ITree, IActionProvider } from 'vs/base/parts/tree/browser/tree'; -import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, IConstructorSignature0, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; /** * The action bar contributor allows to add actions to an actionbar in a given context. @@ -235,7 +235,10 @@ export interface IActionBarRegistry { */ getActionBarContributors(scope: string): ActionBarContributor[]; - setInstantiationService(service: IInstantiationService): void; + /** + * Starts the registry by providing the required services. + */ + start(accessor: ServicesAccessor): void; } class ActionBarRegistry implements IActionBarRegistry { @@ -243,8 +246,8 @@ class ActionBarRegistry implements IActionBarRegistry { private actionBarContributorInstances: { [scope: string]: ActionBarContributor[] } = Object.create(null); private instantiationService: IInstantiationService; - setInstantiationService(service: IInstantiationService): void { - this.instantiationService = service; + start(accessor: ServicesAccessor): void { + this.instantiationService = accessor.get(IInstantiationService); while (this.actionBarContributorConstructors.length > 0) { const entry = this.actionBarContributorConstructors.shift()!; diff --git a/src/vs/workbench/common/contributions.ts b/src/vs/workbench/common/contributions.ts index 01a8631bf8f..e60c8dbc795 100644 --- a/src/vs/workbench/common/contributions.ts +++ b/src/vs/workbench/common/contributions.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, IConstructorSignature0, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { runWhenIdle, IdleDeadline } from 'vs/base/common/async'; @@ -34,10 +34,9 @@ export interface IWorkbenchContributionsRegistry { /** * Starts the registry by providing the required services. */ - start(instantiationService: IInstantiationService, lifecycleService: ILifecycleService): void; + start(accessor: ServicesAccessor): void; } - class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry { private instantiationService: IInstantiationService; private lifecycleService: ILifecycleService; @@ -63,12 +62,12 @@ class WorkbenchContributionsRegistry implements IWorkbenchContributionsRegistry } } - start(instantiationService: IInstantiationService, lifecycleService: ILifecycleService): void { - this.instantiationService = instantiationService; - this.lifecycleService = lifecycleService; + start(accessor: ServicesAccessor): void { + this.instantiationService = accessor.get(IInstantiationService); + this.lifecycleService = accessor.get(ILifecycleService); [LifecyclePhase.Starting, LifecyclePhase.Ready, LifecyclePhase.Restored, LifecyclePhase.Eventually].forEach(phase => { - this.instantiateByPhase(instantiationService, lifecycleService, phase); + this.instantiateByPhase(this.instantiationService, this.lifecycleService, phase); }); } diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index bd9740edb23..6a016bc91cc 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { IEditor as ICodeEditor, IEditorViewState, ScrollType, IDiffEditor } from 'vs/editor/common/editorCommon'; import { IEditorModel, IEditorOptions, ITextEditorOptions, IBaseResourceInput } from 'vs/platform/editor/common/editor'; -import { IInstantiationService, IConstructorSignature0 } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, IConstructorSignature0, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITextModel } from 'vs/editor/common/model'; @@ -175,7 +175,10 @@ export interface IEditorInputFactoryRegistry { */ getEditorInputFactory(editorInputId: string): IEditorInputFactory; - setInstantiationService(service: IInstantiationService): void; + /** + * Starts the registry by providing the required services. + */ + start(accessor: ServicesAccessor): void; } export interface IEditorInputFactory { @@ -1034,8 +1037,8 @@ class EditorInputFactoryRegistry implements IEditorInputFactoryRegistry { private editorInputFactoryConstructors: { [editorInputId: string]: IConstructorSignature0 } = Object.create(null); private editorInputFactoryInstances: { [editorInputId: string]: IEditorInputFactory } = Object.create(null); - setInstantiationService(service: IInstantiationService): void { - this.instantiationService = service; + start(accessor: ServicesAccessor): void { + this.instantiationService = accessor.get(IInstantiationService); for (let key in this.editorInputFactoryConstructors) { const element = this.editorInputFactoryConstructors[key]; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index d293d8e11b0..b79377cfcbe 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -311,11 +311,14 @@ export class Workbench extends Disposable implements IPartService { readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), getZoomLevel())); // Create Workbench Container - this.createWorkbench(); + this.createWorkbenchContainer(); // Services this.initServices(this.serviceCollection); + // Registries + this.startRegistries(); + // Context Keys this._register(this.instantiationService.createInstance(WorkbenchContextKeysHandler)); @@ -343,7 +346,7 @@ export class Workbench extends Disposable implements IPartService { return this.restoreParts().then(() => this.whenStarted(), error => this.whenStarted(error)); } - private createWorkbench(): void { + private createWorkbenchContainer(): void { this.workbench = document.createElement('div'); const platformClass = isWindows ? 'windows' : isLinux ? 'linux' : 'mac'; @@ -415,8 +418,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService, undefined, true)); // Remote Resolver - const remoteAuthorityResolverService = new RemoteAuthorityResolverService(); - serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); + serviceCollection.set(IRemoteAuthorityResolverService, new SyncDescriptor(RemoteAuthorityResolverService, undefined, true)); // Remote Agent const remoteAgentService = new RemoteAgentService(this.configuration, this.notificationService, this.environmentService, remoteAuthorityResolverService); @@ -552,15 +554,18 @@ export class Workbench extends Disposable implements IPartService { remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService)); } - // Set the some services to registries that have been created eagerly - Registry.as(ActionBarExtensions.Actionbar).setInstantiationService(this.instantiationService); - Registry.as(WorkbenchExtensions.Workbench).start(this.instantiationService, this.lifecycleService); - Registry.as(EditorExtensions.EditorInputFactories).setInstantiationService(this.instantiationService); - // TODO@Sandeep debt around cyclic dependencies this.configurationService.acquireInstantiationService(this.instantiationService); } + private startRegistries(): void { + this.instantiationService.invokeFunction(accessor => { + Registry.as(ActionBarExtensions.Actionbar).start(accessor); + Registry.as(WorkbenchExtensions.Workbench).start(accessor); + Registry.as(EditorExtensions.EditorInputFactories).start(accessor); + }); + } + private hasInitialFilesToOpen(): boolean { return !!( (this.configuration.filesToCreate && this.configuration.filesToCreate.length > 0) || @@ -577,6 +582,25 @@ export class Workbench extends Disposable implements IPartService { this._register(this.configurationService.onDidChangeConfiguration(() => this.setFontAliasing())); } + private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto'; + private setFontAliasing() { + const aliasing = this.configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>(Settings.FONT_ALIASING); + if (this.fontAliasing === aliasing) { + return; + } + + this.fontAliasing = aliasing; + + // Remove all + const fontAliasingValues: (typeof aliasing)[] = ['antialiased', 'none', 'auto']; + removeClasses(this.workbench, ...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); + + // Add specific + if (fontAliasingValues.some(option => option === aliasing)) { + addClass(this.workbench, `monaco-font-aliasing-${aliasing}`); + } + } + private renderWorkbench(): void { if (this.state.sideBar.hidden) { addClass(this.workbench, 'nosidebar'); @@ -612,25 +636,6 @@ export class Workbench extends Disposable implements IPartService { this.container.appendChild(this.workbench); } - private fontAliasing: 'default' | 'antialiased' | 'none' | 'auto'; - private setFontAliasing() { - const aliasing = this.configurationService.getValue<'default' | 'antialiased' | 'none' | 'auto'>(Settings.FONT_ALIASING); - if (this.fontAliasing === aliasing) { - return; - } - - this.fontAliasing = aliasing; - - // Remove all - const fontAliasingValues: (typeof aliasing)[] = ['antialiased', 'none', 'auto']; - removeClasses(this.workbench, ...fontAliasingValues.map(value => `monaco-font-aliasing-${value}`)); - - // Add specific - if (fontAliasingValues.some(option => option === aliasing)) { - addClass(this.workbench, `monaco-font-aliasing-${aliasing}`); - } - } - private createTitlebarPart(): void { const titlebarContainer = this.createPart(Identifiers.TITLEBAR_PART, 'contentinfo', 'titlebar'); @@ -736,14 +741,20 @@ export class Workbench extends Disposable implements IPartService { if (this.state.sideBar.viewletToRestore) { mark('willRestoreViewlet'); restorePromises.push(this.sidebarPart.openViewlet(this.state.sideBar.viewletToRestore) - .then(viewlet => viewlet || this.sidebarPart.openViewlet(this.sidebarPart.getDefaultViewletId())) + .then(viewlet => { + if (!viewlet) { + return this.sidebarPart.openViewlet(this.sidebarPart.getDefaultViewletId()); // fallback to default viewlet as needed + } + + return viewlet; + }) .then(() => mark('didRestoreViewlet'))); } // Restore Panel if (this.state.panel.panelToRestore) { mark('willRestorePanel'); - this.panelPart.openPanel(this.state.panel.panelToRestore, false); + this.panelPart.openPanel(this.state.panel.panelToRestore); mark('didRestorePanel'); } diff --git a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts index b959ede3928..4f7400dbc91 100644 --- a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts @@ -180,7 +180,7 @@ suite('Workbench base editor', () => { }); test('Editor Input Factory', function () { - EditorInputRegistry.setInstantiationService(workbenchInstantiationService()); + workbenchInstantiationService().invokeFunction(accessor => EditorInputRegistry.start(accessor)); EditorInputRegistry.registerEditorInputFactory('myInputId', MyInputFactory); let factory = EditorInputRegistry.getEditorInputFactory('myInputId'); diff --git a/src/vs/workbench/test/common/editor/editorGroups.test.ts b/src/vs/workbench/test/common/editor/editorGroups.test.ts index bc186f8d331..fde39c097be 100644 --- a/src/vs/workbench/test/common/editor/editorGroups.test.ts +++ b/src/vs/workbench/test/common/editor/editorGroups.test.ts @@ -215,7 +215,7 @@ suite('Workbench editor groups', () => { }); test('group serialization', function () { - Registry.as(EditorExtensions.EditorInputFactories).setInstantiationService(inst()); + inst().invokeFunction(accessor => Registry.as(EditorExtensions.EditorInputFactories).start(accessor)); const group = createGroup(); const input1 = input(); @@ -1003,7 +1003,7 @@ suite('Workbench editor groups', () => { config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); inst.stub(IConfigurationService, config); - (Registry.as(EditorExtensions.EditorInputFactories)).setInstantiationService(inst); + inst.invokeFunction(accessor => Registry.as(EditorExtensions.EditorInputFactories).start(accessor)); let group = createGroup(); @@ -1037,7 +1037,7 @@ suite('Workbench editor groups', () => { config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); inst.stub(IConfigurationService, config); - (Registry.as(EditorExtensions.EditorInputFactories)).setInstantiationService(inst); + inst.invokeFunction(accessor => Registry.as(EditorExtensions.EditorInputFactories).start(accessor)); let group1 = createGroup(); @@ -1107,7 +1107,7 @@ suite('Workbench editor groups', () => { config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); inst.stub(IConfigurationService, config); - (Registry.as(EditorExtensions.EditorInputFactories)).setInstantiationService(inst); + inst.invokeFunction(accessor => Registry.as(EditorExtensions.EditorInputFactories).start(accessor)); let group = createGroup(); @@ -1151,7 +1151,7 @@ suite('Workbench editor groups', () => { config.setUserConfiguration('workbench', { editor: { openPositioning: 'right' } }); inst.stub(IConfigurationService, config); - (Registry.as(EditorExtensions.EditorInputFactories)).setInstantiationService(inst); + inst.invokeFunction(accessor => Registry.as(EditorExtensions.EditorInputFactories).start(accessor)); let group1 = createGroup(); let group2 = createGroup(); From 3996321aaa07d3e14fe71aa3b3a3b7f5f1261a26 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 11:59:19 +0100 Subject: [PATCH 188/290] fix compile issue --- src/vs/workbench/electron-browser/workbench.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index b79377cfcbe..9e386737a68 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -421,8 +421,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IRemoteAuthorityResolverService, new SyncDescriptor(RemoteAuthorityResolverService, undefined, true)); // Remote Agent - const remoteAgentService = new RemoteAgentService(this.configuration, this.notificationService, this.environmentService, remoteAuthorityResolverService); - serviceCollection.set(IRemoteAgentService, remoteAgentService); + serviceCollection.set(IRemoteAgentService, new SyncDescriptor(RemoteAgentService, [this.configuration])); // Extensions Management const extensionManagementChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('extensions'))); @@ -547,12 +546,14 @@ export class Workbench extends Disposable implements IPartService { } // TODO this should move somewhere else - const remoteAgentConnection = remoteAgentService.getConnection(); - if (remoteAgentConnection) { - remoteAgentConnection.registerChannel('dialog', this.instantiationService.createInstance(DialogChannel)); - remoteAgentConnection.registerChannel('download', new DownloadServiceChannel()); - remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService)); - } + this.instantiationService.invokeFunction(accessor => { + const remoteAgentConnection = accessor.get(IRemoteAgentService).getConnection(); + if (remoteAgentConnection) { + remoteAgentConnection.registerChannel('dialog', this.instantiationService.createInstance(DialogChannel)); + remoteAgentConnection.registerChannel('download', new DownloadServiceChannel()); + remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService)); + } + }); // TODO@Sandeep debt around cyclic dependencies this.configurationService.acquireInstantiationService(this.instantiationService); From 54da2fb645afdb5f4e155f50bf7ec6929f569620 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 12:22:41 +0100 Subject: [PATCH 189/290] :lipstick: --- .../workbench/electron-browser/workbench.ts | 101 +++++++++++------- 1 file changed, 64 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 9e386737a68..1d3363dfb8b 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -103,6 +103,8 @@ import { WorkbenchThemeService } from 'vs/workbench/services/themes/browser/work import { IProductService } from 'vs/platform/product/common/product'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; +import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; // import@node import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; @@ -190,13 +192,17 @@ export class Workbench extends Disposable implements IPartService { private editorService: EditorService; private editorGroupService: IEditorGroupsService; private contextViewService: ContextViewService; - private keybindingService: IKeybindingService; private backupFileService: IBackupFileService; private notificationService: NotificationService; - private themeService: WorkbenchThemeService; - private telemetryService: ITelemetryService; private windowService: IWindowService; private lifecycleService: LifecycleService; + private instantiationService: IInstantiationService; + private contextService: IWorkspaceContextService; + private storageService: IStorageService; + private configurationService: WorkspaceService; + private environmentService: IEnvironmentService; + private logService: ILogService; + private windowsService: IWindowsService; private titlebarPart: TitlebarPart; private activitybarPart: ActivitybarPart; @@ -215,16 +221,24 @@ export class Workbench extends Disposable implements IPartService { private container: HTMLElement, private configuration: IWindowConfiguration, private serviceCollection: ServiceCollection, - @IInstantiationService private readonly instantiationService: IInstantiationService, - @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @IStorageService private readonly storageService: IStorageService, - @IConfigurationService private readonly configurationService: WorkspaceService, - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @ILogService private readonly logService: ILogService, - @IWindowsService private readonly windowsService: IWindowsService + @IInstantiationService instantiationService: IInstantiationService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IStorageService storageService: IStorageService, + @IConfigurationService configurationService: WorkspaceService, + @IEnvironmentService environmentService: IEnvironmentService, + @ILogService logService: ILogService, + @IWindowsService windowsService: IWindowsService ) { super(); + this.instantiationService = instantiationService; + this.contextService = contextService; + this.storageService = storageService; + this.configurationService = configurationService; + this.environmentService = environmentService; + this.logService = logService; + this.windowsService = windowsService; + this.registerErrorHandler(); } @@ -343,7 +357,7 @@ export class Workbench extends Disposable implements IPartService { this.lifecycleService.when(LifecyclePhase.Restored).then(() => clearTimeout(timeoutHandle)); // Restore Parts - return this.restoreParts().then(() => this.whenStarted(), error => this.whenStarted(error)); + return this.restoreParts().then(() => this.instantiationService.invokeFunction(accessor => this.whenStarted(accessor)), error => this.instantiationService.invokeFunction(accessor => this.whenStarted(accessor, error))); } private createWorkbenchContainer(): void { @@ -385,6 +399,7 @@ export class Workbench extends Disposable implements IPartService { }); // Telemetry + let telemetryService: ITelemetryService; if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!productService.enableTelemetry) { const channel = getDelayedChannel(sharedProcess.then(c => c.getChannel('telemetryAppender'))); const config: ITelemetryServiceConfig = { @@ -393,14 +408,14 @@ export class Workbench extends Disposable implements IPartService { piiPaths: [this.environmentService.appRoot, this.environmentService.extensionsPath] }; - this.telemetryService = this._register(this.instantiationService.createInstance(TelemetryService, config)); - this._register(new ErrorTelemetry(this.telemetryService)); + telemetryService = this._register(this.instantiationService.createInstance(TelemetryService, config)); + this._register(new ErrorTelemetry(telemetryService)); } else { - this.telemetryService = NullTelemetryService; + telemetryService = NullTelemetryService; } - serviceCollection.set(ITelemetryService, this.telemetryService); - this._register(configurationTelemetry(this.telemetryService, this.configurationService)); + serviceCollection.set(ITelemetryService, telemetryService); + this._register(configurationTelemetry(telemetryService, this.configurationService)); // Lifecycle this.lifecycleService = this.instantiationService.createInstance(LifecycleService); @@ -436,8 +451,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IExtensionService, new SyncDescriptor(ExtensionService)); // Theming - this.themeService = this.instantiationService.createInstance(WorkbenchThemeService, document.body); - serviceCollection.set(IWorkbenchThemeService, this.themeService); + serviceCollection.set(IWorkbenchThemeService, new SyncDescriptor(WorkbenchThemeService, [document.body])); // Commands serviceCollection.set(ICommandService, new SyncDescriptor(CommandService, undefined, true)); @@ -469,8 +483,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IContextKeyService, new SyncDescriptor(ContextKeyService)); // Keybindings - this.keybindingService = this.instantiationService.createInstance(WorkbenchKeybindingService, window); - serviceCollection.set(IKeybindingService, this.keybindingService); + serviceCollection.set(IKeybindingService, new SyncDescriptor(WorkbenchKeybindingService, [window])); // Context view service this.contextViewService = this.instantiationService.createInstance(ContextViewService, this.workbench); @@ -501,10 +514,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IActivityService, new SyncDescriptor(ActivityService, [this.activitybarPart, this.panelPart], true)); // File Service - const fileService = this.instantiationService.createInstance(RemoteFileService); - serviceCollection.set(IFileService, fileService); - this.configurationService.acquireFileService(fileService); - this.themeService.acquireFileService(fileService); + serviceCollection.set(IFileService, new SyncDescriptor(RemoteFileService)); // Editor and Group services this.editorPart = this.instantiationService.createInstance(EditorPart, Identifiers.EDITOR_PART, !this.hasInitialFilesToOpen()); @@ -545,7 +555,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(contributedService.id, contributedService.descriptor); } - // TODO this should move somewhere else + // TODO@Alex TODO@Sandeep this should move somewhere else this.instantiationService.invokeFunction(accessor => { const remoteAgentConnection = accessor.get(IRemoteAgentService).getConnection(); if (remoteAgentConnection) { @@ -555,8 +565,17 @@ export class Workbench extends Disposable implements IPartService { } }); - // TODO@Sandeep debt around cyclic dependencies - this.configurationService.acquireInstantiationService(this.instantiationService); + // TODO@Sandeep TODO@Martin debt around cyclic dependencies + this.instantiationService.invokeFunction(accessor => { + const fileService = accessor.get(IFileService); + const instantiationService = accessor.get(IInstantiationService); + const themeService = accessor.get(IThemeService) as WorkbenchThemeService; + + this.configurationService.acquireFileService(fileService); + this.configurationService.acquireInstantiationService(instantiationService); + + themeService.acquireFileService(fileService); + }); } private startRegistries(): void { @@ -772,17 +791,25 @@ export class Workbench extends Disposable implements IPartService { return Promise.all(restorePromises); } - private whenStarted(error?: Error): void { + private whenStarted(accessor: ServicesAccessor, error?: Error): void { + const themeService = accessor.get(IWorkbenchThemeService); + const keybindingsService = accessor.get(IKeybindingService); + const lifecycleService = accessor.get(ILifecycleService) as LifecycleService; + const editorService = accessor.get(IEditorService); + const activityService = accessor.get(IActivityService); + const contextService = accessor.get(IWorkspaceContextService); + const telemetryService = accessor.get(ITelemetryService); + this.restored = true; // Set lifecycle phase to `Restored` - this.lifecycleService.phase = LifecyclePhase.Restored; + lifecycleService.phase = LifecyclePhase.Restored; // Set lifecycle phase to `Eventually` after a short delay and when // idle (min 2.5sec, max 5sec) setTimeout(() => { this._register(runWhenIdle(() => { - this.lifecycleService.phase = LifecyclePhase.Eventually; + lifecycleService.phase = LifecyclePhase.Eventually; }, 2500)); }, 2500); @@ -813,20 +840,20 @@ export class Workbench extends Disposable implements IPartService { "startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } } */ - this.telemetryService.publicLog('workspaceLoad', { + telemetryService.publicLog('workspaceLoad', { userAgent: navigator.userAgent, windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }, - emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY, + emptyWorkbench: contextService.getWorkbenchState() === WorkbenchState.EMPTY, 'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0, 'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0, 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, - customKeybindingsCount: this.keybindingService.customKeybindingsCount(), - theme: this.themeService.getColorTheme().id, + customKeybindingsCount: keybindingsService.customKeybindingsCount(), + theme: themeService.getColorTheme().id, language, - pinnedViewlets: this.activitybarPart.getPinnedViewletIds(), + pinnedViewlets: activityService.getPinnedViewletIds(), restoredViewlet: this.state.sideBar.viewletToRestore, - restoredEditors: this.editorService.visibleEditors.length, - startupKind: this.lifecycleService.startupKind + restoredEditors: editorService.visibleEditors.length, + startupKind: lifecycleService.startupKind }); // Telemetry: startup metrics From ef20041efe558573f442e0eccdc7b41af2430d75 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 12:24:55 +0100 Subject: [PATCH 190/290] use IWorkbenchThemeService as import --- src/vs/workbench/electron-browser/workbench.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 1d3363dfb8b..44ec80fb496 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -104,7 +104,6 @@ import { IProductService } from 'vs/platform/product/common/product'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; // import@node import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; @@ -569,7 +568,7 @@ export class Workbench extends Disposable implements IPartService { this.instantiationService.invokeFunction(accessor => { const fileService = accessor.get(IFileService); const instantiationService = accessor.get(IInstantiationService); - const themeService = accessor.get(IThemeService) as WorkbenchThemeService; + const themeService = accessor.get(IWorkbenchThemeService) as WorkbenchThemeService; this.configurationService.acquireFileService(fileService); this.configurationService.acquireInstantiationService(instantiationService); From e8e7703ab497f70677e922434393ff5be100b109 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 12:30:06 +0100 Subject: [PATCH 191/290] fix #69406 --- .../services/markerDecorationsServiceImpl.ts | 27 ++++++++++++++++--- .../services/markersDecorationService.ts | 8 +++++- .../contrib/documentSymbols/outlineModel.ts | 20 +++++++++----- .../contrib/outline/browser/outlinePanel.ts | 22 +++++++-------- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/vs/editor/common/services/markerDecorationsServiceImpl.ts b/src/vs/editor/common/services/markerDecorationsServiceImpl.ts index ecf4af882d6..70748519a41 100644 --- a/src/vs/editor/common/services/markerDecorationsServiceImpl.ts +++ b/src/vs/editor/common/services/markerDecorationsServiceImpl.ts @@ -15,6 +15,7 @@ import { Range } from 'vs/editor/common/core/range'; import { keys } from 'vs/base/common/map'; import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; import { Schemas } from 'vs/base/common/network'; +import { Emitter, Event } from 'vs/base/common/event'; function MODEL_ID(resource: URI): string { return resource.toString(); @@ -44,12 +45,26 @@ class MarkerDecorations extends Disposable { getMarker(decoration: IModelDecoration): IMarker | undefined { return this._markersData.get(decoration.id); } + + getMarkers(): [Range, IMarker][] { + const res: [Range, IMarker][] = []; + this._markersData.forEach((marker, id) => { + let range = this.model.getDecorationRange(id); + if (range) { + res.push([range, marker]); + } + }); + return res; + } } export class MarkerDecorationsService extends Disposable implements IMarkerDecorationsService { _serviceBrand: any; + private readonly _onDidChangeMarker = new Emitter(); + readonly onDidChangeMarker: Event = this._onDidChangeMarker.event; + private readonly _markerDecorations: Map = new Map(); constructor( @@ -68,11 +83,16 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor return markerDecorations ? markerDecorations.getMarker(decoration) || null : null; } + getLiveMarkers(model: ITextModel): [Range, IMarker][] { + const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri)); + return markerDecorations ? markerDecorations.getMarkers() : []; + } + private _handleMarkerChange(changedResources: URI[]): void { changedResources.forEach((resource) => { const markerDecorations = this._markerDecorations.get(MODEL_ID(resource)); if (markerDecorations) { - this.updateDecorations(markerDecorations); + this._updateDecorations(markerDecorations); } }); } @@ -80,7 +100,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor private _onModelAdded(model: ITextModel): void { const markerDecorations = new MarkerDecorations(model); this._markerDecorations.set(MODEL_ID(model.uri), markerDecorations); - this.updateDecorations(markerDecorations); + this._updateDecorations(markerDecorations); } private _onModelRemoved(model: ITextModel): void { @@ -100,7 +120,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor } } - private updateDecorations(markerDecorations: MarkerDecorations): void { + private _updateDecorations(markerDecorations: MarkerDecorations): void { // Limit to the first 500 errors/warnings const markers = this._markerService.read({ resource: markerDecorations.model.uri, take: 500 }); let newModelDecorations: IModelDeltaDecoration[] = markers.map((marker) => { @@ -110,6 +130,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor }; }); markerDecorations.update(markers, newModelDecorations); + this._onDidChangeMarker.fire(markerDecorations.model); } private _createDecorationRange(model: ITextModel, rawMarker: IMarker): Range { diff --git a/src/vs/editor/common/services/markersDecorationService.ts b/src/vs/editor/common/services/markersDecorationService.ts index b2424a4d312..44aa7ca2463 100644 --- a/src/vs/editor/common/services/markersDecorationService.ts +++ b/src/vs/editor/common/services/markersDecorationService.ts @@ -6,11 +6,17 @@ import { ITextModel, IModelDecoration } from 'vs/editor/common/model'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IMarker } from 'vs/platform/markers/common/markers'; +import { Event } from 'vs/base/common/event'; +import { Range } from 'vs/editor/common/core/range'; export const IMarkerDecorationsService = createDecorator('markerDecorationsService'); export interface IMarkerDecorationsService { _serviceBrand: any; + onDidChangeMarker: Event; + getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null; -} \ No newline at end of file + + getLiveMarkers(model: ITextModel): [Range, IMarker][]; +} diff --git a/src/vs/editor/contrib/documentSymbols/outlineModel.ts b/src/vs/editor/contrib/documentSymbols/outlineModel.ts index 759ea82e044..61991f8a654 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineModel.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineModel.ts @@ -13,7 +13,7 @@ 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'; +import { MarkerSeverity } from 'vs/platform/markers/common/markers'; export abstract class TreeElement { @@ -86,6 +86,14 @@ export abstract class TreeElement { } } +export interface IOutlineMarker { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + severity: MarkerSeverity; +} + export class OutlineElement extends TreeElement { children: { [id: string]: OutlineElement; } = Object.create(null); @@ -140,13 +148,13 @@ export class OutlineGroup extends TreeElement { return undefined; } - updateMarker(marker: IMarker[]): void { + updateMarker(marker: IOutlineMarker[]): void { for (const key in this.children) { this._updateMarker(marker, this.children[key]); } } - private _updateMarker(markers: IMarker[], item: OutlineElement): void { + private _updateMarker(markers: IOutlineMarker[], item: OutlineElement): void { item.marker = undefined; // find the proper start index to check for item/marker overlap. @@ -161,7 +169,7 @@ export class OutlineGroup extends TreeElement { start = idx; } - let myMarkers: IMarker[] = []; + let myMarkers: IOutlineMarker[] = []; let myTopSev: MarkerSeverity | undefined; for (; start < markers.length && Range.areIntersecting(item.symbol.range, markers[start]); start++) { @@ -169,7 +177,7 @@ export class OutlineGroup extends TreeElement { // and store them in a 'private' array. let marker = markers[start]; myMarkers.push(marker); - (markers as Array)[start] = undefined; + (markers as Array)[start] = undefined; if (!myTopSev || marker.severity > myTopSev) { myTopSev = marker.severity; } @@ -413,7 +421,7 @@ export class OutlineModel extends TreeElement { return TreeElement.getElementById(id, this); } - updateMarker(marker: IMarker[]): void { + updateMarker(marker: IOutlineMarker[]): void { // sort markers by start range so that we can use // outline element starts for quicker look up marker.sort(Range.compareRangesUsingStarts); diff --git a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts index 59dbfe4c344..a083b522f01 100644 --- a/src/vs/workbench/contrib/outline/browser/outlinePanel.ts +++ b/src/vs/workbench/contrib/outline/browser/outlinePanel.ts @@ -7,7 +7,6 @@ import * as dom from 'vs/base/browser/dom'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; 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 { createCancelablePromise, TimeoutTimer } from 'vs/base/common/async'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; @@ -15,7 +14,6 @@ import { defaultGenerator } from 'vs/base/common/idGenerator'; import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LRUCache } from 'vs/base/common/map'; import { escape } from 'vs/base/common/strings'; -import { URI } from 'vs/base/common/uri'; import 'vs/css!./outlinePanel'; import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; import { Range } from 'vs/editor/common/core/range'; @@ -24,7 +22,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents'; import { DocumentSymbolProviderRegistry } from 'vs/editor/common/modes'; import { LanguageFeatureRegistry } from 'vs/editor/common/modes/languageFeatureRegistry'; -import { OutlineElement, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; +import { OutlineElement, OutlineModel, TreeElement, IOutlineMarker } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; @@ -33,7 +31,6 @@ import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { WorkbenchDataTree } from 'vs/platform/list/browser/listService'; -import { IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/markers'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { attachProgressBarStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -48,6 +45,7 @@ import { IDataTreeViewState } from 'vs/base/browser/ui/tree/dataTree'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { basename } from 'vs/base/common/resources'; import { IDataSource } from 'vs/base/browser/ui/tree/tree'; +import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; class RequestState { @@ -261,7 +259,7 @@ export class OutlinePanel extends ViewletPanel { @IThemeService private readonly _themeService: IThemeService, @IStorageService private readonly _storageService: IStorageService, @IEditorService private readonly _editorService: IEditorService, - @IMarkerService private readonly _markerService: IMarkerService, + @IMarkerDecorationsService private readonly _markerDecorationService: IMarkerDecorationsService, @IConfigurationService private readonly _configurationService: IConfigurationService, @IKeybindingService keybindingService: IKeybindingService, @IConfigurationService configurationService: IConfigurationService, @@ -569,21 +567,23 @@ export class OutlinePanel extends ViewletPanel { })); // feature: show markers in outline - const updateMarker = (e: URI[], ignoreEmpty?: boolean) => { + const updateMarker = (model: ITextModel, ignoreEmpty?: boolean) => { if (!this._configurationService.getValue(OutlineConfigKeys.problemsEnabled)) { return; } - if (firstIndex(e, a => a.toString() === textModel.uri.toString()) < 0) { + if (model !== textModel) { return; } - const marker = this._markerService.read({ resource: textModel.uri, severities: MarkerSeverity.Error | MarkerSeverity.Warning }); + const marker = this._markerDecorationService.getLiveMarkers(textModel).map(([range, marker]) => { + return { ...range, severity: marker.severity } as IOutlineMarker; + }); if (marker.length > 0 || !ignoreEmpty) { newModel.updateMarker(marker); this._tree.updateChildren(); } }; - updateMarker([textModel.uri], true); - this._editorDisposables.push(this._markerService.onMarkerChanged(updateMarker)); + updateMarker(textModel, true); + this._editorDisposables.push(this._markerDecorationService.onDidChangeMarker(updateMarker)); this._editorDisposables.push(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(OutlineConfigKeys.problemsBadges) || e.affectsConfiguration(OutlineConfigKeys.problemsColors)) { @@ -597,7 +597,7 @@ export class OutlinePanel extends ViewletPanel { newModel.updateMarker([]); this._tree.updateChildren(); } else { - updateMarker([textModel.uri], true); + updateMarker(textModel, true); } })); } From f9bda10403d717dba8da40d8c04db8e95ce4fe35 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 12:43:22 +0100 Subject: [PATCH 192/290] debt - extract a telemetry workbench contribution --- .../browser/telemetry.contribution.ts | 90 +++++++++++++++++++ .../workbench/electron-browser/workbench.ts | 57 ++---------- src/vs/workbench/workbench.main.ts | 3 + 3 files changed, 99 insertions(+), 51 deletions(-) create mode 100644 src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts diff --git a/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts b/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts new file mode 100644 index 00000000000..b2ca963f342 --- /dev/null +++ b/src/vs/workbench/contrib/telemetry/browser/telemetry.contribution.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 { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; +import { IActivityService } from 'vs/workbench/services/activity/common/activity'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { language } from 'vs/base/common/platform'; +import { Disposable } from 'vs/base/common/lifecycle'; +import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; +import { configurationTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; + +export class TelemetryContribution extends Disposable implements IWorkbenchContribution { + + constructor( + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IActivityService activityService: IActivityService, + @ILifecycleService lifecycleService: ILifecycleService, + @IEditorService editorService: IEditorService, + @IKeybindingService keybindingsService: IKeybindingService, + @IWorkbenchThemeService themeService: IWorkbenchThemeService, + @IWindowService windowService: IWindowService, + @IConfigurationService configurationService: IConfigurationService, + @IViewletService viewletService: IViewletService + ) { + super(); + + const { filesToOpen, filesToCreate, filesToDiff } = windowService.getConfiguration(); + const activeViewlet = viewletService.getActiveViewlet(); + + /* __GDPR__ + "workspaceLoad" : { + "userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" }, + "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + } + */ + telemetryService.publicLog('workspaceLoad', { + userAgent: navigator.userAgent, + windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }, + emptyWorkbench: contextService.getWorkbenchState() === WorkbenchState.EMPTY, + 'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0, + 'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0, + 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, + customKeybindingsCount: keybindingsService.customKeybindingsCount(), + theme: themeService.getColorTheme().id, + language, + pinnedViewlets: activityService.getPinnedViewletIds(), + restoredViewlet: activeViewlet ? activeViewlet.getId() : undefined, + restoredEditors: editorService.visibleEditors.length, + startupKind: lifecycleService.startupKind + }); + + // Error Telemetry + this._register(new ErrorTelemetry(telemetryService)); + + // Configuration Telemetry + this._register(configurationTelemetry(telemetryService, configurationService)); + + // Lifecycle + this._register(lifecycleService.onShutdown(() => this.dispose())); + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(TelemetryContribution, LifecyclePhase.Restored); \ 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 44ec80fb496..61dc43e4a62 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -16,7 +16,7 @@ import { mark } from 'vs/base/common/performance'; import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { Registry } from 'vs/platform/registry/common/platform'; -import { isWindows, isLinux, isMacintosh, language } from 'vs/base/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, IUntitledResourceInput, IResourceDiffInput } from 'vs/workbench/common/editor'; @@ -82,8 +82,7 @@ import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ILabelService } from 'vs/platform/label/common/label'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { combinedAppender, LogAppender, NullTelemetryService, configurationTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; -import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; +import { combinedAppender, LogAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IExtensionGalleryService, IExtensionManagementServerService, IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; @@ -356,7 +355,10 @@ export class Workbench extends Disposable implements IPartService { this.lifecycleService.when(LifecyclePhase.Restored).then(() => clearTimeout(timeoutHandle)); // Restore Parts - return this.restoreParts().then(() => this.instantiationService.invokeFunction(accessor => this.whenStarted(accessor)), error => this.instantiationService.invokeFunction(accessor => this.whenStarted(accessor, error))); + let error: Error; + return this.restoreParts() + .catch(err => error = err) + .finally(() => this.instantiationService.invokeFunction(accessor => this.whenStarted(accessor, error))); } private createWorkbenchContainer(): void { @@ -408,13 +410,11 @@ export class Workbench extends Disposable implements IPartService { }; telemetryService = this._register(this.instantiationService.createInstance(TelemetryService, config)); - this._register(new ErrorTelemetry(telemetryService)); } else { telemetryService = NullTelemetryService; } serviceCollection.set(ITelemetryService, telemetryService); - this._register(configurationTelemetry(telemetryService, this.configurationService)); // Lifecycle this.lifecycleService = this.instantiationService.createInstance(LifecycleService); @@ -791,13 +791,7 @@ export class Workbench extends Disposable implements IPartService { } private whenStarted(accessor: ServicesAccessor, error?: Error): void { - const themeService = accessor.get(IWorkbenchThemeService); - const keybindingsService = accessor.get(IKeybindingService); const lifecycleService = accessor.get(ILifecycleService) as LifecycleService; - const editorService = accessor.get(IEditorService); - const activityService = accessor.get(IActivityService); - const contextService = accessor.get(IWorkspaceContextService); - const telemetryService = accessor.get(ITelemetryService); this.restored = true; @@ -816,45 +810,6 @@ export class Workbench extends Disposable implements IPartService { onUnexpectedError(error); } - const { filesToOpen, filesToCreate, filesToDiff } = this.configuration; - - /* __GDPR__ - "workspaceLoad" : { - "userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" }, - "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, - "pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } - } - */ - telemetryService.publicLog('workspaceLoad', { - userAgent: navigator.userAgent, - windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth }, - emptyWorkbench: contextService.getWorkbenchState() === WorkbenchState.EMPTY, - 'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0, - 'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0, - 'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0, - customKeybindingsCount: keybindingsService.customKeybindingsCount(), - theme: themeService.getColorTheme().id, - language, - pinnedViewlets: activityService.getPinnedViewletIds(), - restoredViewlet: this.state.sideBar.viewletToRestore, - restoredEditors: editorService.visibleEditors.length, - startupKind: lifecycleService.startupKind - }); - // Telemetry: startup metrics mark('didStartWorkbench'); } diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 3487d9ab09a..ceffd2a8727 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -88,6 +88,9 @@ registerSingleton(IClipboardService, ClipboardService, true); //#region --- workbench contributions +// Telemetry +import 'vs/workbench/contrib/telemetry/browser/telemetry.contribution'; + // Localizations import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; From 3c209bdc83fc18fa0022015a49bc6c693dc79185 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Mar 2019 12:53:36 +0100 Subject: [PATCH 193/290] fix #65997 --- src/vs/editor/common/services/editorSimpleWorker.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index 4ef83f744a7..f5564b6f567 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -491,12 +491,15 @@ export abstract class BaseEditorSimpleWorker { return Promise.resolve(null); } + const seen: Record = Object.create(null); const suggestions: CompletionItem[] = []; const wordDefRegExp = new RegExp(wordDef, wordDefFlags); - const currentWord = model.getWordUntilPosition(position, wordDefRegExp); + const wordUntil = model.getWordUntilPosition(position, wordDefRegExp); - const seen: Record = Object.create(null); - seen[currentWord.word] = true; + const wordAt = model.getWordAtPosition(position, wordDefRegExp); + if (wordAt) { + seen[model.getValueInRange(wordAt)] = true; + } for ( let iter = model.createWordIterator(wordDefRegExp), e = iter.next(); @@ -516,10 +519,9 @@ export abstract class BaseEditorSimpleWorker { kind: CompletionItemKind.Text, label: word, insertText: word, - range: { startLineNumber: position.lineNumber, startColumn: currentWord.startColumn, endLineNumber: position.lineNumber, endColumn: currentWord.endColumn } + range: { startLineNumber: position.lineNumber, startColumn: wordUntil.startColumn, endLineNumber: position.lineNumber, endColumn: wordUntil.endColumn } }); } - return Promise.resolve({ suggestions }); } From f7f4357b9f4dc26483bf621e4dc9269469146491 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 12:56:38 +0100 Subject: [PATCH 194/290] services - sync descriptor for notification service --- src/vs/editor/common/controller/cursor.ts | 4 ++-- .../workbench/electron-browser/workbench.ts | 22 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 15ccc7a4e1f..81493777b1c 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import * as strings from 'vs/base/common/strings'; @@ -828,7 +827,8 @@ class CommandExecutor { try { command.getEditOperations(ctx.model, editOperationBuilder); } catch (e) { - e.friendlyMessage = nls.localize('corrupt.commands', "Unexpected exception while executing command."); + // TODO@Alex use notification service if this should be user facing + // e.friendlyMessage = nls.localize('corrupt.commands', "Unexpected exception while executing command."); onUnexpectedError(e); return { operations: [], diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 61dc43e4a62..b1e469d99db 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -191,7 +191,6 @@ export class Workbench extends Disposable implements IPartService { private editorGroupService: IEditorGroupsService; private contextViewService: ContextViewService; private backupFileService: IBackupFileService; - private notificationService: NotificationService; private windowService: IWindowService; private lifecycleService: LifecycleService; private instantiationService: IInstantiationService; @@ -281,11 +280,6 @@ export class Workbench extends Disposable implements IPartService { // Log it this.logService.error(errorMsg); - - // Show to user if friendly message provided - if (error && error.friendlyMessage && this.notificationService) { - this.notificationService.error(error.friendlyMessage); - } } startup(): void { @@ -379,8 +373,7 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(ILabelService, new SyncDescriptor(LabelService, undefined, true)); // Notifications - this.notificationService = new NotificationService(); - serviceCollection.set(INotificationService, this.notificationService); + serviceCollection.set(INotificationService, new SyncDescriptor(NotificationService, undefined, true)); // Window this.windowService = this.instantiationService.createInstance(WindowService, this.configuration); @@ -649,7 +642,7 @@ export class Workbench extends Disposable implements IPartService { this.createStatusbarPart(); // Notification Handlers - this.createNotificationsHandlers(); + this.instantiationService.invokeFunction(accessor => this.createNotificationsHandlers(accessor)); // Add Workbench to DOM this.container.appendChild(this.workbench); @@ -706,19 +699,20 @@ export class Workbench extends Disposable implements IPartService { return part; } - private createNotificationsHandlers(): void { + private createNotificationsHandlers(accessor: ServicesAccessor): void { + const notificationService = accessor.get(INotificationService) as NotificationService; // Notifications Center - this.notificationsCenter = this._register(this.instantiationService.createInstance(NotificationsCenter, this.workbench, this.notificationService.model)); + this.notificationsCenter = this._register(this.instantiationService.createInstance(NotificationsCenter, this.workbench, notificationService.model)); // Notifications Toasts - this.notificationsToasts = this._register(this.instantiationService.createInstance(NotificationsToasts, this.workbench, this.notificationService.model)); + this.notificationsToasts = this._register(this.instantiationService.createInstance(NotificationsToasts, this.workbench, notificationService.model)); // Notifications Alerts - this._register(this.instantiationService.createInstance(NotificationsAlerts, this.notificationService.model)); + this._register(this.instantiationService.createInstance(NotificationsAlerts, notificationService.model)); // Notifications Status - const notificationsStatus = this.instantiationService.createInstance(NotificationsStatus, this.notificationService.model); + const notificationsStatus = this.instantiationService.createInstance(NotificationsStatus, notificationService.model); // Eventing this._register(this.notificationsCenter.onDidChangeVisibility(() => { From c9370aeaf10450c09b6bb1f25fcc9d70ed5b48e9 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 5 Mar 2019 15:21:23 +0100 Subject: [PATCH 195/290] [css] updates service (multi-semantic selection, webpack) --- .../client/src/cssMain.ts | 42 +++++-------------- extensions/css-language-features/package.json | 2 +- .../server/build/filesFillIn.js | 5 --- .../server/extension.webpack.config.js | 10 +---- .../css-language-features/server/package.json | 4 +- .../server/src/cssServerMain.ts | 6 +-- .../css-language-features/server/yarn.lock | 38 ++++++++--------- extensions/css-language-features/yarn.lock | 28 ++++++------- 8 files changed, 51 insertions(+), 84 deletions(-) delete mode 100644 extensions/css-language-features/server/build/filesFillIn.js diff --git a/extensions/css-language-features/client/src/cssMain.ts b/extensions/css-language-features/client/src/cssMain.ts index 0312498f672..641d11f335b 100644 --- a/extensions/css-language-features/client/src/cssMain.ts +++ b/extensions/css-language-features/client/src/cssMain.ts @@ -9,8 +9,8 @@ import * as fs from 'fs'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { languages, window, commands, ExtensionContext, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString, workspace, TextDocument, SelectionRange, SelectionRangeKind } from 'vscode'; -import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Disposable, TextDocumentIdentifier } from 'vscode-languageclient'; +import { languages, window, commands, ExtensionContext, Range, Position, CompletionItem, CompletionItemKind, TextEdit, SnippetString, workspace, TextDocument, SelectionRange } from 'vscode'; +import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, Disposable } from 'vscode-languageclient'; import { getCustomDataPathsInAllWorkspaces, getCustomDataPathsFromAllExtensions } from './customData'; // this method is called when vs code is activated @@ -83,43 +83,23 @@ export function activate(context: ExtensionContext) { context.subscriptions.push(languages.registerSelectionRangeProvider(selector, { async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise { const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(document); - return Promise.all(positions.map(async position => { - const rawRanges = await client.sendRequest('$/textDocument/selectionRange', { textDocument, position }); - if (Array.isArray(rawRanges)) { - return rawRanges.map(r => { + const rawResult = await client.sendRequest('$/textDocument/selectionRanges', { textDocument, positions: positions.map(client.code2ProtocolConverter.asPosition) }); + if (Array.isArray(rawResult)) { + return rawResult.map(rawSelectionRanges => { + return rawSelectionRanges.map(selectionRange => { return { - range: client.protocol2CodeConverter.asRange(r), - kind: SelectionRangeKind.Declaration + range: client.protocol2CodeConverter.asRange(selectionRange.range), + kind: selectionRange.kind }; }); - } - return []; - })); + }); + } + return []; } })); }); }); - const selectionRangeProvider = { - async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise { - const textDocument = TextDocumentIdentifier.create(document.uri.toString()); - return Promise.all(positions.map(async position => { - const rawRanges: Range[] = await client.sendRequest('$/textDocument/selectionRange', { textDocument, position }); - - return rawRanges.map(r => { - const actualRange = new Range(new Position(r.start.line, r.start.character), new Position(r.end.line, r.end.character)); - return { - range: actualRange, - kind: SelectionRangeKind.Declaration - }; - }); - })); - } - }; - documentSelector.forEach(selector => { - languages.registerSelectionRangeProvider(selector, selectionRangeProvider); - }); - function initCompletionProvider(): Disposable { const regionCompletionRegExpr = /^(\s*)(\/(\*\s*(#\w*)?)?)?$/; diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index 99b022469d6..ac8a4b23c72 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -726,7 +726,7 @@ ] }, "dependencies": { - "vscode-languageclient": "^5.1.0", + "vscode-languageclient": "^5.2.1", "vscode-nls": "^4.0.0" }, "devDependencies": { diff --git a/extensions/css-language-features/server/build/filesFillIn.js b/extensions/css-language-features/server/build/filesFillIn.js deleted file mode 100644 index 906617384e0..00000000000 --- a/extensions/css-language-features/server/build/filesFillIn.js +++ /dev/null @@ -1,5 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -module.exports = {}; \ No newline at end of file diff --git a/extensions/css-language-features/server/extension.webpack.config.js b/extensions/css-language-features/server/extension.webpack.config.js index 17dc2d39e34..68b850b3773 100644 --- a/extensions/css-language-features/server/extension.webpack.config.js +++ b/extensions/css-language-features/server/extension.webpack.config.js @@ -9,7 +9,6 @@ const withDefaults = require('../../shared.webpack.config'); const path = require('path'); -var webpack = require('webpack'); module.exports = withDefaults({ context: path.join(__dirname), @@ -19,12 +18,5 @@ module.exports = withDefaults({ output: { filename: 'cssServerMain.js', path: path.join(__dirname, 'dist') - }, - plugins: [ - new webpack.NormalModuleReplacementPlugin( - /[/\\]vscode-languageserver[/\\]lib[/\\]files\.js/, - require.resolve('./build/filesFillIn') - ), - new webpack.IgnorePlugin(/vertx/) - ], + } }); diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index 9bc32c0a788..71e14f56ea2 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -9,8 +9,8 @@ }, "main": "./out/cssServerMain", "dependencies": { - "vscode-css-languageservice": "^3.0.13-next.12", - "vscode-languageserver": "^5.1.0" + "vscode-css-languageservice": "^4.0.0-next.3", + "vscode-languageserver": "^5.3.0-next.2" }, "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 3ef166f1b80..e1c78b158c1 100644 --- a/extensions/css-language-features/server/src/cssServerMain.ts +++ b/extensions/css-language-features/server/src/cssServerMain.ts @@ -335,14 +335,14 @@ connection.onFoldingRanges((params, token) => { }, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token); }); -connection.onRequest('$/textDocument/selectionRange', async (params, token) => { +connection.onRequest('$/textDocument/selectionRanges', async (params, token) => { return runSafe(() => { const document = documents.get(params.textDocument.uri); - const position: Position = params.position; + const positions: Position[] = params.positions; if (document) { const stylesheet = stylesheets.get(document); - return getLanguageService(document).getSelectionRanges(document, position, stylesheet); + return getLanguageService(document).getSelectionRanges(document, positions, stylesheet); } return Promise.resolve(null); }, null, `Error while computing selection ranges for ${params.textDocument.uri}`, token); diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index a2fa388731d..bfbcab4c931 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -229,12 +229,12 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.13-next.12: - version "3.0.13-next.12" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.13-next.12.tgz#8d20828e41bc7dcf44cdba4b2e476393780a7793" - integrity sha512-5B3NYU2DBFhbUvMuTg7kBlc9COHyr/pbR1cDzXGFwemQG8W6ERsgn+eftPHFbcug1kwBjPVSoMgtw/czKpboHQ== +vscode-css-languageservice@^4.0.0-next.3: + version "4.0.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.0-next.3.tgz#e9529f3b4ddf95c9a3e5dc2a6d701a38280ffa98" + integrity sha512-/xmbWpIQLw+HZ/3LsaE2drHFSNJbM9mZ8bKR5NUiu2ZUr10WbGxX0j/GDZB3LlMmdSHQGgRQ5hTM/Ic2PuBDRw== dependencies: - vscode-languageserver-types "^3.13.0" + vscode-languageserver-types "^3.14.0" vscode-nls "^4.0.0" vscode-jsonrpc@^4.0.0: @@ -242,25 +242,25 @@ vscode-jsonrpc@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== -vscode-languageserver-protocol@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.13.0.tgz#710d8e42119bb3affb1416e1e104bd6b4d503595" - integrity sha512-2ZGKwI+P2ovQll2PGAp+2UfJH+FK9eait86VBUdkPd9HRlm8e58aYT9pV/NYanHOcp3pL6x2yTLVCFMcTer0mg== +vscode-languageserver-protocol@3.15.0-next.1: + version "3.15.0-next.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.1.tgz#1e45e224d7eef8c79b4bed75b9dcb1930d2ab8ed" + integrity sha512-LXF0d9s3vxFBxVQ4aKl/XghdEMAncGt3dh4urIYa9Is43g3MfIQL9fC44YZtP+XXOrI2rpZU8lRNN01U1V6CDg== dependencies: vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.13.0" + vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.13.0, vscode-languageserver-types@^3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" - integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== +vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== -vscode-languageserver@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.1.0.tgz#012a28f154cc7a848c443d217894942e4c3eeb39" - integrity sha512-CIsrgx2Y5VHS317g/HwkSTWYBIQmy0DwEyZPmB2pEpVOhYFwVsYpbiJwHIIyLQsQtmRaO4eA2xM8KPjNSdXpBw== +vscode-languageserver@^5.3.0-next.2: + version "5.3.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.3.0-next.2.tgz#31ce4c34d68b517b400ca9e211e43f8d868b8dcc" + integrity sha512-n5onRw9naMrRHp2jnOn+ZwN1n+tTfzftWLPonjp1FWf/iCZWIlnw2TyF/Hn+SDGhLoVtoghmxhwEQaxEAfLHvw== dependencies: - vscode-languageserver-protocol "3.13.0" + vscode-languageserver-protocol "3.15.0-next.1" vscode-uri "^1.0.6" vscode-nls@^4.0.0: diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index 6314214090a..385d59738dd 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -167,26 +167,26 @@ vscode-jsonrpc@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== -vscode-languageclient@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.1.0.tgz#650ab0dc9fd0daaade058a8471aaff5bc3f9580e" - integrity sha512-Z95Kps8UqD4o17HE3uCkZuvenOsxHVH46dKmaGVpGixEFZigPaVuVxLM/JWeIY9aRenoC0ZD9CK1O7L4jpffKg== +vscode-languageclient@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193" + integrity sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q== dependencies: semver "^5.5.0" - vscode-languageserver-protocol "3.13.0" + vscode-languageserver-protocol "3.14.1" -vscode-languageserver-protocol@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.13.0.tgz#710d8e42119bb3affb1416e1e104bd6b4d503595" - integrity sha512-2ZGKwI+P2ovQll2PGAp+2UfJH+FK9eait86VBUdkPd9HRlm8e58aYT9pV/NYanHOcp3pL6x2yTLVCFMcTer0mg== +vscode-languageserver-protocol@3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f" + integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g== dependencies: vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.13.0" + vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" - integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== +vscode-languageserver-types@3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== vscode-nls@^4.0.0: version "4.0.0" From 8e986b18a0bc1656cbde8c13ecb5f9b78c1bc803 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 5 Mar 2019 15:22:49 +0100 Subject: [PATCH 196/290] [html] update service (multi semantic selection, webpack) --- .../client/src/htmlMain.ts | 20 ++++---- .../html-language-features/package.json | 2 +- .../server/build/filesFillIn.js | 5 -- .../server/extension.webpack.config.js | 10 +--- .../server/package.json | 8 ++-- .../server/src/customData.ts | 4 +- .../server/src/htmlServerMain.ts | 8 ++-- .../server/src/modes/htmlMode.ts | 6 +-- .../server/src/modes/languageModes.ts | 4 +- .../html-language-features/server/yarn.lock | 48 +++++++++---------- extensions/html-language-features/yarn.lock | 28 +++++------ 11 files changed, 65 insertions(+), 78 deletions(-) delete mode 100644 extensions/html-language-features/server/build/filesFillIn.js diff --git a/extensions/html-language-features/client/src/htmlMain.ts b/extensions/html-language-features/client/src/htmlMain.ts index 696bc074c84..27f3ad2d626 100644 --- a/extensions/html-language-features/client/src/htmlMain.ts +++ b/extensions/html-language-features/client/src/htmlMain.ts @@ -8,7 +8,7 @@ import * as fs from 'fs'; import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, workspace, SelectionRange, SelectionRangeKind } from 'vscode'; +import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, workspace, SelectionRange } from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams } from 'vscode-languageclient'; import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared'; import { activateTagClosing } from './tagClosing'; @@ -92,18 +92,18 @@ export function activate(context: ExtensionContext) { context.subscriptions.push(languages.registerSelectionRangeProvider(selector, { async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise { const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(document); - return Promise.all(positions.map(async position => { - const rawRanges = await client.sendRequest('$/textDocument/selectionRange', { textDocument, position }); - if (Array.isArray(rawRanges)) { - return rawRanges.map(r => { + const rawResult = await client.sendRequest('$/textDocument/selectionRanges', { textDocument, positions: positions.map(client.code2ProtocolConverter.asPosition) }); + if (Array.isArray(rawResult)) { + return rawResult.map(rawSelectionRanges => { + return rawSelectionRanges.map(selectionRange => { return { - range: client.protocol2CodeConverter.asRange(r), - kind: SelectionRangeKind.Declaration + range: client.protocol2CodeConverter.asRange(selectionRange.range), + kind: selectionRange.kind }; }); - } - return []; - })); + }); + } + return []; } })); }); diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 64fe111d64b..e44dc9f7102 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -176,7 +176,7 @@ }, "dependencies": { "vscode-extension-telemetry": "0.1.1", - "vscode-languageclient": "^5.1.0", + "vscode-languageclient": "^5.2.1", "vscode-nls": "^4.0.0" }, "devDependencies": { diff --git a/extensions/html-language-features/server/build/filesFillIn.js b/extensions/html-language-features/server/build/filesFillIn.js deleted file mode 100644 index 906617384e0..00000000000 --- a/extensions/html-language-features/server/build/filesFillIn.js +++ /dev/null @@ -1,5 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -module.exports = {}; \ No newline at end of file diff --git a/extensions/html-language-features/server/extension.webpack.config.js b/extensions/html-language-features/server/extension.webpack.config.js index a535ddeae9a..77b86e718b1 100644 --- a/extensions/html-language-features/server/extension.webpack.config.js +++ b/extensions/html-language-features/server/extension.webpack.config.js @@ -9,7 +9,6 @@ const withDefaults = require('../../shared.webpack.config'); const path = require('path'); -var webpack = require('webpack'); module.exports = withDefaults({ context: path.join(__dirname), @@ -22,12 +21,5 @@ module.exports = withDefaults({ }, externals: { 'typescript': 'commonjs typescript' - }, - plugins: [ - new webpack.NormalModuleReplacementPlugin( - /[/\\]vscode-languageserver[/\\]lib[/\\]files\.js/, - require.resolve('./build/filesFillIn') - ), - new webpack.IgnorePlugin(/vertx/) - ], + } }); diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index bfc23ebe0bc..b01c03a3f15 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -9,10 +9,10 @@ }, "main": "./out/htmlServerMain", "dependencies": { - "vscode-css-languageservice": "^3.0.13-next.10", - "vscode-html-languageservice": "^2.1.11", - "vscode-languageserver": "^5.1.0", - "vscode-languageserver-types": "^3.13.0", + "vscode-css-languageservice": "^4.0.0-next.3", + "vscode-html-languageservice": "^3.0.0-next.3", + "vscode-languageserver": "^5.3.0-next.2", + "vscode-languageserver-types": "^3.14.0", "vscode-nls": "^4.0.0", "vscode-uri": "^1.0.6" }, diff --git a/extensions/html-language-features/server/src/customData.ts b/extensions/html-language-features/server/src/customData.ts index 673e4a4ab9d..1d550eddf9f 100644 --- a/extensions/html-language-features/server/src/customData.ts +++ b/extensions/html-language-features/server/src/customData.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IHTMLDataProvider, HTMLDataProvider } from 'vscode-html-languageservice'; +import { IHTMLDataProvider, newHTMLDataProvider } from 'vscode-html-languageservice'; import * as fs from 'fs'; export function getDataProviders(dataPaths?: string[]): IHTMLDataProvider[] { @@ -18,7 +18,7 @@ export function getDataProviders(dataPaths?: string[]): IHTMLDataProvider[] { if (fs.existsSync(path)) { const htmlData = JSON.parse(fs.readFileSync(path, 'utf-8')); - providers.push(new HTMLDataProvider(`customProvider${i}`, htmlData)); + providers.push(newHTMLDataProvider(`customProvider${i}`, htmlData)); } } catch (err) { console.log(`Failed to load tag from ${path}`); diff --git a/extensions/html-language-features/server/src/htmlServerMain.ts b/extensions/html-language-features/server/src/htmlServerMain.ts index 43ae7d5070c..7974284bd77 100644 --- a/extensions/html-language-features/server/src/htmlServerMain.ts +++ b/extensions/html-language-features/server/src/htmlServerMain.ts @@ -455,15 +455,15 @@ connection.onFoldingRanges((params, token) => { }, null, `Error while computing folding regions for ${params.textDocument.uri}`, token); }); -connection.onRequest('$/textDocument/selectionRange', async (params, token) => { +connection.onRequest('$/textDocument/selectionRanges', async (params, token) => { return runSafe(() => { const document = documents.get(params.textDocument.uri); - const position: Position = params.position; + const positions: Position[] = params.positions; if (document) { const htmlMode = languageModes.getMode('html'); - if (htmlMode && htmlMode.doSelection) { - return htmlMode.doSelection(document, position); + if (htmlMode && htmlMode.getSelectionRanges) { + return htmlMode.getSelectionRanges(document, positions); } } return Promise.resolve(null); diff --git a/extensions/html-language-features/server/src/modes/htmlMode.ts b/extensions/html-language-features/server/src/modes/htmlMode.ts index 00a690f56eb..09efb996f6e 100644 --- a/extensions/html-language-features/server/src/modes/htmlMode.ts +++ b/extensions/html-language-features/server/src/modes/htmlMode.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { getLanguageModelCache } from '../languageModelCache'; -import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, HTMLFormatConfiguration } from 'vscode-html-languageservice'; +import { LanguageService as HTMLLanguageService, HTMLDocument, DocumentContext, FormattingOptions, HTMLFormatConfiguration, SelectionRange } from 'vscode-html-languageservice'; import { TextDocument, Position, Range, CompletionItem, FoldingRange } from 'vscode-languageserver-types'; import { LanguageMode, Workspace } from './languageModes'; import { getPathCompletionParticipant } from './pathCompletion'; @@ -15,8 +15,8 @@ export function getHTMLMode(htmlLanguageService: HTMLLanguageService, workspace: getId() { return 'html'; }, - doSelection(document: TextDocument, position: Position): Range[] { - return htmlLanguageService.getSelectionRanges(document, position); + getSelectionRanges(document: TextDocument, positions: Position[]): SelectionRange[][] { + return htmlLanguageService.getSelectionRanges(document, positions); }, doComplete(document: TextDocument, position: Position, settings = workspace.settings) { let options = settings && settings.html && settings.html.suggest; diff --git a/extensions/html-language-features/server/src/modes/languageModes.ts b/extensions/html-language-features/server/src/modes/languageModes.ts index 048076ed70d..94c0b04a293 100644 --- a/extensions/html-language-features/server/src/modes/languageModes.ts +++ b/extensions/html-language-features/server/src/modes/languageModes.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getLanguageService as getHTMLLanguageService, DocumentContext, IHTMLDataProvider } from 'vscode-html-languageservice'; +import { getLanguageService as getHTMLLanguageService, DocumentContext, IHTMLDataProvider, SelectionRange } from 'vscode-html-languageservice'; import { CompletionItem, Location, SignatureHelp, Definition, TextEdit, TextDocument, Diagnostic, DocumentLink, Range, Hover, DocumentHighlight, CompletionList, Position, FormattingOptions, SymbolInformation, FoldingRange @@ -31,7 +31,7 @@ export interface Workspace { export interface LanguageMode { getId(): string; - doSelection?: (document: TextDocument, position: Position) => Range[]; + getSelectionRanges?: (document: TextDocument, positions: Position[]) => SelectionRange[][]; doValidation?: (document: TextDocument, settings?: Settings) => Diagnostic[]; doComplete?: (document: TextDocument, position: Position, settings?: Settings) => CompletionList; doResolve?: (document: TextDocument, item: CompletionItem) => CompletionItem; diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index 5173fd2b003..79eeb0196cb 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -229,20 +229,20 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -vscode-css-languageservice@^3.0.13-next.10: - version "3.0.13-next.10" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.13-next.10.tgz#f5822e832b06e1e91ec96c528bab83bb07251c35" - integrity sha512-zKwzo3GVhrAllYDM4afL8q1XCHixsI8tP3SyLrWGzp0Nc9P+bbjKQeC26VcaOb0dtkgfpB/vfBPf+4yOs4s/pw== +vscode-css-languageservice@^4.0.0-next.3: + version "4.0.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.0-next.3.tgz#e9529f3b4ddf95c9a3e5dc2a6d701a38280ffa98" + integrity sha512-/xmbWpIQLw+HZ/3LsaE2drHFSNJbM9mZ8bKR5NUiu2ZUr10WbGxX0j/GDZB3LlMmdSHQGgRQ5hTM/Ic2PuBDRw== dependencies: - vscode-languageserver-types "^3.13.0" + vscode-languageserver-types "^3.14.0" vscode-nls "^4.0.0" -vscode-html-languageservice@^2.1.11: - version "2.1.11" - resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.1.11.tgz#56fc25cf64793a9eaef2f571a0ecd591eaed26c1" - integrity sha512-wfENgWb7JjEhwsRHXhairumuxAGnFcMUwIut5P7SxGwNrJMDXkgfs6OUBZycQpbaXTkMEvwsKNKFqUQppW7P4g== +vscode-html-languageservice@^3.0.0-next.3: + version "3.0.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.0-next.3.tgz#a0230c57375deb21fadbfa0210a770ca6e06d425" + integrity sha512-vPdZ17JSr8kAAnjNjdiH4jYySaJrXqnbT3OhnGXqc51R3jnwMXV/Jf72ctXptbpiUQM3ifHnfUcxwO+34tw6Lw== dependencies: - vscode-languageserver-types "^3.13.0" + vscode-languageserver-types "^3.14.0" vscode-nls "^4.0.0" vscode-uri "^1.0.6" @@ -251,25 +251,25 @@ vscode-jsonrpc@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== -vscode-languageserver-protocol@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.13.0.tgz#710d8e42119bb3affb1416e1e104bd6b4d503595" - integrity sha512-2ZGKwI+P2ovQll2PGAp+2UfJH+FK9eait86VBUdkPd9HRlm8e58aYT9pV/NYanHOcp3pL6x2yTLVCFMcTer0mg== +vscode-languageserver-protocol@3.15.0-next.1: + version "3.15.0-next.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.1.tgz#1e45e224d7eef8c79b4bed75b9dcb1930d2ab8ed" + integrity sha512-LXF0d9s3vxFBxVQ4aKl/XghdEMAncGt3dh4urIYa9Is43g3MfIQL9fC44YZtP+XXOrI2rpZU8lRNN01U1V6CDg== dependencies: vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.13.0" + vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.13.0, vscode-languageserver-types@^3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" - integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== +vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== -vscode-languageserver@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.1.0.tgz#012a28f154cc7a848c443d217894942e4c3eeb39" - integrity sha512-CIsrgx2Y5VHS317g/HwkSTWYBIQmy0DwEyZPmB2pEpVOhYFwVsYpbiJwHIIyLQsQtmRaO4eA2xM8KPjNSdXpBw== +vscode-languageserver@^5.3.0-next.2: + version "5.3.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.3.0-next.2.tgz#31ce4c34d68b517b400ca9e211e43f8d868b8dcc" + integrity sha512-n5onRw9naMrRHp2jnOn+ZwN1n+tTfzftWLPonjp1FWf/iCZWIlnw2TyF/Hn+SDGhLoVtoghmxhwEQaxEAfLHvw== dependencies: - vscode-languageserver-protocol "3.13.0" + vscode-languageserver-protocol "3.15.0-next.1" vscode-uri "^1.0.6" vscode-nls@^4.0.0: diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 2737f409efa..a0667775d59 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -45,26 +45,26 @@ vscode-jsonrpc@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== -vscode-languageclient@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.1.0.tgz#650ab0dc9fd0daaade058a8471aaff5bc3f9580e" - integrity sha512-Z95Kps8UqD4o17HE3uCkZuvenOsxHVH46dKmaGVpGixEFZigPaVuVxLM/JWeIY9aRenoC0ZD9CK1O7L4jpffKg== +vscode-languageclient@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193" + integrity sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q== dependencies: semver "^5.5.0" - vscode-languageserver-protocol "3.13.0" + vscode-languageserver-protocol "3.14.1" -vscode-languageserver-protocol@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.13.0.tgz#710d8e42119bb3affb1416e1e104bd6b4d503595" - integrity sha512-2ZGKwI+P2ovQll2PGAp+2UfJH+FK9eait86VBUdkPd9HRlm8e58aYT9pV/NYanHOcp3pL6x2yTLVCFMcTer0mg== +vscode-languageserver-protocol@3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f" + integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g== dependencies: vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.13.0" + vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" - integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== +vscode-languageserver-types@3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== vscode-nls@^4.0.0: version "4.0.0" From ce3f0c17d7cce900a9c6ab9053f981809e1dcd95 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 5 Mar 2019 15:27:46 +0100 Subject: [PATCH 197/290] [json] update service (webpack) --- .../json-language-features/package.json | 4 +- .../server/build/filesFillIn.js | 5 -- .../server/extension.webpack.config.js | 4 -- .../server/package.json | 6 +-- .../json-language-features/server/yarn.lock | 48 +++++++++---------- extensions/json-language-features/yarn.lock | 28 +++++------ 6 files changed, 43 insertions(+), 52 deletions(-) delete mode 100644 extensions/json-language-features/server/build/filesFillIn.js diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 47d1f7bf32d..4cd6d425a76 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -102,10 +102,10 @@ }, "dependencies": { "vscode-extension-telemetry": "0.1.1", - "vscode-languageclient": "^5.1.0", + "vscode-languageclient": "^5.2.1", "vscode-nls": "^4.0.0" }, "devDependencies": { "@types/node": "^10.12.21" } -} \ No newline at end of file +} diff --git a/extensions/json-language-features/server/build/filesFillIn.js b/extensions/json-language-features/server/build/filesFillIn.js deleted file mode 100644 index 906617384e0..00000000000 --- a/extensions/json-language-features/server/build/filesFillIn.js +++ /dev/null @@ -1,5 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -module.exports = {}; \ No newline at end of file diff --git a/extensions/json-language-features/server/extension.webpack.config.js b/extensions/json-language-features/server/extension.webpack.config.js index b31abe55f25..9c605f6b5ae 100644 --- a/extensions/json-language-features/server/extension.webpack.config.js +++ b/extensions/json-language-features/server/extension.webpack.config.js @@ -21,10 +21,6 @@ module.exports = withDefaults({ path: path.join(__dirname, 'dist') }, plugins: [ - new webpack.NormalModuleReplacementPlugin( - /[/\\]vscode-languageserver[/\\]lib[/\\]files\.js/, - require.resolve('./build/filesFillIn') - ), new webpack.IgnorePlugin(/vertx/) ], }); diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index 959af9a9794..fc2323a773e 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -12,10 +12,10 @@ }, "main": "./out/jsonServerMain", "dependencies": { - "jsonc-parser": "^2.0.2", + "jsonc-parser": "^2.0.3", "request-light": "^0.2.4", - "vscode-json-languageservice": "^3.3.0-next.4", - "vscode-languageserver": "^5.1.0", + "vscode-json-languageservice": "^3.3.0-next.6", + "vscode-languageserver": "^5.3.0-next.2", "vscode-nls": "^4.0.0", "vscode-uri": "^1.0.6" }, diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index 7a974ff4a2b..bb8489b6d86 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -54,10 +54,10 @@ https-proxy-agent@^2.2.1: agent-base "^4.1.0" debug "^3.1.0" -jsonc-parser@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.2.tgz#42fcf56d70852a043fadafde51ddb4a85649978d" - integrity sha512-TSU435K5tEKh3g7bam1AFf+uZrISheoDsLlpmAo6wWZYqjsnd09lHYK1Qo+moK4Ikifev1Gdpa69g4NELKnCrQ== +jsonc-parser@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.0.3.tgz#6d4199ccab7f21ff5d2a4225050c54e981fb21a2" + integrity sha512-WJi9y9ABL01C8CxTKxRRQkkSpY/x2bo4Gy0WuiZGrInxQqgxQpvkBCLNcDYcHOSdhx4ODgbFcgAvfL49C+PHgQ== ms@2.0.0: version "2.0.0" @@ -73,13 +73,13 @@ request-light@^0.2.4: https-proxy-agent "^2.2.1" vscode-nls "^4.0.0" -vscode-json-languageservice@^3.3.0-next.4: - version "3.3.0-next.4" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.0-next.4.tgz#e13b2fd5665b754ee94608a506407cd12b63d64d" - integrity sha512-tD8w2SvwERj3392q34xXKA/i76WWK7YwmP9eoLdKvdfMRwXB7a0MYWPoYZD4HycwvavAlbJ2x18vP4G7+BFA+A== +vscode-json-languageservice@^3.3.0-next.6: + version "3.3.0-next.6" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.3.0-next.6.tgz#711f121b44ba443a89f3fb01a01c611f2547079f" + integrity sha512-i1tyLiodWc7y6lR9C4cat+OUSptj8Duk1Ybm1FaMzhNfOTFttSiwrBw1otNb+QwI65VEj7EAEBQHRLeQOWznMw== dependencies: - jsonc-parser "^2.0.2" - vscode-languageserver-types "^3.13.0" + jsonc-parser "^2.0.3" + vscode-languageserver-types "^3.14.0" vscode-nls "^4.0.0" vscode-uri "^1.0.6" @@ -88,25 +88,25 @@ vscode-jsonrpc@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== -vscode-languageserver-protocol@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.13.0.tgz#710d8e42119bb3affb1416e1e104bd6b4d503595" - integrity sha512-2ZGKwI+P2ovQll2PGAp+2UfJH+FK9eait86VBUdkPd9HRlm8e58aYT9pV/NYanHOcp3pL6x2yTLVCFMcTer0mg== +vscode-languageserver-protocol@3.15.0-next.1: + version "3.15.0-next.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.0-next.1.tgz#1e45e224d7eef8c79b4bed75b9dcb1930d2ab8ed" + integrity sha512-LXF0d9s3vxFBxVQ4aKl/XghdEMAncGt3dh4urIYa9Is43g3MfIQL9fC44YZtP+XXOrI2rpZU8lRNN01U1V6CDg== dependencies: vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.13.0" + vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.13.0, vscode-languageserver-types@^3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" - integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== +vscode-languageserver-types@3.14.0, vscode-languageserver-types@^3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== -vscode-languageserver@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.1.0.tgz#012a28f154cc7a848c443d217894942e4c3eeb39" - integrity sha512-CIsrgx2Y5VHS317g/HwkSTWYBIQmy0DwEyZPmB2pEpVOhYFwVsYpbiJwHIIyLQsQtmRaO4eA2xM8KPjNSdXpBw== +vscode-languageserver@^5.3.0-next.2: + version "5.3.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-5.3.0-next.2.tgz#31ce4c34d68b517b400ca9e211e43f8d868b8dcc" + integrity sha512-n5onRw9naMrRHp2jnOn+ZwN1n+tTfzftWLPonjp1FWf/iCZWIlnw2TyF/Hn+SDGhLoVtoghmxhwEQaxEAfLHvw== dependencies: - vscode-languageserver-protocol "3.13.0" + vscode-languageserver-protocol "3.15.0-next.1" vscode-uri "^1.0.6" vscode-nls@^4.0.0: diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index e49fc01bd24..9315ad7e193 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -50,26 +50,26 @@ vscode-jsonrpc@^4.0.0: resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz#a7bf74ef3254d0a0c272fab15c82128e378b3be9" integrity sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg== -vscode-languageclient@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.1.0.tgz#650ab0dc9fd0daaade058a8471aaff5bc3f9580e" - integrity sha512-Z95Kps8UqD4o17HE3uCkZuvenOsxHVH46dKmaGVpGixEFZigPaVuVxLM/JWeIY9aRenoC0ZD9CK1O7L4jpffKg== +vscode-languageclient@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz#7cfc83a294c409f58cfa2b910a8cfeaad0397193" + integrity sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q== dependencies: semver "^5.5.0" - vscode-languageserver-protocol "3.13.0" + vscode-languageserver-protocol "3.14.1" -vscode-languageserver-protocol@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.13.0.tgz#710d8e42119bb3affb1416e1e104bd6b4d503595" - integrity sha512-2ZGKwI+P2ovQll2PGAp+2UfJH+FK9eait86VBUdkPd9HRlm8e58aYT9pV/NYanHOcp3pL6x2yTLVCFMcTer0mg== +vscode-languageserver-protocol@3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz#b8aab6afae2849c84a8983d39a1cf742417afe2f" + integrity sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g== dependencies: vscode-jsonrpc "^4.0.0" - vscode-languageserver-types "3.13.0" + vscode-languageserver-types "3.14.0" -vscode-languageserver-types@3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" - integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== +vscode-languageserver-types@3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz#d3b5952246d30e5241592b6dde8280e03942e743" + integrity sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A== vscode-nls@^4.0.0: version "4.0.0" From f0983abe97e10cacd98f27dc4c8f219eb857e8ce Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Mar 2019 15:39:36 +0100 Subject: [PATCH 198/290] Fix #69681 --- src/tsconfig.strictNullChecks.json | 1 + src/vs/workbench/common/editor.ts | 4 +- .../electron-browser/preferencesSearch.ts | 39 +----- .../preferences/browser/preferencesService.ts | 117 ++++++++++-------- .../preferences/common/preferences.ts | 16 +-- .../common/preferencesEditorInput.ts | 2 +- .../preferences/common/preferencesModels.ts | 75 +++++------ .../test/common/preferencesModel.test.ts | 10 +- 8 files changed, 130 insertions(+), 134 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 7bed7f931fe..9bdb62faf4d 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -28,6 +28,7 @@ "./vs/workbench/services/themes/**/*.ts", "./vs/workbench/services/bulkEdit/**/*.ts", "./vs/workbench/services/progress/**/*.ts", + "./vs/workbench/services/preferences/**/*.ts", "./vs/workbench/services/timer/**/*.ts" ], "files": [ diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 6a016bc91cc..eb745aa83fc 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -533,7 +533,7 @@ export class SideBySideEditorInput extends EditorInput { static readonly ID: string = 'workbench.editorinputs.sidebysideEditorInput'; - constructor(private name: string, private description: string, private _details: EditorInput, private _master: EditorInput) { + constructor(private name: string, private description: string | null, private _details: EditorInput, private _master: EditorInput) { super(); this.registerListeners(); @@ -602,7 +602,7 @@ export class SideBySideEditorInput extends EditorInput { return this.name; } - getDescription(): string { + getDescription(): string | null { return this.description; } diff --git a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts index 4edd06ce8e7..9c34a8343f5 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts @@ -23,6 +23,7 @@ import { IPreferencesSearchService, ISearchProvider, IWorkbenchSettingsConfigura import { CancellationToken } from 'vs/base/common/cancellation'; import { canceled } from 'vs/base/common/errors'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { nullRange } from 'vs/workbench/services/preferences/common/preferencesModels'; export interface IEndpointDetails { urlBase: string; @@ -426,12 +427,12 @@ function remoteSettingToISetting(remoteSetting: IRemoteSetting): IExtensionSetti return { description: remoteSetting.description.split('\n'), descriptionIsMarkdown: false, - descriptionRanges: null, + descriptionRanges: [], key: remoteSetting.key, - keyRange: null, + keyRange: nullRange, value: remoteSetting.defaultValue, - range: null, - valueRange: null, + range: nullRange, + valueRange: nullRange, overrides: [], extensionName: remoteSetting.extensionName, extensionPublisher: remoteSetting.extensionPublisher @@ -536,16 +537,6 @@ class SettingMatches { } private toKeyRange(setting: ISetting, match: IMatch): IRange { - if (!setting.keyRange) { - // No source range? Return fake range, don't care - return { - startLineNumber: 0, - startColumn: 0, - endLineNumber: 0, - endColumn: 0, - }; - } - return { startLineNumber: setting.keyRange.startLineNumber, startColumn: setting.keyRange.startColumn + match.start, @@ -555,16 +546,6 @@ class SettingMatches { } private toDescriptionRange(setting: ISetting, match: IMatch, lineIndex: number): IRange { - if (!setting.keyRange) { - // No source range? Return fake range, don't care - return { - startLineNumber: 0, - startColumn: 0, - endLineNumber: 0, - endColumn: 0, - }; - } - return { startLineNumber: setting.descriptionRanges[lineIndex].startLineNumber, startColumn: setting.descriptionRanges[lineIndex].startColumn + match.start, @@ -574,16 +555,6 @@ class SettingMatches { } private toValueRange(setting: ISetting, match: IMatch): IRange { - if (!setting.keyRange) { - // No source range? Return fake range, don't care - return { - startLineNumber: 0, - startColumn: 0, - endLineNumber: 0, - endColumn: 0, - }; - } - return { startLineNumber: setting.valueRange.startLineNumber, startColumn: setting.valueRange.startColumn + match.start + 1, diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index e5cd0c64ab7..744146bb756 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -89,10 +89,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic private readonly defaultSettingsRawResource = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/defaultSettings.json' }); get userSettingsResource(): URI { - return this.getEditableSettingsURI(ConfigurationTarget.USER); + return this.getEditableSettingsURI(ConfigurationTarget.USER)!; } - get workspaceSettingsResource(): URI { + get workspaceSettingsResource(): URI | null { return this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE); } @@ -100,11 +100,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.instantiationService.createInstance(SettingsEditor2Input); } - getFolderSettingsResource(resource: URI): URI { + getFolderSettingsResource(resource: URI): URI | null { return this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, resource); } - resolveModel(uri: URI): Promise { + resolveModel(uri: URI): Promise { if (this.isDefaultSettingsResource(uri)) { const target = this.getConfigurationTargetFromDefaultSettingsResource(uri); @@ -156,7 +156,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.createDefaultSettingsEditorModel(uri); } - if (this.getEditableSettingsURI(ConfigurationTarget.USER).toString() === uri.toString()) { + if (this.userSettingsResource.toString() === uri.toString()) { return this.createEditableSettingsEditorModel(ConfigurationTarget.USER, uri); } @@ -169,7 +169,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.createEditableSettingsEditorModel(ConfigurationTarget.WORKSPACE_FOLDER, uri); } - return Promise.resolve>(null); + return Promise.reject(`unknown resource: ${uri.toString()}`); } openRawDefaultSettings(): Promise { @@ -190,7 +190,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic } const editorInput = this.getActiveSettingsEditorInput() || this.lastOpenedSettingsInput; - const resource = editorInput ? editorInput.master.getResource() : this.userSettingsResource; + const resource = editorInput ? editorInput.master.getResource()! : this.userSettingsResource; const target = this.getConfigurationTargetFromSettingsResource(resource); return this.openOrSwitchSettings(target, resource); } @@ -198,7 +198,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic private openSettings2(): Promise { const input = this.settingsEditor2Input; return this.editorGroupService.activeGroup.openEditor(input) - .then(() => this.editorGroupService.activeGroup.activeControl); + .then(() => this.editorGroupService.activeGroup.activeControl!); } openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { @@ -211,14 +211,14 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.openOrSwitchSettings2(ConfigurationTarget.USER, undefined, options, group); } - openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; - if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) { + if (!this.workspaceSettingsResource) { this.notificationService.info(nls.localize('openFolderFirst', "Open a folder first to create workspace settings")); - return Promise.resolve(null); + return Promise.reject(null); } return jsonEditor ? @@ -230,22 +230,26 @@ export class PreferencesService extends Disposable implements IPreferencesServic jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; - - return jsonEditor ? - this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder), options, group) : - this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE_FOLDER, folder, options, group); + const folderSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder); + if (jsonEditor) { + if (folderSettingsUri) { + return this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, folderSettingsUri, options, group); + } + return Promise.reject(`Invalid folder URI - ${folder.toString()}`); + } + return this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE_FOLDER, folder, options, group); } switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): Promise { if (!jsonEditor) { - return this.doOpenSettings2(target, resource).then(() => null); + return this.doOpenSettings2(target, resource).then(() => undefined); } const activeControl = this.editorService.activeControl; if (activeControl && activeControl.input instanceof PreferencesEditorInput) { - return this.doSwitchSettings(target, resource, activeControl.input, activeControl.group).then(() => null); + return this.doSwitchSettings(target, resource, activeControl.input, activeControl.group).then(() => undefined); } else { - return this.doOpenSettings(target, resource).then(() => null); + return this.doOpenSettings(target, resource).then(() => undefined); } } @@ -276,7 +280,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } - return this.editorService.openEditor(this.instantiationService.createInstance(KeybindingsEditorInput), { pinned: true, revealIfOpened: true }).then(() => null); + return this.editorService.openEditor(this.instantiationService.createInstance(KeybindingsEditorInput), { pinned: true, revealIfOpened: true }).then(() => undefined); } openDefaultKeybindingsFile(): Promise { @@ -291,7 +295,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic if (codeEditor) { this.addLanguageOverrideEntry(language, settingsModel, codeEditor) .then(position => { - if (codeEditor) { + if (codeEditor && position) { codeEditor.setPosition(position); codeEditor.revealLine(position.lineNumber); codeEditor.focus(); @@ -303,8 +307,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic private openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { const editorInput = this.getActiveSettingsEditorInput(group); - if (editorInput && editorInput.master.getResource().fsPath !== resource.fsPath) { - return this.doSwitchSettings(configurationTarget, resource, editorInput, group, options); + if (editorInput) { + const editorInputResource = editorInput.master.getResource(); + if (editorInputResource && editorInputResource.fsPath !== resource.fsPath) { + return this.doSwitchSettings(configurationTarget, resource, editorInput, group, options); + } } return this.doOpenSettings(configurationTarget, resource, options, group); } @@ -335,7 +342,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return Promise.all([ this.editorService.openEditor({ resource: this.defaultSettingsRawResource, options: { pinned: true, preserveFocus: true, revealIfOpened: true }, label: nls.localize('defaultSettings', "Default Settings"), description: '' }), this.editorService.openEditor(editableSettingsEditorInput, { pinned: true, revealIfOpened: true }, sideEditorGroup.id) - ]).then(() => null); + ]).then(([defaultEditor, editor]) => editor); } else { return this.editorService.openEditor(editableSettingsEditorInput, SettingsEditorOptions.create(options), group); } @@ -374,7 +381,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic } private doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup, options?: ISettingsEditorOptions): Promise { - return this.getOrCreateEditableSettingsEditorInput(target, this.getEditableSettingsURI(target, resource)) + const settingsURI = this.getEditableSettingsURI(target, resource); + if (!settingsURI) { + return Promise.reject(`Invalid settings URI - ${resource.toString()}`); + } + return this.getOrCreateEditableSettingsEditorInput(target, settingsURI) .then(toInput => { return group.openEditor(input).then(() => { const replaceWith = new PreferencesEditorInput(this.getPreferencesEditorInputName(target, resource), toInput.getDescription(), this.instantiationService.createInstance(DefaultPreferencesEditorInput, this.getDefaultSettingsResource(target)), toInput); @@ -382,10 +393,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic return group.replaceEditors([{ editor: input, replacement: replaceWith, - options: SettingsEditorOptions.create(options) + options: options ? SettingsEditorOptions.create(options) : undefined }]).then(() => { this.lastOpenedSettingsInput = replaceWith; - return group.activeControl; + return group.activeControl!; }); }); }); @@ -464,7 +475,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.textModelResolverService.createModelReference(settingsUri) .then(reference => this.instantiationService.createInstance(SettingsEditorModel, reference, configurationTarget)); } - return Promise.resolve(null); + return Promise.reject(`unknown target: ${configurationTarget} and resource: ${resource.toString()}`); } private createDefaultSettingsEditorModel(defaultSettingsUri: URI): Promise { @@ -494,7 +505,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this._defaultUserSettingsContentModel; } - private getEditableSettingsURI(configurationTarget: ConfigurationTarget, resource?: URI): URI { + private getEditableSettingsURI(configurationTarget: ConfigurationTarget, resource?: URI): URI | null { switch (configurationTarget) { case ConfigurationTarget.USER: return URI.file(this.environmentService.appSettingsPath); @@ -505,8 +516,10 @@ export class PreferencesService extends Disposable implements IPreferencesServic const workspace = this.contextService.getWorkspace(); return workspace.configuration || workspace.folders[0].toResource(FOLDER_SETTINGS_PATH); case ConfigurationTarget.WORKSPACE_FOLDER: - const folder = this.contextService.getWorkspaceFolder(resource); - return folder ? folder.toResource(FOLDER_SETTINGS_PATH) : null; + if (resource) { + const folder = this.contextService.getWorkspaceFolder(resource); + return folder ? folder.toResource(FOLDER_SETTINGS_PATH) : null; + } } return null; } @@ -523,7 +536,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic if (Object.keys(parse(content.value)).indexOf('settings') === -1) { return this.jsonEditingService.write(resource, { key: 'settings', value: {} }, true).then(undefined, () => { }); } - return null; + return undefined; }); } return this.createIfNotExists(resource, emptyEditableSettingsContent).then(() => { }); @@ -557,29 +570,35 @@ export class PreferencesService extends Disposable implements IPreferencesServic ]; } - private addLanguageOverrideEntry(language: string, settingsModel: IPreferencesEditorModel, codeEditor: ICodeEditor): Promise { + private addLanguageOverrideEntry(language: string, settingsModel: IPreferencesEditorModel, codeEditor: ICodeEditor): Promise { const languageKey = `[${language}]`; let setting = settingsModel.getPreference(languageKey); const model = codeEditor.getModel(); - const configuration = this.configurationService.getValue<{ editor: { tabSize: number; insertSpaces: boolean } }>(); - const eol = model.getEOL(); - if (setting) { - if (setting.overrides.length) { - const lastSetting = setting.overrides[setting.overrides.length - 1]; - return Promise.resolve({ lineNumber: lastSetting.valueRange.endLineNumber, column: model.getLineMaxColumn(lastSetting.valueRange.endLineNumber) }); + if (model) { + const configuration = this.configurationService.getValue<{ editor: { tabSize: number; insertSpaces: boolean } }>(); + const eol = model.getEOL(); + if (setting) { + if (setting.overrides && setting.overrides.length) { + const lastSetting = setting.overrides[setting.overrides.length - 1]; + return Promise.resolve({ lineNumber: lastSetting.valueRange.endLineNumber, column: model.getLineMaxColumn(lastSetting.valueRange.endLineNumber) }); + } + return Promise.resolve({ lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.startColumn + 1 }); } - return Promise.resolve({ lineNumber: setting.valueRange.startLineNumber, column: setting.valueRange.startColumn + 1 }); + return this.configurationService.updateValue(languageKey, {}, ConfigurationTarget.USER) + .then(() => { + setting = settingsModel.getPreference(languageKey); + if (setting) { + let content = eol + this.spaces(2, configuration.editor) + eol + this.spaces(1, configuration.editor); + let editOperation = EditOperation.insert(new Position(setting.valueRange.endLineNumber, setting.valueRange.endColumn - 1), content); + model.pushEditOperations([], [editOperation], () => []); + let lineNumber = setting.valueRange.endLineNumber + 1; + settingsModel.dispose(); + return { lineNumber, column: model.getLineMaxColumn(lineNumber) }; + } + return null; + }); } - return this.configurationService.updateValue(languageKey, {}, ConfigurationTarget.USER) - .then(() => { - setting = settingsModel.getPreference(languageKey); - let content = eol + this.spaces(2, configuration.editor) + eol + this.spaces(1, configuration.editor); - let editOperation = EditOperation.insert(new Position(setting.valueRange.endLineNumber, setting.valueRange.endColumn - 1), content); - model.pushEditOperations([], [editOperation], () => []); - let lineNumber = setting.valueRange.endLineNumber + 1; - settingsModel.dispose(); - return { lineNumber, column: model.getLineMaxColumn(lineNumber) }; - }); + return Promise.resolve(null); } private spaces(count: number, { tabSize, insertSpaces }: { tabSize: number; insertSpaces: boolean }): string { diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 4bf2e5500f5..b1d1d0a4a99 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -53,7 +53,7 @@ export interface ISetting { value: any; valueRange: IRange; description: string[]; - descriptionIsMarkdown: boolean; + descriptionIsMarkdown?: boolean; descriptionRanges: IRange[]; overrides?: ISetting[]; overrideOf?: ISetting; @@ -65,7 +65,7 @@ export interface ISetting { enumDescriptions?: string[]; enumDescriptionsAreMarkdown?: boolean; tags?: string[]; - validator?: (value: any) => string; + validator?: (value: any) => string | null; } export interface IExtensionSetting extends ISetting { @@ -162,11 +162,7 @@ export class SettingsEditorOptions extends EditorOptions implements ISettingsEdi folderUri?: URI; query?: string; - static create(settings: ISettingsEditorOptions): SettingsEditorOptions | null { - if (!settings) { - return null; - } - + static create(settings: ISettingsEditorOptions): SettingsEditorOptions { const options = new SettingsEditorOptions(); options.target = settings.target; @@ -195,10 +191,10 @@ export interface IPreferencesService { _serviceBrand: any; userSettingsResource: URI; - workspaceSettingsResource: URI; - getFolderSettingsResource(resource: URI): URI; + workspaceSettingsResource: URI | null; + getFolderSettingsResource(resource: URI): URI | null; - resolveModel(uri: URI): Promise; + resolveModel(uri: URI): Promise; createPreferencesEditorModel(uri: URI): Promise>; createSettings2EditorModel(): Settings2EditorModel; // TODO diff --git a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts index 4929b15f8f9..e1db37ca23b 100644 --- a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts +++ b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts @@ -22,7 +22,7 @@ export class PreferencesEditorInput extends SideBySideEditorInput { return PreferencesEditorInput.ID; } - getTitle(verbosity: Verbosity): string { + getTitle(verbosity: Verbosity): string | null { return this.master.getTitle(verbosity); } } diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index f61324585e4..1c7936e9096 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -23,6 +23,9 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { EditorModel } from 'vs/workbench/common/editor'; import { IFilterMetadata, IFilterResult, IGroupFilter, IKeybindingsEditorModel, ISearchResultGroup, ISetting, ISettingMatch, ISettingMatcher, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +export const nullRange: IRange = { startLineNumber: -1, startColumn: -1, endLineNumber: -1, endColumn: -1 }; +export function isNullRange(range: IRange): boolean { return range.startLineNumber === -1 && range.startColumn === -1 && range.endLineNumber === -1 && range.endColumn === -1; } + export abstract class AbstractSettingsModel extends EditorModel { protected _currentResultGroups = new Map(); @@ -124,7 +127,7 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti constructor(reference: IReference, private _configurationTarget: ConfigurationTarget) { super(); - this.settingsModel = reference.object.textEditorModel; + this.settingsModel = reference.object.textEditorModel!; this._register(this.onDispose(() => reference.dispose())); this._register(this.settingsModel.onDidChangeContent(() => { this._settingsGroups = null; @@ -268,7 +271,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, } if (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null)) { // settings value started - const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting.overrides[overrideSetting.overrides.length - 1]; + const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting!.overrides![overrideSetting!.overrides!.length - 1]; if (setting) { const valueStartPosition = model.getPositionAt(offset); const valueEndPosition = model.getPositionAt(offset + length); @@ -288,7 +291,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, } const visitor: JSONVisitor = { onObjectBegin: (offset: number, length: number) => { - if (isSettingsProperty(currentProperty, previousParents)) { + if (isSettingsProperty(currentProperty!, previousParents)) { // Settings started settingsPropertyIndex = previousParents.length; const position = model.getPositionAt(offset); @@ -323,10 +326,10 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, endColumn: 0 }, value: null, - valueRange: null, - descriptionRanges: null, + valueRange: nullRange, + descriptionRanges: [], overrides: [], - overrideOf: overrideSetting + overrideOf: overrideSetting || undefined }; if (previousParents.length === settingsPropertyIndex + 1) { settings.push(setting); @@ -334,7 +337,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, overrideSetting = setting; } } else { - overrideSetting.overrides.push(setting); + overrideSetting!.overrides!.push(setting); } } }, @@ -342,7 +345,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, currentParent = previousParents.pop(); if (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null)) { // setting ended - const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting.overrides[overrideSetting.overrides.length - 1]; + const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting!.overrides![overrideSetting!.overrides!.length - 1]; if (setting) { const valueEndPosition = model.getPositionAt(offset + length); setting.valueRange = assign(setting.valueRange, { @@ -377,7 +380,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, currentParent = previousParents.pop(); if (previousParents.length === settingsPropertyIndex + 1 || (previousParents.length === settingsPropertyIndex + 2 && overrideSetting !== null)) { // setting value ended - const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting.overrides[overrideSetting.overrides.length - 1]; + const setting = previousParents.length === settingsPropertyIndex + 1 ? settings[settings.length - 1] : overrideSetting!.overrides![overrideSetting!.overrides!.length - 1]; if (setting) { const valueEndPosition = model.getPositionAt(offset + length); setting.valueRange = assign(setting.valueRange, { @@ -394,7 +397,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, onLiteralValue: onValue, onError: (error) => { const setting = settings[settings.length - 1]; - if (setting && (!setting.range || !setting.keyRange || !setting.valueRange)) { + if (setting && (isNullRange(setting.range) || isNullRange(setting.keyRange) || isNullRange(setting.valueRange))) { settings.pop(); } } @@ -408,8 +411,8 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, settings } ], - title: null, - titleRange: null, + title: '', + titleRange: nullRange, range }] : []; } @@ -514,13 +517,15 @@ export class DefaultSettings extends Disposable { description: setting.description, key: setting.key, value: setting.value, - range: null, - valueRange: null, + keyRange: nullRange, + range: nullRange, + valueRange: nullRange, overrides: [], scope: ConfigurationScope.RESOURCE, type: setting.type, enum: setting.enum, - enumDescriptions: setting.enumDescriptions + enumDescriptions: setting.enumDescriptions, + descriptionRanges: [] }; } return null; @@ -528,9 +533,9 @@ export class DefaultSettings extends Disposable { return { id: 'mostCommonlyUsed', - range: null, + range: nullRange, title: nls.localize('commonlyUsed', "Commonly Used"), - titleRange: null, + titleRange: nullRange, sections: [ { settings @@ -552,7 +557,7 @@ export class DefaultSettings extends Disposable { if (!settingsGroup) { settingsGroup = find(result, g => g.title === title); if (!settingsGroup) { - settingsGroup = { sections: [{ settings: [] }], id: config.id, title: title, titleRange: null, range: null, contributedByExtension: !!config.contributedByExtension }; + settingsGroup = { sections: [{ settings: [] }], id: config.id || '', title: title || '', titleRange: nullRange, range: nullRange, contributedByExtension: !!config.contributedByExtension }; result.push(settingsGroup); } } else { @@ -561,7 +566,7 @@ export class DefaultSettings extends Disposable { } if (config.properties) { if (!settingsGroup) { - settingsGroup = { sections: [{ settings: [] }], id: config.id, title: config.id, titleRange: null, range: null, contributedByExtension: !!config.contributedByExtension }; + settingsGroup = { sections: [{ settings: [] }], id: config.id || '', title: config.id || '', titleRange: nullRange, range: nullRange, contributedByExtension: !!config.contributedByExtension }; result.push(settingsGroup); } const configurationSettings: ISetting[] = []; @@ -605,9 +610,9 @@ export class DefaultSettings extends Disposable { value, description, descriptionIsMarkdown: !prop.description, - range: null, - keyRange: null, - valueRange: null, + range: nullRange, + keyRange: nullRange, + valueRange: nullRange, descriptionRanges: [], overrides, scope: prop.scope, @@ -630,9 +635,9 @@ export class DefaultSettings extends Disposable { value: overrideSettings[key], description: [], descriptionIsMarkdown: false, - range: null, - keyRange: null, - valueRange: null, + range: nullRange, + keyRange: nullRange, + valueRange: nullRange, descriptionRanges: [], overrides: [] })); @@ -691,7 +696,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements super(); this._register(defaultSettings.onDidChange(() => this._onDidChangeGroups.fire())); - this._model = reference.object.textEditorModel; + this._model = reference.object.textEditorModel!; this._register(this.onDispose(() => reference.dispose())); } @@ -712,7 +717,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements return this.settingsGroups.slice(1); } - protected update(): IFilterResult { + protected update(): IFilterResult | null { if (this._model.isDisposed()) { return null; } @@ -825,10 +830,10 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements overrideOf: setting.overrideOf, tags: setting.tags, deprecationMessage: setting.deprecationMessage, - keyRange: undefined, - valueRange: undefined, + keyRange: nullRange, + valueRange: nullRange, descriptionIsMarkdown: undefined, - descriptionRanges: undefined + descriptionRanges: [] }; } @@ -852,9 +857,9 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements private getGroup(resultGroup: ISearchResultGroup): ISettingsGroup { return { id: resultGroup.id, - range: null, + range: nullRange, title: resultGroup.label, - titleRange: null, + titleRange: nullRange, sections: [ { settings: resultGroup.result.filterMatches.map(m => this.copySetting(m.setting)) @@ -899,7 +904,7 @@ class SettingsContentBuilder { this._contentByLines.push('}'); } - protected _pushGroup(group: ISettingsGroup, indent: string): ISetting { + protected _pushGroup(group: ISettingsGroup, indent: string): ISetting | null { let lastSetting: ISetting | null = null; const groupStart = this.lineCountWithOffset + 1; for (const section of group.sections) { @@ -959,7 +964,7 @@ class SettingsContentBuilder { if (setting.enumDescriptions && setting.enumDescriptions.some(desc => !!desc)) { setting.enumDescriptions.forEach((desc, i) => { - const displayEnum = escapeInvisibleChars(String(setting.enum[i])); + const displayEnum = escapeInvisibleChars(String(setting.enum![i])); const line = desc ? `${displayEnum}: ${fixSettingLink(desc)}` : displayEnum; @@ -974,7 +979,7 @@ class SettingsContentBuilder { private pushValue(setting: ISetting, preValueConent: string, indent: string): void { const valueString = JSON.stringify(setting.value, null, indent); if (valueString && (typeof setting.value === 'object')) { - if (setting.overrides.length) { + if (setting.overrides && setting.overrides.length) { this._contentByLines.push(preValueConent + ' {'); for (const subSetting of setting.overrides) { this.pushSetting(subSetting, indent + indent); 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 d4dae17cbc3..c428209859a 100644 --- a/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts +++ b/src/vs/workbench/services/preferences/test/common/preferencesModel.test.ts @@ -10,7 +10,7 @@ import { IConfigurationPropertySchema } from 'vs/platform/configuration/common/c suite('Preferences Model test', () => { class Tester { - private validator: (value: any) => string; + private validator: (value: any) => string | null; constructor(private settings: IConfigurationPropertySchema) { this.validator = createValidator(settings)!; @@ -24,8 +24,12 @@ suite('Preferences Model test', () => { 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)}.`) + (message) => { + const actual = this.validator(input); + assert.ok(actual); + assert(actual!.indexOf(message) > -1, + `Expected error of ${JSON.stringify(this.settings)} on \`${input}\` to contain ${message}. Got ${this.validator(input)}.`); + } }; } From c6315a3d30771ff83bb6cf56528404859f25a9e4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 16:07:41 +0100 Subject: [PATCH 199/290] debt - more services cleanup --- src/vs/platform/lifecycle/common/lifecycle.ts | 2 +- .../workbench/electron-browser/workbench.ts | 88 ++++++++++--------- .../services/backup/node/backupFileService.ts | 67 +++++++++++++- .../backupFileService.test.ts | 22 ++++- src/vs/workbench/workbench.main.ts | 1 + 5 files changed, 134 insertions(+), 46 deletions(-) diff --git a/src/vs/platform/lifecycle/common/lifecycle.ts b/src/vs/platform/lifecycle/common/lifecycle.ts index 4879ee13e8d..18782a0d0b3 100644 --- a/src/vs/platform/lifecycle/common/lifecycle.ts +++ b/src/vs/platform/lifecycle/common/lifecycle.ts @@ -133,7 +133,7 @@ export interface ILifecycleService { /** * A flag indicating in what phase of the lifecycle we currently are. */ - readonly phase: LifecyclePhase; + phase: LifecyclePhase; /** * Fired before shutdown happens. Allows listeners to veto against the diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index b1e469d99db..0625ab7372a 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -105,8 +105,6 @@ import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; // import@node -import { BackupFileService, InMemoryBackupFileService } from 'vs/workbench/services/backup/node/backupFileService'; -import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; import { getDelayedChannel } from 'vs/base/parts/ipc/node/ipc'; import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net'; import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc'; @@ -190,13 +188,13 @@ export class Workbench extends Disposable implements IPartService { private editorService: EditorService; private editorGroupService: IEditorGroupsService; private contextViewService: ContextViewService; - private backupFileService: IBackupFileService; private windowService: IWindowService; - private lifecycleService: LifecycleService; + private lifecycleService: ILifecycleService; + private instantiationService: IInstantiationService; private contextService: IWorkspaceContextService; private storageService: IStorageService; - private configurationService: WorkspaceService; + private configurationService: IConfigurationService; private environmentService: IEnvironmentService; private logService: ILogService; private windowsService: IWindowsService; @@ -221,7 +219,7 @@ export class Workbench extends Disposable implements IPartService { @IInstantiationService instantiationService: IInstantiationService, @IWorkspaceContextService contextService: IWorkspaceContextService, @IStorageService storageService: IStorageService, - @IConfigurationService configurationService: WorkspaceService, + @IConfigurationService configurationService: IConfigurationService, @IEnvironmentService environmentService: IEnvironmentService, @ILogService logService: ILogService, @IWindowsService windowsService: IWindowsService @@ -333,7 +331,7 @@ export class Workbench extends Disposable implements IPartService { this.registerLayoutListeners(); // Layout State - this.initLayoutState(); + this.instantiationService.invokeFunction(accessor => this.initLayoutState(accessor)); // Render Workbench this.renderWorkbench(); @@ -525,14 +523,6 @@ export class Workbench extends Disposable implements IPartService { // History serviceCollection.set(IHistoryService, new SyncDescriptor(HistoryService)); - // Backup File Service - if (this.configuration.backupPath) { - this.backupFileService = this.instantiationService.createInstance(BackupFileService, this.configuration.backupPath); - } else { - this.backupFileService = new InMemoryBackupFileService(); - } - serviceCollection.set(IBackupFileService, this.backupFileService); - // Quick open service (quick open controller) this.quickOpen = this.instantiationService.createInstance(QuickOpenController); serviceCollection.set(IQuickOpenService, this.quickOpen); @@ -561,12 +551,20 @@ export class Workbench extends Disposable implements IPartService { this.instantiationService.invokeFunction(accessor => { const fileService = accessor.get(IFileService); const instantiationService = accessor.get(IInstantiationService); - const themeService = accessor.get(IWorkbenchThemeService) as WorkbenchThemeService; + const configurationService = accessor.get(IConfigurationService) as any; + const themeService = accessor.get(IWorkbenchThemeService) as any; - this.configurationService.acquireFileService(fileService); - this.configurationService.acquireInstantiationService(instantiationService); + if (typeof configurationService.acquireFileService === 'function') { + configurationService.acquireFileService(fileService); + } - themeService.acquireFileService(fileService); + if (typeof configurationService.acquireInstantiationService === 'function') { + configurationService.acquireInstantiationService(instantiationService); + } + + if (typeof themeService.acquireFileService === 'function') { + themeService.acquireFileService(fileService); + } }); } @@ -785,7 +783,7 @@ export class Workbench extends Disposable implements IPartService { } private whenStarted(accessor: ServicesAccessor, error?: Error): void { - const lifecycleService = accessor.get(ILifecycleService) as LifecycleService; + const lifecycleService = accessor.get(ILifecycleService); this.restored = true; @@ -1020,22 +1018,27 @@ export class Workbench extends Disposable implements IPartService { } } - private initLayoutState(): void { + private initLayoutState(accessor: ServicesAccessor): void { + const configurationService = accessor.get(IConfigurationService); + const storageService = accessor.get(IStorageService); + const lifecycleService = accessor.get(ILifecycleService); + const contextService = accessor.get(IWorkspaceContextService); + const environmentService = accessor.get(IEnvironmentService); // Fullscreen this.state.fullscreen = isFullscreen(); // Menubar visibility - this.state.menuBar.visibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); + this.state.menuBar.visibility = configurationService.getValue(Settings.MENUBAR_VISIBLE); // Activity bar visibility - this.state.activityBar.hidden = !this.configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); + this.state.activityBar.hidden = !configurationService.getValue(Settings.ACTIVITYBAR_VISIBLE); // Sidebar visibility - this.state.sideBar.hidden = this.storageService.getBoolean(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE, this.contextService.getWorkbenchState() === WorkbenchState.EMPTY); + this.state.sideBar.hidden = storageService.getBoolean(Storage.SIDEBAR_HIDDEN, StorageScope.WORKSPACE, contextService.getWorkbenchState() === WorkbenchState.EMPTY); // Sidebar position - this.state.sideBar.position = (this.configurationService.getValue(Settings.SIDEBAR_POSITION) === 'right') ? Position.RIGHT : Position.LEFT; + this.state.sideBar.position = (configurationService.getValue(Settings.SIDEBAR_POSITION) === 'right') ? Position.RIGHT : Position.LEFT; // Sidebar viewlet if (!this.state.sideBar.hidden) { @@ -1043,8 +1046,8 @@ export class Workbench extends Disposable implements IPartService { // Only restore last viewlet if window was reloaded or we are in development mode let viewletToRestore: string; - if (!this.environmentService.isBuilt || this.lifecycleService.startupKind === StartupKind.ReloadedWindow) { - viewletToRestore = this.storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE, viewletRegistry.getDefaultViewletId()); + if (!environmentService.isBuilt || lifecycleService.startupKind === StartupKind.ReloadedWindow) { + viewletToRestore = storageService.get(SidebarPart.activeViewletSettingsKey, StorageScope.WORKSPACE, viewletRegistry.getDefaultViewletId()); } else { viewletToRestore = viewletRegistry.getDefaultViewletId(); } @@ -1057,13 +1060,13 @@ export class Workbench extends Disposable implements IPartService { } // Editor centered layout - this.state.editor.restoreCentered = this.storageService.getBoolean(Storage.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false); + this.state.editor.restoreCentered = storageService.getBoolean(Storage.CENTERED_LAYOUT_ENABLED, StorageScope.WORKSPACE, false); // Editors to open - this.state.editor.editorsToOpen = this.resolveEditorsToOpen(); + this.state.editor.editorsToOpen = this.resolveEditorsToOpen(accessor); // Panel visibility - this.state.panel.hidden = this.storageService.getBoolean(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE, true); + this.state.panel.hidden = storageService.getBoolean(Storage.PANEL_HIDDEN, StorageScope.WORKSPACE, true); // Panel position this.updatePanelPosition(); @@ -1072,7 +1075,7 @@ export class Workbench extends Disposable implements IPartService { if (!this.state.panel.hidden) { const panelRegistry = Registry.as(PanelExtensions.Panels); - let panelToRestore = this.storageService.get(PanelPart.activePanelSettingsKey, StorageScope.WORKSPACE, panelRegistry.getDefaultPanelId()); + let panelToRestore = storageService.get(PanelPart.activePanelSettingsKey, StorageScope.WORKSPACE, panelRegistry.getDefaultPanelId()); if (!panelRegistry.hasPanel(panelToRestore)) { panelToRestore = panelRegistry.getDefaultPanelId(); // fallback to default if panel is unknown } @@ -1085,19 +1088,24 @@ export class Workbench extends Disposable implements IPartService { } // Statusbar visibility - this.state.statusBar.hidden = !this.configurationService.getValue(Settings.STATUSBAR_VISIBLE); + this.state.statusBar.hidden = !configurationService.getValue(Settings.STATUSBAR_VISIBLE); // Zen mode enablement - this.state.zenMode.restore = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false) && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); + this.state.zenMode.restore = storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false) && configurationService.getValue(Settings.ZEN_MODE_RESTORE); } - private resolveEditorsToOpen(): Promise | IResourceEditor[] { + private resolveEditorsToOpen(accessor: ServicesAccessor): Promise | IResourceEditor[] { + const configuration = accessor.get(IWindowService).getConfiguration(); + const configurationService = accessor.get(IConfigurationService); + const contextService = accessor.get(IWorkspaceContextService); + const editorGroupService = accessor.get(IEditorGroupsService); + const backupFileService = accessor.get(IBackupFileService); // Files to open, diff or create if (this.hasInitialFilesToOpen()) { // Files to diff is exclusive - const filesToDiff = this.toInputs(this.configuration.filesToDiff, false); + const filesToDiff = this.toInputs(configuration.filesToDiff, false); if (filesToDiff && filesToDiff.length === 2) { return [{ leftResource: filesToDiff[0].resource, @@ -1107,21 +1115,21 @@ export class Workbench extends Disposable implements IPartService { }]; } - const filesToCreate = this.toInputs(this.configuration.filesToCreate, true); - const filesToOpen = this.toInputs(this.configuration.filesToOpen, false); + const filesToCreate = this.toInputs(configuration.filesToCreate, true); + const filesToOpen = this.toInputs(configuration.filesToOpen, false); // Otherwise: Open/Create files return [...filesToOpen, ...filesToCreate]; } // Empty workbench - else if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY && this.configurationService.inspect('workbench.startupEditor').value === 'newUntitledFile') { - const isEmpty = this.editorGroupService.count === 1 && this.editorGroupService.activeGroup.count === 0; + else if (contextService.getWorkbenchState() === WorkbenchState.EMPTY && configurationService.inspect('workbench.startupEditor').value === 'newUntitledFile') { + const isEmpty = editorGroupService.count === 1 && editorGroupService.activeGroup.count === 0; if (!isEmpty) { return []; // do not open any empty untitled file if we restored editors from previous session } - return this.backupFileService.hasBackups().then(hasBackups => { + return backupFileService.hasBackups().then(hasBackups => { if (hasBackups) { return []; // do not open any empty untitled file if we have backups to restore } diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index a089102b7f9..5eb3e0402c5 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -15,6 +15,8 @@ import { ITextBufferFactory } from 'vs/editor/common/model'; import { createTextBufferFactoryFromStream, createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel'; import { keys } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export interface IBackupFilesModel { resolve(backupRoot: string): Promise; @@ -107,6 +109,63 @@ export class BackupFilesModel implements IBackupFilesModel { export class BackupFileService implements IBackupFileService { + _serviceBrand: any; + + private impl: IBackupFileService; + + constructor( + @IWindowService windowService: IWindowService, + @IFileService fileService: IFileService + ) { + const backupWorkspacePath = windowService.getConfiguration().backupPath; + if (backupWorkspacePath) { + this.impl = new BackupFileServiceImpl(backupWorkspacePath, fileService); + } else { + this.impl = new InMemoryBackupFileService(); + } + } + + initialize(backupWorkspacePath: string): void { + if (this.impl instanceof BackupFileServiceImpl) { + this.impl.initialize(backupWorkspacePath); + } + } + + hasBackups(): Promise { + return this.impl.hasBackups(); + } + + loadBackupResource(resource: Uri): Promise { + return this.impl.loadBackupResource(resource); + } + + backupResource(resource: Uri, content: ITextSnapshot, versionId?: number): Promise { + return this.impl.backupResource(resource, content, versionId); + } + + discardResourceBackup(resource: Uri): Promise { + return this.impl.discardResourceBackup(resource); + } + + discardAllWorkspaceBackups(): Promise { + return this.impl.discardAllWorkspaceBackups(); + } + + getWorkspaceFileBackups(): Promise { + return this.impl.getWorkspaceFileBackups(); + } + + resolveBackupContent(backup: Uri): Promise { + return this.impl.resolveBackupContent(backup); + } + + toBackupResource(resource: Uri): Uri { + return this.impl.toBackupResource(resource); + } +} + +class BackupFileServiceImpl implements IBackupFileService { + private static readonly META_MARKER = '\n'; _serviceBrand: any; @@ -170,7 +229,7 @@ export class BackupFileService implements IBackupFileService { } return this.ioOperationQueues.queueFor(backupResource).queue(() => { - const preamble = `${resource.toString()}${BackupFileService.META_MARKER}`; + const preamble = `${resource.toString()}${BackupFileServiceImpl.META_MARKER}`; // Update content with value return this.fileService.updateContent(backupResource, new BackupSnapshot(content, preamble), BACKUP_FILE_UPDATE_OPTIONS).then(() => model.add(backupResource, versionId)); @@ -202,7 +261,7 @@ export class BackupFileService implements IBackupFileService { model.get().forEach(fileBackup => { readPromises.push( - readToMatchingString(fileBackup.fsPath, BackupFileService.META_MARKER, 2000, 10000).then(Uri.parse) + readToMatchingString(fileBackup.fsPath, BackupFileServiceImpl.META_MARKER, 2000, 10000).then(Uri.parse) ); }); @@ -217,7 +276,7 @@ export class BackupFileService implements IBackupFileService { let metaFound = false; const metaPreambleFilter = (chunk: string) => { if (!metaFound && chunk) { - const metaIndex = chunk.indexOf(BackupFileService.META_MARKER); + const metaIndex = chunk.indexOf(BackupFileServiceImpl.META_MARKER); if (metaIndex === -1) { return ''; // meta not yet found, return empty string } @@ -302,3 +361,5 @@ export function hashPath(resource: Uri): string { const str = resource.scheme === Schemas.file ? resource.fsPath : resource.toString(); return crypto.createHash('md5').update(str).digest('hex'); } + +registerSingleton(IBackupFileService, BackupFileService); \ No newline at end of file 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 5f1ea987873..d2d9a82d2c2 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 @@ -13,7 +13,7 @@ import { URI as Uri } from 'vs/base/common/uri'; import { BackupFileService, BackupFilesModel, hashPath } from 'vs/workbench/services/backup/node/backupFileService'; import { FileService } from 'vs/workbench/services/files/node/fileService'; import { TextModel, createTextBufferFactory } from 'vs/editor/common/model/textModel'; -import { TestContextService, TestTextResourceConfigurationService, TestLifecycleService, TestEnvironmentService, TestStorageService } from 'vs/workbench/test/workbenchTestServices'; +import { TestContextService, TestTextResourceConfigurationService, TestLifecycleService, TestEnvironmentService, TestStorageService, TestWindowService } from 'vs/workbench/test/workbenchTestServices'; import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace'; @@ -21,6 +21,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { DefaultEndOfLine } from 'vs/editor/common/model'; import { snapshotToString } from 'vs/platform/files/common/files'; import { Schemas } from 'vs/base/common/network'; +import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'backupfileservice'); const backupHome = path.join(parentDir, 'Backups'); @@ -35,11 +36,28 @@ const fooBackupPath = path.join(workspaceBackupPath, 'file', hashPath(fooFile)); const barBackupPath = path.join(workspaceBackupPath, 'file', hashPath(barFile)); const untitledBackupPath = path.join(workspaceBackupPath, 'untitled', hashPath(untitledFile)); +class TestBackupWindowService extends TestWindowService { + + private config: IWindowConfiguration; + + constructor(workspaceBackupPath: string) { + super(); + + this.config = Object.create(null); + this.config.backupPath = workspaceBackupPath; + } + + getConfiguration(): IWindowConfiguration { + return this.config; + } +} + class TestBackupFileService extends BackupFileService { constructor(workspace: Uri, backupHome: string, workspacesJsonPath: string) { 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 }); + const windowService = new TestBackupWindowService(workspaceBackupPath); - super(workspaceBackupPath, fileService); + super(windowService, fileService); } public toBackupResource(resource: Uri): Uri { diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index ceffd2a8727..e06ec70c0b0 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -73,6 +73,7 @@ import 'vs/workbench/services/configuration/node/jsonEditingService'; import 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import 'vs/workbench/services/textfile/common/textFileService'; import 'vs/workbench/services/dialogs/electron-browser/dialogService'; +import 'vs/workbench/services/backup/node/backupFileService'; registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); From 849d9417eab3d8f85792070247bdc99247ce174a Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 5 Mar 2019 16:26:43 +0100 Subject: [PATCH 200/290] [json] fetch http and https schemas on the ext host --- .../client/src/jsonMain.ts | 24 +++++-- .../extension.webpack.config.js | 7 +- .../json-language-features/package.json | 3 +- .../server/extension.webpack.config.js | 4 +- extensions/json-language-features/yarn.lock | 68 +++++++++++++++++++ 5 files changed, 97 insertions(+), 9 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonMain.ts b/extensions/json-language-features/client/src/jsonMain.ts index 30b122071b1..ee52e73fc61 100644 --- a/extensions/json-language-features/client/src/jsonMain.ts +++ b/extensions/json-language-features/client/src/jsonMain.ts @@ -6,6 +6,8 @@ import * as path from 'path'; import * as fs from 'fs'; import * as nls from 'vscode-nls'; +import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light'; + const localize = nls.loadMessageBundle(); import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, Position, SelectionRange } from 'vscode'; @@ -93,6 +95,9 @@ export function activate(context: ExtensionContext) { let clientOptions: LanguageClientOptions = { // Register the server for json documents documentSelector, + initializationOptions: { + handledSchemaProtocols: ['file'] // language server only loads file-URI. Fetching schemas with other protocols ('http'...) are made on the client. + }, synchronize: { // Synchronize the setting section 'json' to the server configurationSection: ['json', 'http'], @@ -138,11 +143,20 @@ export function activate(context: ExtensionContext) { // handle content request client.onRequest(VSCodeContentRequest.type, (uriPath: string) => { let uri = Uri.parse(uriPath); - return workspace.openTextDocument(uri).then(doc => { - return doc.getText(); - }, error => { - return Promise.reject(error); - }); + if (uri.scheme !== 'http' && uri.scheme !== 'https') { + return workspace.openTextDocument(uri).then(doc => { + return doc.getText(); + }, error => { + return Promise.reject(error); + }); + } else { + const headers = { 'Accept-Encoding': 'gzip, deflate' }; + return xhr({ url: uriPath, followRedirects: 5, headers }).then(response => { + return response.responseText; + }, (error: XHRResponse) => { + return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString()); + }); + } }); let handleContentChange = (uri: Uri) => { diff --git a/extensions/json-language-features/extension.webpack.config.js b/extensions/json-language-features/extension.webpack.config.js index 4c2ab99cf25..bf887a3d0d8 100644 --- a/extensions/json-language-features/extension.webpack.config.js +++ b/extensions/json-language-features/extension.webpack.config.js @@ -9,6 +9,7 @@ const withDefaults = require('../shared.webpack.config'); const path = require('path'); +var webpack = require('webpack'); module.exports = withDefaults({ context: path.join(__dirname, 'client'), @@ -18,5 +19,9 @@ module.exports = withDefaults({ output: { filename: 'jsonMain.js', path: path.join(__dirname, 'client', 'dist') - } + }, + plugins: [ + new webpack.IgnorePlugin(/vertx/) // request-light dependendeny + ] + }); diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 4cd6d425a76..9dc4f87d9f0 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -103,7 +103,8 @@ "dependencies": { "vscode-extension-telemetry": "0.1.1", "vscode-languageclient": "^5.2.1", - "vscode-nls": "^4.0.0" + "vscode-nls": "^4.0.0", + "request-light": "^0.2.4" }, "devDependencies": { "@types/node": "^10.12.21" diff --git a/extensions/json-language-features/server/extension.webpack.config.js b/extensions/json-language-features/server/extension.webpack.config.js index 9c605f6b5ae..e6f4c516bc9 100644 --- a/extensions/json-language-features/server/extension.webpack.config.js +++ b/extensions/json-language-features/server/extension.webpack.config.js @@ -21,6 +21,6 @@ module.exports = withDefaults({ path: path.join(__dirname, 'dist') }, plugins: [ - new webpack.IgnorePlugin(/vertx/) - ], + new webpack.IgnorePlugin(/vertx/) // request-light dependendeny + ] }); diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 9315ad7e193..758f96fd511 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -7,6 +7,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.21.tgz#7e8a0c34cf29f4e17a36e9bd0ea72d45ba03908e" integrity sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ== +agent-base@4, agent-base@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + applicationinsights@1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5" @@ -16,6 +23,20 @@ applicationinsights@1.0.8: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + 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" @@ -28,6 +49,53 @@ diagnostic-channel@0.2.0: dependencies: semver "^5.3.0" +es6-promise@^4.0.3: + version "4.2.6" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f" + integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +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" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +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" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +request-light@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.4.tgz#3cea29c126682e6bcadf7915353322eeba01a755" + integrity sha512-pM9Fq5jRnSb+82V7M97rp8FE9/YNeP2L9eckB4Szd7lyeclSIx02aIpPO/6e4m6Dy31+FBN/zkFMTd2HkNO3ow== + dependencies: + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + vscode-nls "^4.0.0" + semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" From 66b45946a1ce68c0b4774d1772fb6707906b858d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 16:33:39 +0100 Subject: [PATCH 201/290] fix strict null --- src/vs/workbench/services/backup/node/backupFileService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index 5eb3e0402c5..396f9acb3ce 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -155,7 +155,7 @@ export class BackupFileService implements IBackupFileService { return this.impl.getWorkspaceFileBackups(); } - resolveBackupContent(backup: Uri): Promise { + resolveBackupContent(backup: Uri): Promise { return this.impl.resolveBackupContent(backup); } From a40b2ae4d87a4450471bfe7b6795180a7704b252 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 16:38:37 +0100 Subject: [PATCH 202/290] :lipstick: --- src/vs/workbench/services/backup/node/backupFileService.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/services/backup/node/backupFileService.ts b/src/vs/workbench/services/backup/node/backupFileService.ts index 396f9acb3ce..61fafbaa6f6 100644 --- a/src/vs/workbench/services/backup/node/backupFileService.ts +++ b/src/vs/workbench/services/backup/node/backupFileService.ts @@ -351,7 +351,6 @@ export class InMemoryBackupFileService implements IBackupFileService { toBackupResource(resource: Uri): Uri { return Uri.file(path.join(resource.scheme, hashPath(resource))); } - } /* From b5b811980f1b4f147b4fdea6a22b56359fe09783 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Mar 2019 15:59:59 +0100 Subject: [PATCH 203/290] Remove IWorkspaceConfigurationService --- .../api/electron-browser/mainThreadConfiguration.ts | 5 ++--- src/vs/workbench/browser/parts/editor/editorStatus.ts | 7 +++---- .../contrib/feedback/electron-browser/feedback.ts | 4 ++-- .../feedback/electron-browser/feedbackStatusbarItem.ts | 7 +++---- .../preferences/electron-browser/preferencesSearch.ts | 4 ++-- .../contrib/terminal/browser/terminalConfigHelper.ts | 3 +-- .../contrib/terminal/browser/terminalProcessManager.ts | 4 ++-- .../contrib/themes/browser/themes.contribution.ts | 7 +++---- .../electron-browser/actions/windowActions.ts | 10 +++++----- src/vs/workbench/electron-browser/window.ts | 4 ++-- .../services/configuration/common/configuration.ts | 8 -------- .../configuration/node/configurationService.ts | 6 +++--- .../test/electron-browser/configurationService.test.ts | 5 ++--- .../services/preferences/browser/preferencesService.ts | 5 ++--- .../services/workspace/node/workspaceEditingService.ts | 4 ++-- 15 files changed, 34 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts b/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts index 495b36864ad..4947445ffe3 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadConfiguration.ts @@ -8,10 +8,9 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope, getScopes } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { MainThreadConfigurationShape, MainContext, ExtHostContext, IExtHostContext, IWorkspaceConfigurationChangeEventData, IConfigurationInitData } from '../node/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; -import { ConfigurationTarget, IConfigurationChangeEvent, IConfigurationModel } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationChangeEvent, IConfigurationModel, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @extHostNamedCustomer(MainContext.MainThreadConfiguration) @@ -22,7 +21,7 @@ export class MainThreadConfiguration implements MainThreadConfigurationShape { constructor( extHostContext: IExtHostContext, @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, ) { const proxy = extHostContext.getProxy(ExtHostContext.ExtHostConfiguration); diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index a8542918815..cee38df5af8 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -26,7 +26,6 @@ import { BaseBinaryResourceEditor } from 'vs/workbench/browser/parts/editor/bina import { BinaryResourceDiffEditor } from 'vs/workbench/browser/parts/editor/binaryDiffEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; 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'; import { IModeService, ILanguageSelection } from 'vs/editor/common/services/modeService'; @@ -40,7 +39,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { IConfigurationChangedEvent, IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; -import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { deepClone } from 'vs/base/common/objects'; import { ICodeEditor, isCodeEditor, isDiffEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser'; import { Schemas } from 'vs/base/common/network'; @@ -293,7 +292,7 @@ export class EditorStatus implements IStatusbarItem { @IUntitledEditorService private readonly untitledEditorService: IUntitledEditorService, @IModeService private readonly modeService: IModeService, @ITextFileService private readonly textFileService: ITextFileService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @INotificationService private readonly notificationService: INotificationService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService ) { @@ -845,7 +844,7 @@ export class ChangeModeAction extends Action { @IModeService private readonly modeService: IModeService, @IModelService private readonly modelService: IModelService, @IEditorService private readonly editorService: IEditorService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @IQuickInputService private readonly quickInputService: IQuickInputService, @IPreferencesService private readonly preferencesService: IPreferencesService, @IInstantiationService private readonly instantiationService: IInstantiationService, diff --git a/src/vs/workbench/contrib/feedback/electron-browser/feedback.ts b/src/vs/workbench/contrib/feedback/electron-browser/feedback.ts index 9175a111ac2..51c206a57f7 100644 --- a/src/vs/workbench/contrib/feedback/electron-browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/electron-browser/feedback.ts @@ -15,10 +15,10 @@ import { IIntegrityService } from 'vs/workbench/services/integrity/common/integr import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { attachButtonStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { editorWidgetBackground, widgetShadow, inputBorder, inputForeground, inputBackground, inputActiveOptionBorder, editorBackground, buttonBackground, contrastBorder, darken } from 'vs/platform/theme/common/colorRegistry'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IAnchor } from 'vs/base/browser/ui/contextview/contextview'; import { Button } from 'vs/base/browser/ui/button/button'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export const FEEDBACK_VISIBLE_CONFIG = 'workbench.statusBar.feedback.visible'; @@ -66,7 +66,7 @@ export class FeedbackDropdown extends Dropdown { @ITelemetryService private readonly telemetryService: ITelemetryService, @IIntegrityService private readonly integrityService: IIntegrityService, @IThemeService private readonly themeService: IThemeService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(container, { contextViewProvider: options.contextViewProvider, diff --git a/src/vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts b/src/vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts index d03f6921014..7a904adc838 100644 --- a/src/vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts @@ -12,8 +12,7 @@ import product from 'vs/platform/product/node/product'; import { Themable, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_ITEM_HOVER_BACKGROUND } from 'vs/workbench/common/theme'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; 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 { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { clearNode, EventHelper, addClass, removeClass, addDisposableListener } from 'vs/base/browser/dom'; import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; @@ -62,7 +61,7 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem { @IContextViewService private readonly contextViewService: IContextViewService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IContextMenuService private readonly contextMenuService: IContextMenuService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @IThemeService themeService: IThemeService ) { super(themeService); @@ -155,7 +154,7 @@ export class FeedbackStatusbarItem extends Themable implements IStatusbarItem { class HideAction extends Action { constructor( - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super('feedback.hide', localize('hide', "Hide")); } diff --git a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts index 9c34a8343f5..c72c3d6c1ee 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts @@ -11,7 +11,6 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; import { IMatch, or, matchesContiguousSubString, matchesPrefix, matchesCamelCase, matchesWords } from 'vs/base/common/filters'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IRequestService } from 'vs/platform/request/node/request'; @@ -24,6 +23,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { canceled } from 'vs/base/common/errors'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { nullRange } from 'vs/workbench/services/preferences/common/preferencesModels'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export interface IEndpointDetails { urlBase: string; @@ -36,7 +36,7 @@ export class PreferencesSearchService extends Disposable implements IPreferences private _installedExtensions: Promise; constructor( - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IInstantiationService private readonly instantiationService: IInstantiationService, @IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, diff --git a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts index f4f0476caa0..506ceef0bf0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts @@ -8,7 +8,6 @@ import * as path from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; import { EDITOR_FONT_DEFAULTS, IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ITerminalConfiguration, ITerminalFont, IShellLaunchConfig, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, TERMINAL_CONFIG_SECTION, DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, MINIMUM_LETTER_SPACING, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import Severity from 'vs/base/common/severity'; @@ -33,7 +32,7 @@ export class TerminalConfigHelper implements IBrowserTerminalConfigHelper { public constructor( private readonly _linuxDistro: LinuxDistro, @IConfigurationService private readonly _configurationService: IConfigurationService, - @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly _workspaceConfigurationService: IConfigurationService, @INotificationService private readonly _notificationService: INotificationService, @IStorageService private readonly _storageService: IStorageService ) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 18d6d58d78b..432d886e99f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -18,10 +18,10 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { Schemas } from 'vs/base/common/network'; import { REMOTE_HOST_SCHEME, getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts'; import { sanitizeProcessEnvironment } from 'vs/base/common/processes'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IProductService } from 'vs/platform/product/common/product'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; /** The amount of time to consider terminal errors to be related to the launch */ const LAUNCHING_DURATION = 500; @@ -61,7 +61,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { @IWorkspaceContextService private readonly _workspaceContextService: IWorkspaceContextService, @IConfigurationResolverService private readonly _configurationResolverService: IConfigurationResolverService, @IWindowService private readonly _windowService: IWindowService, - @IWorkspaceConfigurationService private readonly _workspaceConfigurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly _workspaceConfigurationService: IConfigurationService, @IEnvironmentService private readonly _environmentService: IEnvironmentService, @IProductService private readonly _productService: IProductService, @ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService diff --git a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts index 47a9776b807..10167ea1196 100644 --- a/src/vs/workbench/contrib/themes/browser/themes.contribution.ts +++ b/src/vs/workbench/contrib/themes/browser/themes.contribution.ts @@ -15,11 +15,10 @@ import { VIEWLET_ID, IExtensionsViewlet } from 'vs/workbench/contrib/extensions/ import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { Delayer } from 'vs/base/common/async'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IColorRegistry, Extensions as ColorRegistryExtensions } from 'vs/platform/theme/common/colorRegistry'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { Color } from 'vs/base/common/color'; -import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { LIGHT, DARK, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService'; import { colorThemeSchemaId } from 'vs/workbench/services/themes/common/colorThemeSchema'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -37,7 +36,7 @@ export class SelectColorThemeAction extends Action { @IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService, @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, @IViewletService private readonly viewletService: IViewletService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(id, label); } @@ -98,7 +97,7 @@ class SelectIconThemeAction extends Action { @IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService, @IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService, @IViewletService private readonly viewletService: IViewletService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(id, label); diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index ef640150e1f..ea55154a0ad 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -10,7 +10,6 @@ import { Action } from 'vs/base/common/actions'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { isMacintosh } from 'vs/base/common/platform'; import * as browser from 'vs/base/browser/browser'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -27,6 +26,7 @@ import { getIconClasses } from 'vs/editor/common/services/getIconClasses'; import product from 'vs/platform/product/node/product'; import { ICommandHandler } from 'vs/platform/commands/common/commands'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class CloseCurrentWindowAction extends Action { @@ -82,7 +82,7 @@ export abstract class BaseZoomAction extends Action { constructor( id: string, label: string, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService ) { super(id, label); } @@ -111,7 +111,7 @@ export class ZoomInAction extends BaseZoomAction { constructor( id: string, label: string, - @IWorkspaceConfigurationService configurationService: IWorkspaceConfigurationService + @IConfigurationService configurationService: IConfigurationService ) { super(id, label, configurationService); } @@ -131,7 +131,7 @@ export class ZoomOutAction extends BaseZoomAction { constructor( id: string, label: string, - @IWorkspaceConfigurationService configurationService: IWorkspaceConfigurationService + @IConfigurationService configurationService: IConfigurationService ) { super(id, label, configurationService); } @@ -151,7 +151,7 @@ export class ZoomResetAction extends BaseZoomAction { constructor( id: string, label: string, - @IWorkspaceConfigurationService configurationService: IWorkspaceConfigurationService + @IConfigurationService configurationService: IConfigurationService ) { super(id, label, configurationService); } diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index acb68c8ad71..0ca278cc10b 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -14,7 +14,6 @@ import { IFileService } from 'vs/platform/files/common/files'; 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, IOpenFileRequest, IWindowsConfiguration, IAddFoldersRequest, IRunActionInWindowRequest, IPathData, IRunKeybindingInWindowRequest } from 'vs/platform/windows/common/windows'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; @@ -43,6 +42,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { coalesce } from 'vs/base/common/arrays'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; const TextInputActions: IAction[] = [ new Action('undo', nls.localize('undo', "Undo"), undefined, true, () => Promise.resolve(document.execCommand('undo'))), @@ -75,7 +75,7 @@ export class ElectronWindow extends Disposable { @IEditorService private readonly editorService: EditorServiceImpl, @IWindowsService private readonly windowsService: IWindowsService, @IWindowService private readonly windowService: IWindowService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @ITitleService private readonly titleService: ITitleService, @IWorkbenchThemeService protected themeService: IWorkbenchThemeService, @INotificationService private readonly notificationService: INotificationService, diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index 344bfa78905..ad2658aa60e 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -3,18 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; - export const FOLDER_CONFIG_FOLDER_NAME = '.vscode'; export const FOLDER_SETTINGS_NAME = 'settings'; export const FOLDER_SETTINGS_PATH = `${FOLDER_CONFIG_FOLDER_NAME}/${FOLDER_SETTINGS_NAME}.json`; -export const IWorkspaceConfigurationService = createDecorator('configurationService'); - -export interface IWorkspaceConfigurationService extends IConfigurationService { -} - export const defaultSettingsSchemaId = 'vscode://schemas/settings/default'; export const userSettingsSchemaId = 'vscode://schemas/settings/user'; export const workspaceSettingsSchemaId = 'vscode://schemas/settings/workspace'; diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index b71054c6318..61a17082dca 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -17,9 +17,9 @@ import { isLinux } from 'vs/base/common/platform'; import { IFileService } from 'vs/platform/files/common/files'; 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'; +import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels'; -import { IWorkspaceConfigurationService, FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationNode, IConfigurationRegistry, Extensions, IConfigurationPropertySchema, allSettings, windowSettings, resourceSettings, applicationSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; @@ -37,7 +37,7 @@ import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { Schemas } from 'vs/base/common/network'; -export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService { +export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { public _serviceBrand: any; 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 5e78dc69c52..d7e050e7a94 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -31,7 +31,6 @@ import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { JSONEditingService } from 'vs/workbench/services/configuration/node/jsonEditingService'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { createHash } from 'crypto'; import { Emitter, Event } from 'vs/base/common/event'; import { Schemas } from 'vs/base/common/network'; @@ -697,7 +696,7 @@ suite('WorkspaceService - Initialization', () => { suite('WorkspaceConfigurationService - Folder', () => { - let workspaceName = `testWorkspace${uuid.generateUuid()}`, parentResource: string, workspaceDir: string, testObject: IWorkspaceConfigurationService, globalSettingsFile: string; + let workspaceName = `testWorkspace${uuid.generateUuid()}`, parentResource: string, workspaceDir: string, testObject: IConfigurationService, globalSettingsFile: string; const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); suiteSetup(() => { @@ -983,7 +982,7 @@ suite('WorkspaceConfigurationService - Folder', () => { suite('WorkspaceConfigurationService-Multiroot', () => { - let parentResource: string, workspaceContextService: IWorkspaceContextService, environmentService: IEnvironmentService, jsonEditingServce: IJSONEditingService, testObject: IWorkspaceConfigurationService; + let parentResource: string, workspaceContextService: IWorkspaceContextService, environmentService: IEnvironmentService, jsonEditingServce: IJSONEditingService, testObject: IConfigurationService; const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); suiteSetup(() => { diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 744146bb756..8efc41d7c34 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -18,7 +18,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { IModeService } from 'vs/editor/common/services/modeService'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import * as nls from 'vs/nls'; -import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; @@ -29,7 +29,6 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { EditorInput, IEditor } from 'vs/workbench/common/editor'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { GroupDirection, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -59,7 +58,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic @IEditorService private readonly editorService: IEditorService, @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @IFileService private readonly fileService: IFileService, - @IWorkspaceConfigurationService private readonly configurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, @INotificationService private readonly notificationService: INotificationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IInstantiationService private readonly instantiationService: IInstantiationService, diff --git a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts index a1884b928a5..ac34d2b1ae2 100644 --- a/src/vs/workbench/services/workspace/node/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/node/workspaceEditingService.ts @@ -10,7 +10,6 @@ import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/ import { IWindowService, MessageBoxOptions, IWindowsService } from 'vs/platform/windows/common/windows'; import { IJSONEditingService, JSONEditingError, JSONEditingErrorCode } from 'vs/workbench/services/configuration/common/jsonEditing'; import { IWorkspaceIdentifier, IWorkspaceFolderCreationData, isWorkspaceIdentifier, toWorkspaceIdentifier, IWorkspacesService, rewriteWorkspaceFileForNewLocation } from 'vs/platform/workspaces/common/workspaces'; -import { IWorkspaceConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { WorkspaceService } from 'vs/workbench/services/configuration/node/configurationService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { StorageService } from 'vs/platform/storage/node/storageService'; @@ -27,6 +26,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { IFileService } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class WorkspaceEditingService implements IWorkspaceEditingService { @@ -36,7 +36,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, @IWorkspaceContextService private readonly contextService: WorkspaceService, @IWindowService private readonly windowService: IWindowService, - @IWorkspaceConfigurationService private readonly workspaceConfigurationService: IWorkspaceConfigurationService, + @IConfigurationService private readonly workspaceConfigurationService: IConfigurationService, @IStorageService private readonly storageService: IStorageService, @IExtensionService private readonly extensionService: IExtensionService, @IBackupFileService private readonly backupFileService: IBackupFileService, From fc277b039ba07ed734ee15b37869bd86f8ae1403 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 5 Mar 2019 16:56:01 +0100 Subject: [PATCH 204/290] Fix #69521 --- src/vs/workbench/browser/parts/compositeBarActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index 54c9a40efa7..6e59e616bcd 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -252,9 +252,9 @@ export class ActivityActionItem extends BaseActionItem { const noOfThousands = badge.number / 1000; const floor = Math.floor(noOfThousands); if (noOfThousands > floor) { - number = nls.localize('largeNumberBadge1', '{0}k+', floor); + number = `${floor}K+`; } else { - number = nls.localize('largeNumberBadge2', '{0}k', noOfThousands); + number = `${noOfThousands}K`; } } this.badgeContent.textContent = number; From bf9a27ec01f2ef82fc45f69e0c946c7d74a57d3e Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 5 Mar 2019 17:06:11 +0100 Subject: [PATCH 205/290] [Debug] Filter "Call Stack" panel based on thread state fixes #69793 --- src/vs/workbench/contrib/debug/common/debug.ts | 2 ++ src/vs/workbench/contrib/debug/common/debugModel.ts | 9 +++++++++ .../contrib/debug/electron-browser/callStackView.ts | 10 ++-------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 89c6088288c..e303532fc05 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -246,6 +246,8 @@ export interface IThread extends ITreeElement { */ readonly exceptionInfo: Promise; + readonly stateLabel: string; + /** * Gets the callstack if it has already been received from the debug * adapter, otherwise it returns null. diff --git a/src/vs/workbench/contrib/debug/common/debugModel.ts b/src/vs/workbench/contrib/debug/common/debugModel.ts index 36f80abb7f8..91422072397 100644 --- a/src/vs/workbench/contrib/debug/common/debugModel.ts +++ b/src/vs/workbench/contrib/debug/common/debugModel.ts @@ -418,6 +418,15 @@ export class Thread implements IThread { return this.staleCallStack; } + get stateLabel(): string { + if (this.stopped) { + return this.stoppedDetails.description || + this.stoppedDetails.reason ? nls.localize({ key: 'pausedOn', comment: ['indicates reason for program being paused'] }, "Paused on {0}", this.stoppedDetails.reason) : nls.localize('paused', "Paused"); + } + + return nls.localize({ key: 'running', comment: ['indicates state'] }, "Running"); + } + /** * Queries the debug adapter for the callstack and returns a promise * which completes once the call stack has been retrieved. diff --git a/src/vs/workbench/contrib/debug/electron-browser/callStackView.ts b/src/vs/workbench/contrib/debug/electron-browser/callStackView.ts index dc153ca4e0e..ff9c117f7e5 100644 --- a/src/vs/workbench/contrib/debug/electron-browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/electron-browser/callStackView.ts @@ -133,7 +133,7 @@ export class CallStackView extends ViewletPanel { return e.getLabel(); } if (e instanceof Thread) { - return e.name; + return `${e.name} ${e.stateLabel}`; } if (e instanceof StackFrame || typeof e === 'string') { return e; @@ -410,13 +410,7 @@ class ThreadsRenderer implements ITreeRenderer Date: Tue, 5 Mar 2019 18:17:47 +0100 Subject: [PATCH 206/290] fixes #68549 --- src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index 5137f89c2c5..fbb1c4db32f 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -410,7 +410,7 @@ export class BulkEditService implements IBulkEditService { } } - const bulkEdit = new BulkEdit(codeEditor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._labelService, this._configurationService); + const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._labelService, this._configurationService); bulkEdit.add(edits); return bulkEdit.perform().then(() => { From 2f0fdae41d44c1f87bf3b0877c625d170dfdba22 Mon Sep 17 00:00:00 2001 From: Adam Tajti Date: Tue, 5 Mar 2019 18:37:24 +0100 Subject: [PATCH 207/290] Cleanup: Remove duplicate configuration from outline.contribution.ts --- .../contrib/outline/browser/outline.contribution.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/workbench/contrib/outline/browser/outline.contribution.ts b/src/vs/workbench/contrib/outline/browser/outline.contribution.ts index a53f3eae4d7..7ac9a19b96f 100644 --- a/src/vs/workbench/contrib/outline/browser/outline.contribution.ts +++ b/src/vs/workbench/contrib/outline/browser/outline.contribution.ts @@ -41,11 +41,6 @@ Registry.as(ConfigurationExtensions.Configuration).regis 'type': 'boolean', 'default': true }, - [OutlineConfigKeys.problemsEnabled]: { - 'description': localize('outline.showProblem', "Show Errors & Warnings on Outline Elements."), - 'type': 'boolean', - 'default': true - }, [OutlineConfigKeys.problemsColors]: { 'description': localize('outline.problem.colors', "Use colors for Errors & Warnings."), 'type': 'boolean', From 1251a5094d8433ae6c081d86304f6910b3ab1e12 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 5 Mar 2019 18:39:12 +0100 Subject: [PATCH 208/290] Revert "fixes #68549" This reverts commit a3817504c42c073a8ff2ad2d87801ac8339e754d. --- src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index fbb1c4db32f..5137f89c2c5 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -410,7 +410,7 @@ export class BulkEditService implements IBulkEditService { } } - const bulkEdit = new BulkEdit(options.editor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._labelService, this._configurationService); + const bulkEdit = new BulkEdit(codeEditor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._labelService, this._configurationService); bulkEdit.add(edits); return bulkEdit.perform().then(() => { From 4a8d7b7080d7878718e94ad8b4132013f925e71f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 18:55:58 +0100 Subject: [PATCH 209/290] workbench - move restoreTimeoutHandle to a better place --- .../workbench/electron-browser/workbench.ts | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 0625ab7372a..bdeb9e52ede 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -189,7 +189,6 @@ export class Workbench extends Disposable implements IPartService { private editorGroupService: IEditorGroupsService; private contextViewService: ContextViewService; private windowService: IWindowService; - private lifecycleService: ILifecycleService; private instantiationService: IInstantiationService; private contextService: IWorkspaceContextService; @@ -342,10 +341,6 @@ export class Workbench extends Disposable implements IPartService { // Layout this.layout(); - // Handle case where workbench is not starting up properly - const timeoutHandle = setTimeout(() => this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.'), 10000); - this.lifecycleService.when(LifecyclePhase.Restored).then(() => clearTimeout(timeoutHandle)); - // Restore Parts let error: Error; return this.restoreParts() @@ -408,10 +403,10 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(ITelemetryService, telemetryService); // Lifecycle - this.lifecycleService = this.instantiationService.createInstance(LifecycleService); - serviceCollection.set(ILifecycleService, this.lifecycleService); - this._register(this.lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event))); - this._register(this.lifecycleService.onShutdown(() => { + const lifecycleService = this.instantiationService.createInstance(LifecycleService); + serviceCollection.set(ILifecycleService, lifecycleService); + this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event))); + this._register(lifecycleService.onShutdown(() => { this._onShutdown.fire(); this.dispose(); })); @@ -726,7 +721,7 @@ export class Workbench extends Disposable implements IPartService { registerNotificationCommands(this.notificationsCenter, this.notificationsToasts); } - private restoreParts(): Promise { + private restoreParts(): Promise { const restorePromises: Promise[] = []; // Restore editors @@ -779,7 +774,10 @@ export class Workbench extends Disposable implements IPartService { this.centerEditorLayout(true); } - return Promise.all(restorePromises); + // Emit a warning after 10s if restore does not complete + const restoreTimeoutHandle = setTimeout(() => this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.'), 10000); + + return Promise.all(restorePromises).then(() => clearTimeout(restoreTimeoutHandle)); } private whenStarted(accessor: ServicesAccessor, error?: Error): void { From 2f4ee72b2ac4c93640f04d07c12801d20e19fc88 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Mar 2019 18:58:50 +0100 Subject: [PATCH 210/290] :lipstick: --- src/vs/workbench/electron-browser/workbench.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index bdeb9e52ede..39de9310f86 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -341,11 +341,8 @@ export class Workbench extends Disposable implements IPartService { // Layout this.layout(); - // Restore Parts - let error: Error; - return this.restoreParts() - .catch(err => error = err) - .finally(() => this.instantiationService.invokeFunction(accessor => this.whenStarted(accessor, error))); + // Restore + return this.restoreWorkbench(); } private createWorkbenchContainer(): void { @@ -721,7 +718,7 @@ export class Workbench extends Disposable implements IPartService { registerNotificationCommands(this.notificationsCenter, this.notificationsToasts); } - private restoreParts(): Promise { + private restoreWorkbench(): Promise { const restorePromises: Promise[] = []; // Restore editors @@ -777,10 +774,15 @@ export class Workbench extends Disposable implements IPartService { // Emit a warning after 10s if restore does not complete const restoreTimeoutHandle = setTimeout(() => this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.'), 10000); - return Promise.all(restorePromises).then(() => clearTimeout(restoreTimeoutHandle)); + let error: Error; + return Promise.all(restorePromises) + .then(() => clearTimeout(restoreTimeoutHandle)) + .catch(err => error = err) + .finally(() => this.instantiationService.invokeFunction(accessor => this.whenRestored(accessor, error))); + } - private whenStarted(accessor: ServicesAccessor, error?: Error): void { + private whenRestored(accessor: ServicesAccessor, error?: Error): void { const lifecycleService = accessor.get(ILifecycleService); this.restored = true; From d52d4bb0fa3e7081b21e48a4e1c770af96efd3f8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 11:55:15 -0800 Subject: [PATCH 211/290] Strict null check untitledEditor --- src/tsconfig.strictNullChecks.json | 13 +++++++++++-- src/vs/base/common/mime.ts | 2 +- .../workbench/common/editor/untitledEditorInput.ts | 2 +- .../workbench/common/editor/untitledEditorModel.ts | 6 +++--- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 9bdb62faf4d..2a44a480baf 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -98,6 +98,7 @@ "./vs/workbench/browser/composite.ts", "./vs/workbench/browser/contextkeys.ts", "./vs/workbench/browser/editor.ts", + "./vs/workbench/browser/labels.ts", "./vs/workbench/browser/panel.ts", "./vs/workbench/browser/part.ts", "./vs/workbench/browser/parts/compositePart.ts", @@ -114,6 +115,7 @@ "./vs/workbench/browser/parts/editor/resourceViewer.ts", "./vs/workbench/browser/parts/editor/sideBySideEditor.ts", "./vs/workbench/browser/parts/editor/textEditor.ts", + "./vs/workbench/browser/parts/editor/textResourceEditor.ts", "./vs/workbench/browser/parts/quickinput/quickInputBox.ts", "./vs/workbench/browser/parts/quickinput/quickInputList.ts", "./vs/workbench/browser/parts/quickinput/quickInputUtils.ts", @@ -145,6 +147,8 @@ "./vs/workbench/common/editor/resourceEditorModel.ts", "./vs/workbench/common/editor/textDiffEditorModel.ts", "./vs/workbench/common/editor/textEditorModel.ts", + "./vs/workbench/common/editor/untitledEditorInput.ts", + "./vs/workbench/common/editor/untitledEditorModel.ts", "./vs/workbench/common/memento.ts", "./vs/workbench/common/notifications.ts", "./vs/workbench/common/panel.ts", @@ -206,11 +210,11 @@ "./vs/workbench/contrib/extensions/common/extensions.ts", "./vs/workbench/contrib/extensions/common/extensionsFileTemplate.ts", "./vs/workbench/contrib/extensions/common/extensionsInput.ts", + "./vs/workbench/contrib/extensions/common/extensionsUtils.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActivationProgress.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsList.ts", - "./vs/workbench/contrib/extensions/common/extensionsUtils.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts", "./vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput.ts", "./vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts", @@ -221,6 +225,7 @@ "./vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts", "./vs/workbench/contrib/files/browser/files.ts", "./vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts", + "./vs/workbench/contrib/files/common/dirtyFilesTracker.ts", "./vs/workbench/contrib/files/common/editors/fileEditorInput.ts", "./vs/workbench/contrib/files/common/explorerModel.ts", "./vs/workbench/contrib/files/common/explorerService.ts", @@ -240,6 +245,9 @@ "./vs/workbench/contrib/markers/browser/markersPanelActions.ts", "./vs/workbench/contrib/markers/browser/messages.ts", "./vs/workbench/contrib/markers/test/electron-browser/markersModel.test.ts", + "./vs/workbench/contrib/output/browser/logViewer.ts", + "./vs/workbench/contrib/output/browser/outputActions.ts", + "./vs/workbench/contrib/output/browser/outputPanel.ts", "./vs/workbench/contrib/output/common/output.ts", "./vs/workbench/contrib/output/common/outputLinkComputer.ts", "./vs/workbench/contrib/output/common/outputLinkProvider.ts", @@ -340,9 +348,9 @@ "./vs/workbench/services/extensions/electron-browser/extensionHostProfiler.ts", "./vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler.ts", "./vs/workbench/services/extensions/node/extensionDescriptionRegistry.ts", + "./vs/workbench/services/extensions/node/extensionHostProtocol.ts", "./vs/workbench/services/extensions/node/extensionManagementServerService.ts", "./vs/workbench/services/extensions/node/extensionPoints.ts", - "./vs/workbench/services/extensions/node/extensionHostProtocol.ts", "./vs/workbench/services/extensions/node/lazyPromise.ts", "./vs/workbench/services/extensions/node/proxyIdentifier.ts", "./vs/workbench/services/extensions/node/rpcProtocol.ts", @@ -410,6 +418,7 @@ "./vs/workbench/services/textfile/common/textfiles.ts", "./vs/workbench/services/textfile/node/textResourcePropertiesService.ts", "./vs/workbench/services/title/common/titleService.ts", + "./vs/workbench/services/untitled/common/untitledEditorService.ts", "./vs/workbench/services/viewlet/browser/viewlet.ts", "./vs/workbench/services/workspace/common/workspaceEditing.ts", "./vs/workbench/test/browser/actionRegistry.test.ts", diff --git a/src/vs/base/common/mime.ts b/src/vs/base/common/mime.ts index 10ab55362b1..de19c7c03f8 100644 --- a/src/vs/base/common/mime.ts +++ b/src/vs/base/common/mime.ts @@ -230,7 +230,7 @@ export function isUnspecific(mime: string[] | string): boolean { * 2. Otherwise, if there are other extensions, suggest the first one. * 3. Otherwise, suggest the prefix. */ -export function suggestFilename(langId: string, prefix: string): string { +export function suggestFilename(langId: string | null, prefix: string): string { const extensions = registeredAssociations .filter(assoc => !assoc.userConfigured && assoc.extension && assoc.id === langId) .map(assoc => assoc.extension); diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index a4fe328d79d..9d3ebed0a01 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -63,7 +63,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport return this.resource; } - getModeId(): string { + getModeId(): string | null { if (this.cachedModel) { return this.cachedModel.getModeId(); } diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index 4d14923cc3f..a19c5e64cf2 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -90,7 +90,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin return this.versionId; } - getModeId(): string { + getModeId(): string | null { if (this.textEditorModel) { return this.textEditorModel.getLanguageIdentifier().language; } @@ -139,7 +139,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin load(): Promise { // Check for backups first - return this.backupFileService.loadBackupResource(this.resource).then(backupResource => { + return this.backupFileService.loadBackupResource(this.resource).then((backupResource) => { if (backupResource) { return this.backupFileService.resolveBackupContent(backupResource); } @@ -193,7 +193,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin // mark the untitled editor as non-dirty once its content becomes empty and we do // not have an associated path set. we never want dirty indicator in that case. - if (!this._hasAssociatedFilePath && this.textEditorModel.getLineCount() === 1 && this.textEditorModel.getLineContent(1) === '') { + if (!this._hasAssociatedFilePath && this.textEditorModel && this.textEditorModel.getLineCount() === 1 && this.textEditorModel.getLineContent(1) === '') { this.setDirty(false); } From 314564c5910575ca44131911c1dd3ad8a3c0e39e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 12:00:17 -0800 Subject: [PATCH 212/290] Strict null check diffEditorModel --- src/tsconfig.strictNullChecks.json | 2 ++ .../common/editor/diffEditorModel.ts | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 2a44a480baf..306f8343f65 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -141,6 +141,7 @@ "./vs/workbench/common/editor.ts", "./vs/workbench/common/editor/binaryEditorModel.ts", "./vs/workbench/common/editor/dataUriEditorInput.ts", + "./vs/workbench/common/editor/diffEditorInput.ts", "./vs/workbench/common/editor/diffEditorModel.ts", "./vs/workbench/common/editor/editorGroup.ts", "./vs/workbench/common/editor/resourceEditorInput.ts", @@ -251,6 +252,7 @@ "./vs/workbench/contrib/output/common/output.ts", "./vs/workbench/contrib/output/common/outputLinkComputer.ts", "./vs/workbench/contrib/output/common/outputLinkProvider.ts", + "./vs/workbench/contrib/output/electron-browser/outputServices.ts", "./vs/workbench/contrib/output/node/outputAppender.ts", "./vs/workbench/contrib/preferences/browser/settingsWidgets.ts", "./vs/workbench/contrib/preferences/common/smartSnippetInserter.ts", diff --git a/src/vs/workbench/common/editor/diffEditorModel.ts b/src/vs/workbench/common/editor/diffEditorModel.ts index 794afd369d5..8405f386269 100644 --- a/src/vs/workbench/common/editor/diffEditorModel.ts +++ b/src/vs/workbench/common/editor/diffEditorModel.ts @@ -11,33 +11,39 @@ import { IEditorModel } from 'vs/platform/editor/common/editor'; * and the modified version. */ export class DiffEditorModel extends EditorModel { - protected _originalModel: IEditorModel; - protected _modifiedModel: IEditorModel; + protected _originalModel: IEditorModel | null; + protected _modifiedModel: IEditorModel | null; - constructor(originalModel: IEditorModel, modifiedModel: IEditorModel) { + constructor(originalModel: IEditorModel | null, modifiedModel: IEditorModel | null) { super(); this._originalModel = originalModel; this._modifiedModel = modifiedModel; } - get originalModel(): EditorModel { + get originalModel(): EditorModel | null { + if (!this._originalModel) { + return null; + } return this._originalModel as EditorModel; } - get modifiedModel(): EditorModel { + get modifiedModel(): EditorModel | null { + if (!this._modifiedModel) { + return null; + } return this._modifiedModel as EditorModel; } load(): Promise { return Promise.all([ - this._originalModel.load(), - this._modifiedModel.load() + this._originalModel ? this._originalModel.load() : Promise.resolve(undefined), + this._modifiedModel ? this._modifiedModel.load() : Promise.resolve(undefined), ]).then(() => this); } isResolved(): boolean { - return this.originalModel.isResolved() && this.modifiedModel.isResolved(); + return !!this.originalModel && this.originalModel.isResolved() && !!this.modifiedModel && this.modifiedModel.isResolved(); } dispose(): void { From 873b17fce6325123258270dd50d0fec190c6f8b4 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 13:29:19 -0800 Subject: [PATCH 213/290] Strict null check dnd --- src/tsconfig.strictNullChecks.json | 4 ++++ src/vs/workbench/browser/dnd.ts | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 306f8343f65..e9512508680 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -97,10 +97,12 @@ "./vs/workbench/browser/actions/workspaceCommands.ts", "./vs/workbench/browser/composite.ts", "./vs/workbench/browser/contextkeys.ts", + "./vs/workbench/browser/dnd.ts", "./vs/workbench/browser/editor.ts", "./vs/workbench/browser/labels.ts", "./vs/workbench/browser/panel.ts", "./vs/workbench/browser/part.ts", + "./vs/workbench/browser/parts/compositeBarActions.ts", "./vs/workbench/browser/parts/compositePart.ts", "./vs/workbench/browser/parts/editor/baseEditor.ts", "./vs/workbench/browser/parts/editor/binaryDiffEditor.ts", @@ -225,6 +227,7 @@ "./vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts", "./vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts", "./vs/workbench/contrib/files/browser/files.ts", + "./vs/workbench/contrib/files/browser/views/emptyView.ts", "./vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts", "./vs/workbench/contrib/files/common/dirtyFilesTracker.ts", "./vs/workbench/contrib/files/common/editors/fileEditorInput.ts", @@ -252,6 +255,7 @@ "./vs/workbench/contrib/output/common/output.ts", "./vs/workbench/contrib/output/common/outputLinkComputer.ts", "./vs/workbench/contrib/output/common/outputLinkProvider.ts", + "./vs/workbench/contrib/output/electron-browser/output.contribution.ts", "./vs/workbench/contrib/output/electron-browser/outputServices.ts", "./vs/workbench/contrib/output/node/outputAppender.ts", "./vs/workbench/contrib/preferences/browser/settingsWidgets.ts", diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index 9b036521f2e..41feee3ebe4 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -162,7 +162,7 @@ export class ResourcesDropHandler { ) { } - handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup) => void, targetIndex?: number): void { + handleDrop(event: DragEvent, resolveTargetGroup: () => IEditorGroup | undefined, afterDrop: (targetGroup: IEditorGroup | undefined) => void, targetIndex?: number): void { const untitledOrFileResources = extractResources(event).filter(r => this.fileService.canHandleResource(r.resource) || r.resource.scheme === Schemas.untitled); if (!untitledOrFileResources.length) { return; @@ -235,10 +235,10 @@ export class ResourcesDropHandler { } // Resolve the contents of the dropped dirty resource from source - return this.backupFileService.resolveBackupContent(droppedDirtyEditor.backupResource).then(content => { + return this.backupFileService.resolveBackupContent(droppedDirtyEditor.backupResource!).then(content => { // Set the contents of to the resource to the target - return this.backupFileService.backupResource(droppedDirtyEditor.resource, content.create(this.getDefaultEOL()).createSnapshot(true)); + return this.backupFileService.backupResource(droppedDirtyEditor.resource, content!.create(this.getDefaultEOL()).createSnapshot(true)); }).then(() => false, () => false /* ignore any error */); } From a6dee4c4070ceb79b307c5c16d649908acf668e7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:18:49 -0800 Subject: [PATCH 214/290] Strict null check textDiffEditor --- src/tsconfig.strictNullChecks.json | 1 + src/vs/editor/common/editorCommon.ts | 2 +- .../browser/parts/editor/textDiffEditor.ts | 15 ++++++++------- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index e9512508680..45a5b9b1948 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -116,6 +116,7 @@ "./vs/workbench/browser/parts/editor/rangeDecorations.ts", "./vs/workbench/browser/parts/editor/resourceViewer.ts", "./vs/workbench/browser/parts/editor/sideBySideEditor.ts", + "./vs/workbench/browser/parts/editor/textDiffEditor.ts", "./vs/workbench/browser/parts/editor/textEditor.ts", "./vs/workbench/browser/parts/editor/textResourceEditor.ts", "./vs/workbench/browser/parts/quickinput/quickInputBox.ts", diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index e969ff60627..bde26ab9802 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -469,7 +469,7 @@ export interface IDiffEditor extends IEditor { /** * Type the getModel() of IEditor. */ - getModel(): IDiffEditorModel; + getModel(): IDiffEditorModel | null; /** * Get the `original` editor. diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index b91fc19dbe6..88f2deeeb0b 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -61,7 +61,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { return new EditorMemento(this.getId(), key, Object.create(null), limit, editorGroupService); // do not persist in storage as diff editors are never persisted } - getTitle(): string { + getTitle(): string | null { if (this.input) { return this.input.getName(); } @@ -120,6 +120,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { // Readonly flag diffEditor.updateOptions({ readOnly: resolvedDiffEditorModel.isReadonly() }); + return undefined; }, error => { // In case we tried to open a file and the response indicates that this is not a text file, fallback to binary diff. @@ -262,7 +263,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { return super.loadTextEditorViewState(resource) as IDiffEditorViewState; // overridden for text diff editor support } - private saveTextDiffEditorViewState(input: EditorInput): void { + private saveTextDiffEditorViewState(input: EditorInput | null): void { if (!(input instanceof DiffEditorInput)) { return; // only supported for diff editor inputs } @@ -288,11 +289,11 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { } } - protected retrieveTextEditorViewState(resource: URI): IDiffEditorViewState { + protected retrieveTextEditorViewState(resource: URI): IDiffEditorViewState | null { return this.retrieveTextDiffEditorViewState(resource); // overridden for text diff editor support } - private retrieveTextDiffEditorViewState(resource: URI): IDiffEditorViewState { + private retrieveTextDiffEditorViewState(resource: URI): IDiffEditorViewState | null { const control = this.getControl(); const model = control.getModel(); if (!model || !model.modified || !model.original) { @@ -311,9 +312,9 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { return control.saveViewState(); } - private toDiffEditorViewStateResource(modelOrInput: IDiffEditorModel | DiffEditorInput): URI { - let original: URI; - let modified: URI; + private toDiffEditorViewStateResource(modelOrInput: IDiffEditorModel | DiffEditorInput): URI | null { + let original: URI | null; + let modified: URI | null; if (modelOrInput instanceof DiffEditorInput) { original = modelOrInput.originalInput.getResource(); From def06bab4840aa766c959afb415b9af6930b4f5b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:24:22 -0800 Subject: [PATCH 215/290] Strict null check customView --- src/tsconfig.strictNullChecks.json | 2 ++ .../browser/parts/views/customView.ts | 18 +++++++++--------- src/vs/workbench/common/views.ts | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 45a5b9b1948..1248c348f7b 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -37,6 +37,7 @@ "./vs/nls.mock.ts", "./vs/vscode.d.ts", "./vs/vscode.proposed.d.ts", + "./vs/workbench/api/browser/viewsExtensionPoint.ts", "./vs/workbench/api/common/configurationExtensionPoint.ts", "./vs/workbench/api/common/jsonValidationExtensionPoint.ts", "./vs/workbench/api/common/menusExtensionPoint.ts", @@ -128,6 +129,7 @@ "./vs/workbench/browser/parts/sidebar/sidebarPart.ts", "./vs/workbench/browser/parts/statusbar/statusbar.ts", "./vs/workbench/browser/parts/statusbar/statusbarPart.ts", + "./vs/workbench/browser/parts/views/customView.ts", "./vs/workbench/browser/parts/views/panelViewlet.ts", "./vs/workbench/browser/parts/views/views.ts", "./vs/workbench/browser/parts/views/viewsViewlet.ts", diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 6dfc083014d..4450da30eb0 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -190,7 +190,7 @@ export class CustomTreeView extends Disposable implements ITreeView { private menus: TitleMenus; private markdownRenderer: MarkdownRenderer; - private markdownResult: IMarkdownRenderResult; + private markdownResult: IMarkdownRenderResult | null; private readonly _onDidExpandItem: Emitter = this._register(new Emitter()); readonly onDidExpandItem: Event = this._onDidExpandItem.event; @@ -242,15 +242,15 @@ export class CustomTreeView extends Disposable implements ITreeView { this.create(); } - private _dataProvider: ITreeViewDataProvider; - get dataProvider(): ITreeViewDataProvider { + private _dataProvider: ITreeViewDataProvider | null; + get dataProvider(): ITreeViewDataProvider | null { return this._dataProvider; } - set dataProvider(dataProvider: ITreeViewDataProvider) { + set dataProvider(dataProvider: ITreeViewDataProvider | null) { if (dataProvider) { this._dataProvider = new class implements ITreeViewDataProvider { - getChildren(node?: ITreeItem): Promise { + getChildren(node: ITreeItem): Promise { if (node && node.children) { return Promise.resolve(node.children); } @@ -377,7 +377,7 @@ export class CustomTreeView extends Disposable implements ITreeView { } private createTree() { - const actionItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuItemActionItem, action) : undefined; + const actionItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuItemActionItem, action) : null; const menus = this._register(this.instantiationService.createInstance(TreeMenus, this.id)); this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels, this)); const dataSource = this.instantiationService.createInstance(TreeDataSource, this, (task: Promise) => this.progressService.withProgress({ location: this.viewContainer.id }, () => task)); @@ -461,7 +461,7 @@ export class CustomTreeView extends Disposable implements ITreeView { this.elementsToRefresh = []; } for (const element of elements) { - element.children = null; // reset children + element.children = undefined; // reset children } if (this.isVisible) { return this.doRefresh(elements); @@ -676,7 +676,7 @@ class TreeRenderer implements IRenderer { renderElement(tree: ITree, node: ITreeItem, templateId: string, templateData: ITreeExplorerTemplateData): void { const resource = node.resourceUri ? URI.revive(node.resourceUri) : null; - const treeItemLabel: ITreeItemLabel = node.label ? node.label : resource ? { label: basename(resource) } : undefined; + const treeItemLabel: ITreeItemLabel | undefined = node.label ? node.label : resource ? { label: basename(resource) } : undefined; const description = isString(node.description) ? node.description : resource && node.description === true ? this.labelService.getUriLabel(dirname(resource), { relative: true }) : undefined; const label = treeItemLabel ? treeItemLabel.label : undefined; const matches = treeItemLabel && treeItemLabel.highlights ? treeItemLabel.highlights.map(([start, end]) => ({ start, end })) : undefined; @@ -872,7 +872,7 @@ class TreeMenus extends Disposable implements IDisposable { return this.getActions(MenuId.ViewItemContext, { key: 'viewItem', value: element.contextValue }).secondary; } - private getActions(menuId: MenuId, context: { key: string, value: string }): { primary: IAction[]; secondary: IAction[]; } { + private getActions(menuId: MenuId, context: { key: string, value?: string }): { primary: IAction[]; secondary: IAction[]; } { const contextKeyService = this.contextKeyService.createScoped(); contextKeyService.createKey('view', this.id); contextKeyService.createKey(context.key, context.value); diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 2a16b9bd9f6..7d08589c1a7 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -378,7 +378,7 @@ export interface ITreeItem { handle: string; - parentHandle: string; + parentHandle: string | null; collapsibleState: TreeItemCollapsibleState; From 2f088e6d969e6811ee55c68114662fbe18d7aae8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:29:51 -0800 Subject: [PATCH 216/290] Strict null check fileEditorTracker --- src/tsconfig.strictNullChecks.json | 1 + .../contrib/files/browser/editors/fileEditorTracker.ts | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 1248c348f7b..1bb8941d011 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -229,6 +229,7 @@ "./vs/workbench/contrib/feedback/electron-browser/feedback.ts", "./vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts", "./vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts", + "./vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts", "./vs/workbench/contrib/files/browser/files.ts", "./vs/workbench/contrib/files/browser/views/emptyView.ts", "./vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts", diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts index c281e9d0bfb..cb15ee33d26 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts @@ -110,7 +110,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut private onFileOperation(e: FileOperationEvent): void { // Handle moves specially when file is opened - if (e.operation === FileOperation.MOVE) { + if (e.operation === FileOperation.MOVE && e.target) { this.handleMovedFileInOpenedEditors(e.resource, e.target.resource); } @@ -300,8 +300,8 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // // Note: we also consider the added event because it could be that a file was added // and updated right after. - distinct([...e.getUpdated(), ...e.getAdded()] - .map(u => this.textFileService.models.get(u.resource)) + distinct(coalesce([...e.getUpdated(), ...e.getAdded()] + .map(u => this.textFileService.models.get(u.resource))) .filter(model => model && !model.isDirty()), m => m.getResource().toString()) .forEach(model => this.queueModelLoad(model)); } From ee75807070082f2c7b48632cd200ef1b948d2fd8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:30:28 -0800 Subject: [PATCH 217/290] Strict null check activitybarActions --- src/tsconfig.strictNullChecks.json | 1 + src/vs/workbench/browser/parts/sidebar/sidebarPart.ts | 6 +++--- src/vs/workbench/services/viewlet/browser/viewlet.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 1bb8941d011..839937fa0d8 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -103,6 +103,7 @@ "./vs/workbench/browser/labels.ts", "./vs/workbench/browser/panel.ts", "./vs/workbench/browser/part.ts", + "./vs/workbench/browser/parts/activitybar/activitybarActions.ts", "./vs/workbench/browser/parts/compositeBarActions.ts", "./vs/workbench/browser/parts/compositePart.ts", "./vs/workbench/browser/parts/editor/baseEditor.ts", diff --git a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts index d1d90205df5..f17cef29eb2 100644 --- a/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts +++ b/src/vs/workbench/browser/parts/sidebar/sidebarPart.ts @@ -199,14 +199,14 @@ export class SidebarPart extends CompositePart implements ISerializable this.hideActiveComposite(); } - openViewlet(id: string, focus?: boolean): Promise { - if (this.getViewlet(id)) { + openViewlet(id: string | undefined, focus?: boolean): Promise { + if (typeof id === 'string' && this.getViewlet(id)) { return Promise.resolve(this.doOpenViewlet(id, focus)); } return this.extensionService.whenInstalledExtensionsRegistered() .then(() => { - if (this.getViewlet(id)) { + if (typeof id === 'string' && this.getViewlet(id)) { return this.doOpenViewlet(id, focus); } diff --git a/src/vs/workbench/services/viewlet/browser/viewlet.ts b/src/vs/workbench/services/viewlet/browser/viewlet.ts index b87357e7630..88410fceb95 100644 --- a/src/vs/workbench/services/viewlet/browser/viewlet.ts +++ b/src/vs/workbench/services/viewlet/browser/viewlet.ts @@ -22,7 +22,7 @@ export interface IViewletService { /** * Opens a viewlet with the given identifier and pass keyboard focus to it if specified. */ - openViewlet(id: string, focus?: boolean): Promise; + openViewlet(id: string | undefined, focus?: boolean): Promise; /** * Returns the current active viewlet or null if none. From 367b5fc7ecbb18198ec08cd0c3d388e13cd3b316 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:34:39 -0800 Subject: [PATCH 218/290] Strict null check editorDropTarget --- src/tsconfig.strictNullChecks.json | 1 + .../browser/parts/editor/editorDropTarget.ts | 28 +++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 839937fa0d8..6085a5e39b0 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -113,6 +113,7 @@ "./vs/workbench/browser/parts/editor/breadcrumbsModel.ts", "./vs/workbench/browser/parts/editor/editor.ts", "./vs/workbench/browser/parts/editor/editorControl.ts", + "./vs/workbench/browser/parts/editor/editorDropTarget.ts", "./vs/workbench/browser/parts/editor/editorPicker.ts", "./vs/workbench/browser/parts/editor/editorWidgets.ts", "./vs/workbench/browser/parts/editor/rangeDecorations.ts", diff --git a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts index 52272c0d2f4..464a494ba92 100644 --- a/src/vs/workbench/browser/parts/editor/editorDropTarget.ts +++ b/src/vs/workbench/browser/parts/editor/editorDropTarget.ts @@ -28,7 +28,7 @@ class DropOverlay extends Themable { private container: HTMLElement; private overlay: HTMLElement; - private currentDropOperation: IDropOperation; + private currentDropOperation?: IDropOperation; private _disposed: boolean; private cleanupOverlayScheduler: RunOnceScheduler; @@ -103,12 +103,12 @@ class DropOverlay extends Themable { // Update the dropEffect to "copy" if there is no local data to be dragged because // in that case we can only copy the data into and not move it from its source - if (!isDraggingEditor && !isDraggingGroup) { + if (!isDraggingEditor && !isDraggingGroup && e.dataTransfer) { e.dataTransfer.dropEffect = 'copy'; } // Find out if operation is valid - const isCopy = isDraggingGroup ? this.isCopyOperation(e) : isDraggingEditor ? this.isCopyOperation(e, this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier) : true; + const isCopy = isDraggingGroup ? this.isCopyOperation(e) : isDraggingEditor ? this.isCopyOperation(e, this.editorTransfer.getData(DraggedEditorIdentifier.prototype)![0].identifier) : true; if (!isCopy) { const sourceGroupView = this.findSourceGroupView(); if (sourceGroupView === this.groupView) { @@ -158,16 +158,16 @@ class DropOverlay extends Themable { })); } - private findSourceGroupView(): IEditorGroupView { + private findSourceGroupView(): IEditorGroupView | undefined { // Check for group transfer if (this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype)) { - return this.accessor.getGroup(this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)[0].identifier); + return this.accessor.getGroup(this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)![0].identifier); } // Check for editor transfer else if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) { - return this.accessor.getGroup(this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier.groupId); + return this.accessor.getGroup(this.editorTransfer.getData(DraggedEditorIdentifier.prototype)![0].identifier.groupId); } return undefined; @@ -189,7 +189,7 @@ class DropOverlay extends Themable { // Check for group transfer if (this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype)) { - const draggedEditorGroup = this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)[0].identifier; + const draggedEditorGroup = this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)![0].identifier; // Return if the drop is a no-op const sourceGroup = this.accessor.getGroup(draggedEditorGroup); @@ -222,7 +222,7 @@ class DropOverlay extends Themable { // Check for editor transfer else if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) { - const draggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier; + const draggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)![0].identifier; const targetGroup = ensureTargetGroup(); // Return if the drop is a no-op @@ -250,7 +250,7 @@ class DropOverlay extends Themable { // Check for URI transfer else { const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: true /* open workspace instead of file if dropped */ }); - dropHandler.handleDrop(event, () => ensureTargetGroup(), targetGroup => targetGroup.focus()); + dropHandler.handleDrop(event, () => ensureTargetGroup(), targetGroup => targetGroup!.focus()); } } @@ -298,7 +298,7 @@ class DropOverlay extends Themable { // child.style.top = edgeHeightThreshold + 'px'; // No split if mouse is above certain threshold in the center of the view - let splitDirection: GroupDirection; + let splitDirection: GroupDirection | undefined; if ( mousePosX > edgeWidthThreshold && mousePosX < editorControlWidth - edgeWidthThreshold && mousePosY > edgeHeightThreshold && mousePosY < editorControlHeight - edgeHeightThreshold @@ -429,7 +429,7 @@ class DropOverlay extends Themable { export class EditorDropTarget extends Themable { - private _overlay: DropOverlay; + private _overlay?: DropOverlay; private counter = 0; @@ -447,7 +447,7 @@ export class EditorDropTarget extends Themable { this.registerListeners(); } - private get overlay(): DropOverlay { + private get overlay(): DropOverlay | undefined { if (this._overlay && !this._overlay.disposed) { return this._overlay; } @@ -468,7 +468,7 @@ export class EditorDropTarget extends Themable { if ( !this.editorTransfer.hasData(DraggedEditorIdentifier.prototype) && !this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype) && - !event.dataTransfer.types.length // see https://github.com/Microsoft/vscode/issues/25789 + event.dataTransfer && !event.dataTransfer.types.length // see https://github.com/Microsoft/vscode/issues/25789 ) { event.dataTransfer.dropEffect = 'none'; return; // unsupported transfer @@ -510,7 +510,7 @@ export class EditorDropTarget extends Themable { this.disposeOverlay(); } - private findTargetGroupView(child: HTMLElement): IEditorGroupView { + private findTargetGroupView(child: HTMLElement): IEditorGroupView | undefined { const groups = this.accessor.groups; for (const groupView of groups) { if (isAncestor(child, groupView.element)) { From 7e05804a90d84ee5e27547b8938e0f9fb0ab525d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:40:44 -0800 Subject: [PATCH 219/290] Strict null check compositeBar --- src/tsconfig.strictNullChecks.json | 1 + .../workbench/browser/parts/compositeBar.ts | 34 +++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 6085a5e39b0..e261c8b964a 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -104,6 +104,7 @@ "./vs/workbench/browser/panel.ts", "./vs/workbench/browser/part.ts", "./vs/workbench/browser/parts/activitybar/activitybarActions.ts", + "./vs/workbench/browser/parts/compositeBar.ts", "./vs/workbench/browser/parts/compositeBarActions.ts", "./vs/workbench/browser/parts/compositePart.ts", "./vs/workbench/browser/parts/editor/baseEditor.ts", diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index 4869bb20391..fe068d5c5c8 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -25,7 +25,7 @@ export interface ICompositeBarItem { id: string; name: string; pinned: boolean; - order: number; + order?: number; visible: boolean; } @@ -49,8 +49,8 @@ export class CompositeBar extends Widget implements ICompositeBar { private dimension: Dimension; private compositeSwitcherBar: ActionBar; - private compositeOverflowAction: CompositeOverflowActivityAction; - private compositeOverflowActionItem: CompositeOverflowActivityActionItem; + private compositeOverflowAction: CompositeOverflowActivityAction | null; + private compositeOverflowActionItem: CompositeOverflowActivityActionItem | null; private model: CompositeBarModel; private visibleComposites: string[]; @@ -174,7 +174,7 @@ export class CompositeBar extends Widget implements ICompositeBar { if (this.model.activate(id)) { // Update if current composite is neither visible nor pinned // or previous active composite is not pinned - if (this.visibleComposites.indexOf(id) === - 1 || !this.model.activeItem.pinned || (previousActiveItem && !previousActiveItem.pinned)) { + if (this.visibleComposites.indexOf(id) === - 1 || (!!this.model.activeItem && !this.model.activeItem.pinned) || (previousActiveItem && !previousActiveItem.pinned)) { this.updateCompositeSwitcher(); } } @@ -304,7 +304,7 @@ export class CompositeBar extends Widget implements ICompositeBar { let size = 0; const limit = this.options.orientation === ActionsOrientation.VERTICAL ? this.dimension.height : this.dimension.width; for (let i = 0; i < compositesToShow.length && size <= limit; i++) { - size += this.compositeSizeInBar.get(compositesToShow[i]); + size += this.compositeSizeInBar.get(compositesToShow[i])!; if (size > limit) { maxVisible = i; } @@ -312,19 +312,19 @@ export class CompositeBar extends Widget implements ICompositeBar { overflows = compositesToShow.length > maxVisible; if (overflows) { - size -= this.compositeSizeInBar.get(compositesToShow[maxVisible]); + size -= this.compositeSizeInBar.get(compositesToShow[maxVisible])!; compositesToShow = compositesToShow.slice(0, maxVisible); size += this.options.overflowActionSize; } // Check if we need to make extra room for the overflow action if (size > limit) { - size -= this.compositeSizeInBar.get(compositesToShow.pop()); + size -= this.compositeSizeInBar.get(compositesToShow.pop()!)!; } // We always try show the active composite - if (this.model.activeItem && compositesToShow.every(compositeId => compositeId !== this.model.activeItem.id)) { - const removedComposite = compositesToShow.pop(); - size = size - this.compositeSizeInBar.get(removedComposite) + this.compositeSizeInBar.get(this.model.activeItem.id); + if (this.model.activeItem && compositesToShow.every(compositeId => !!this.model.activeItem && compositeId !== this.model.activeItem.id)) { + const removedComposite = compositesToShow.pop()!; + size = size - this.compositeSizeInBar.get(removedComposite)! + this.compositeSizeInBar.get(this.model.activeItem.id)!; compositesToShow.push(this.model.activeItem.id); } @@ -342,7 +342,9 @@ export class CompositeBar extends Widget implements ICompositeBar { this.compositeOverflowAction.dispose(); this.compositeOverflowAction = null; - this.compositeOverflowActionItem.dispose(); + if (this.compositeOverflowActionItem) { + this.compositeOverflowActionItem.dispose(); + } this.compositeOverflowActionItem = null; } @@ -378,7 +380,11 @@ export class CompositeBar extends Widget implements ICompositeBar { // Add overflow action as needed if ((visibleCompositesChange && overflows) || this.compositeSwitcherBar.length() === 0) { - this.compositeOverflowAction = this.instantiationService.createInstance(CompositeOverflowActivityAction, () => this.compositeOverflowActionItem.showMenu()); + this.compositeOverflowAction = this.instantiationService.createInstance(CompositeOverflowActivityAction, () => { + if (this.compositeOverflowActionItem) { + this.compositeOverflowActionItem.showMenu(); + } + }); this.compositeOverflowActionItem = this.instantiationService.createInstance( CompositeOverflowActivityActionItem, this.compositeOverflowAction, @@ -453,7 +459,7 @@ class CompositeBarModel { private _items: ICompositeBarModelItem[]; private readonly options: ICompositeBarOptions; - activeItem: ICompositeBarModelItem; + activeItem?: ICompositeBarModelItem; constructor( items: ICompositeBarItem[], @@ -541,7 +547,7 @@ class CompositeBarModel { this.items.push(item); } else { let index = 0; - while (index < this.items.length && this.items[index].order < order) { + while (index < this.items.length && typeof this.items[index].order === 'number' && this.items[index].order! < order) { index++; } this.items.splice(index, 0, item); From 84c059ab525bbc99cb36c00afa8483758475c6f2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 14:54:51 -0800 Subject: [PATCH 220/290] Strict null check editorActions and editorCommands --- src/tsconfig.strictNullChecks.json | 2 ++ .../keybinding/common/keybindingsRegistry.ts | 2 +- .../browser/parts/editor/editorActions.ts | 8 +++---- .../browser/parts/editor/editorCommands.ts | 22 +++++++++---------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index e261c8b964a..e5f464ef6f3 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -113,6 +113,8 @@ "./vs/workbench/browser/parts/editor/breadcrumbs.ts", "./vs/workbench/browser/parts/editor/breadcrumbsModel.ts", "./vs/workbench/browser/parts/editor/editor.ts", + "./vs/workbench/browser/parts/editor/editorActions.ts", + "./vs/workbench/browser/parts/editor/editorCommands.ts", "./vs/workbench/browser/parts/editor/editorControl.ts", "./vs/workbench/browser/parts/editor/editorDropTarget.ts", "./vs/workbench/browser/parts/editor/editorPicker.ts", diff --git a/src/vs/platform/keybinding/common/keybindingsRegistry.ts b/src/vs/platform/keybinding/common/keybindingsRegistry.ts index bfa00350ebd..145508abb2a 100644 --- a/src/vs/platform/keybinding/common/keybindingsRegistry.ts +++ b/src/vs/platform/keybinding/common/keybindingsRegistry.ts @@ -19,7 +19,7 @@ export interface IKeybindingItem { } export interface IKeybindings { - primary: number; + primary?: number; secondary?: number[]; win?: { primary: number; diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 05ed83a7bca..205fdcaac49 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -952,7 +952,7 @@ export class OpenNextEditor extends BaseNavigateEditorAction { // Navigate in active group if possible const activeGroup = this.editorGroupService.activeGroup; const activeGroupEditors = activeGroup.getEditors(EditorsOrder.SEQUENTIAL); - const activeEditorIndex = activeGroupEditors.indexOf(activeGroup.activeEditor); + const activeEditorIndex = activeGroup.activeEditor ? activeGroupEditors.indexOf(activeGroup.activeEditor) : -1; if (activeEditorIndex + 1 < activeGroupEditors.length) { return { editor: activeGroupEditors[activeEditorIndex + 1], groupId: activeGroup.id }; } @@ -987,7 +987,7 @@ export class OpenPreviousEditor extends BaseNavigateEditorAction { // Navigate in active group if possible const activeGroup = this.editorGroupService.activeGroup; const activeGroupEditors = activeGroup.getEditors(EditorsOrder.SEQUENTIAL); - const activeEditorIndex = activeGroupEditors.indexOf(activeGroup.activeEditor); + const activeEditorIndex = activeGroup.activeEditor ? activeGroupEditors.indexOf(activeGroup.activeEditor) : -1; if (activeEditorIndex > 0) { return { editor: activeGroupEditors[activeEditorIndex - 1], groupId: activeGroup.id }; } @@ -1020,7 +1020,7 @@ export class OpenNextEditorInGroup extends BaseNavigateEditorAction { protected navigate(): IEditorIdentifier { const group = this.editorGroupService.activeGroup; const editors = group.getEditors(EditorsOrder.SEQUENTIAL); - const index = editors.indexOf(group.activeEditor); + const index = group.activeEditor ? editors.indexOf(group.activeEditor) : -1; return { editor: index + 1 < editors.length ? editors[index + 1] : editors[0], groupId: group.id }; } @@ -1043,7 +1043,7 @@ export class OpenPreviousEditorInGroup extends BaseNavigateEditorAction { protected navigate(): IEditorIdentifier { const group = this.editorGroupService.activeGroup; const editors = group.getEditors(EditorsOrder.SEQUENTIAL); - const index = editors.indexOf(group.activeEditor); + const index = group.activeEditor ? editors.indexOf(group.activeEditor) : -1; return { editor: index > 0 ? editors[index - 1] : editors[editors.length - 1], groupId: group.id }; } diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 25e420329d5..e1e12fc7790 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -16,7 +16,7 @@ import { URI } from 'vs/base/common/uri'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IListService } from 'vs/platform/list/browser/listService'; import { List } from 'vs/base/browser/ui/list/listWidget'; -import { distinct } from 'vs/base/common/arrays'; +import { distinct, coalesce } from 'vs/base/common/arrays'; import { IEditorGroupsService, IEditorGroup, GroupDirection, GroupLocation, GroupsOrder, preferredSideBySideGroupDirection, EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; @@ -52,9 +52,9 @@ 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'; - value?: number; + to: 'first' | 'last' | 'left' | 'right' | 'up' | 'down' | 'center' | 'position' | 'previous' | 'next'; + by: 'tab' | 'group'; + value: number; } const isActiveEditorMoveArg = function (arg: ActiveEditorMoveArguments): boolean { @@ -357,7 +357,7 @@ function registerOpenEditorAtIndexCommands(): void { case 9: return KeyCode.KEY_9; } - return undefined; + throw new Error('invalid index'); } } @@ -409,7 +409,7 @@ function registerFocusEditorGroupAtIndexCommands(): void { case 7: return 'workbench.action.focusEighthEditorGroup'; } - return undefined; + throw new Error('Invalid index'); } function toKeyCode(index: number): KeyCode { @@ -423,7 +423,7 @@ function registerFocusEditorGroupAtIndexCommands(): void { case 7: return KeyCode.KEY_8; } - return undefined; + throw new Error('Invalid index'); } } @@ -528,9 +528,9 @@ function registerCloseEditorCommands() { return Promise.all(groupIds.map(groupId => { const group = editorGroupService.getGroup(groupId); - const editors = contexts + const editors = coalesce(contexts .filter(context => context.groupId === groupId) - .map(context => typeof context.editorIndex === 'number' ? group.getEditor(context.editorIndex) : group.activeEditor); + .map(context => typeof context.editorIndex === 'number' ? group.getEditor(context.editorIndex) : group.activeEditor)); return group.closeEditors(editors); })); @@ -675,7 +675,7 @@ function getCommandsContext(resourceOrContext: URI | IEditorCommandsContext, con return undefined; } -function resolveCommandsContext(editorGroupService: IEditorGroupsService, context?: IEditorCommandsContext): { group: IEditorGroup, editor: IEditorInput, control: IEditor } { +function resolveCommandsContext(editorGroupService: IEditorGroupsService, context?: IEditorCommandsContext): { group: IEditorGroup, editor?: IEditorInput, control?: IEditor } { // Resolve from context let group = context && typeof context.groupId === 'number' ? editorGroupService.getGroup(context.groupId) : undefined; @@ -689,7 +689,7 @@ function resolveCommandsContext(editorGroupService: IEditorGroupsService, contex control = group.activeControl; } - return { group, editor, control }; + return { group, editor: editor || undefined, control: control || undefined }; } export function getMultiSelectedEditorContexts(editorContext: IEditorCommandsContext | undefined, listService: IListService, editorGroupService: IEditorGroupsService): IEditorCommandsContext[] { From aa912c88ede9b97f59cf36fe47fbc22ec0a206fc Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 15:02:57 -0800 Subject: [PATCH 221/290] Strict null check activityBar --- src/tsconfig.strictNullChecks.json | 1 + .../parts/activitybar/activitybarPart.ts | 35 +++++++++++-------- .../workbench/browser/parts/compositeBar.ts | 6 ++-- .../browser/parts/compositeBarActions.ts | 16 ++++----- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index e5f464ef6f3..d0df318c885 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -104,6 +104,7 @@ "./vs/workbench/browser/panel.ts", "./vs/workbench/browser/part.ts", "./vs/workbench/browser/parts/activitybar/activitybarActions.ts", + "./vs/workbench/browser/parts/activitybar/activitybarPart.ts", "./vs/workbench/browser/parts/compositeBar.ts", "./vs/workbench/browser/parts/compositeBarActions.ts", "./vs/workbench/browser/parts/compositePart.ts", diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index f54dadfb511..caf40047a5a 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -38,11 +38,11 @@ const SCM_VIEWLET_ID = 'workbench.view.scm'; interface ICachedViewlet { id: string; - iconUrl: UriComponents; + iconUrl?: UriComponents; pinned: boolean; - order: number; + order?: number; visible: boolean; - views?: { when: string }[]; + views?: { when?: string }[]; } export class ActivitybarPart extends Part implements ISerializableView { @@ -161,14 +161,19 @@ export class ActivitybarPart extends Part implements ISerializableView { private onDidViewletOpen(viewlet: IViewlet): void { // Update the composite bar by adding - this.compositeBar.addComposite(this.viewletService.getViewlet(viewlet.getId())); + const foundViewlet = this.viewletService.getViewlet(viewlet.getId()); + if (foundViewlet) { + this.compositeBar.addComposite(foundViewlet); + } this.compositeBar.activateComposite(viewlet.getId()); const viewletDescriptor = this.viewletService.getViewlet(viewlet.getId()); - const viewContainer = this.getViewContainer(viewletDescriptor.id); - if (viewContainer) { - const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer); - if (viewDescriptors && viewDescriptors.activeViewDescriptors.length === 0) { - this.removeComposite(viewletDescriptor.id, true); // Update the composite bar by hiding + if (viewletDescriptor) { + const viewContainer = this.getViewContainer(viewletDescriptor.id); + if (viewContainer) { + const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer); + if (viewDescriptors && viewDescriptors.activeViewDescriptors.length === 0) { + this.removeComposite(viewletDescriptor.id, true); // Update the composite bar by hiding + } } } } @@ -241,7 +246,7 @@ export class ActivitybarPart extends Part implements ISerializableView { badgeBackground: theme.getColor(ACTIVITY_BAR_BADGE_BACKGROUND), badgeForeground: theme.getColor(ACTIVITY_BAR_BADGE_FOREGROUND), dragAndDropBackground: theme.getColor(ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND), - activeBackgroundColor: null, inactiveBackgroundColor: null, activeBorderBottomColor: null, + activeBackgroundColor: undefined, inactiveBackgroundColor: undefined, activeBorderBottomColor: undefined, }; } @@ -311,7 +316,7 @@ export class ActivitybarPart extends Part implements ISerializableView { private shouldBeHidden(viewletId: string, cachedViewlet: ICachedViewlet): boolean { return cachedViewlet && cachedViewlet.views && cachedViewlet.views.length - ? cachedViewlet.views.every(({ when }) => when && !this.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(when))) + ? cachedViewlet.views.every(({ when }) => !!when && !this.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(when))) : viewletId === TEST_VIEW_CONTAINER_ID /* Hide Test viewlet for the first time or it had no views registered before */; } @@ -371,7 +376,7 @@ export class ActivitybarPart extends Part implements ISerializableView { } // Pass to super - const sizes = super.layout(dim1 instanceof Dimension ? dim1 : new Dimension(dim1, dim2)); + const sizes = super.layout(dim1 instanceof Dimension ? dim1 : new Dimension(dim1, dim2!)); this.dimension = sizes[1]; @@ -428,7 +433,7 @@ export class ActivitybarPart extends Part implements ISerializableView { const viewContainer = this.getViewContainer(compositeItem.id); const viewlet = allViewlets.filter(({ id }) => id === compositeItem.id)[0]; if (viewlet) { - const views: { when: string }[] = []; + const views: { when: string | undefined }[] = []; if (viewContainer) { const viewDescriptors = this.viewsService.getViewDescriptors(viewContainer); if (viewDescriptors) { @@ -471,7 +476,7 @@ export class ActivitybarPart extends Part implements ISerializableView { return result; } - private _cachedViewletsValue: string; + private _cachedViewletsValue: string | null; private get cachedViewletsValue(): string { if (!this._cachedViewletsValue) { this._cachedViewletsValue = this.getStoredCachedViewletsValue(); @@ -498,7 +503,7 @@ export class ActivitybarPart extends Part implements ISerializableView { private getViewContainer(viewletId: string): ViewContainer | undefined { // TODO: @Joao Remove this after moving SCM Viewlet to ViewContainerViewlet - https://github.com/Microsoft/vscode/issues/49054 if (viewletId === SCM_VIEWLET_ID) { - return null; + return undefined; } const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index fe068d5c5c8..a1367bbb2e6 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -23,7 +23,7 @@ import { Emitter, Event } from 'vs/base/common/event'; export interface ICompositeBarItem { id: string; - name: string; + name?: string; pinned: boolean; order?: number; visible: boolean; @@ -404,7 +404,7 @@ export class CompositeBar extends Widget implements ICompositeBar { this._onDidChange.fire(); } - private getOverflowingComposites(): { id: string, name: string }[] { + private getOverflowingComposites(): { id: string, name?: string }[] { let overflowingIds = this.model.visibleItems.filter(item => item.pinned).map(item => item.id); // Show the active composite even if it is not pinned @@ -513,7 +513,7 @@ class CompositeBarModel { return this.items.filter(item => item.visible && item.pinned); } - private createCompositeBarItem(id: string, name: string, order: number | undefined, pinned: boolean, visible: boolean): ICompositeBarModelItem { + private createCompositeBarItem(id: string, name: string | undefined, order: number | undefined, pinned: boolean, visible: boolean): ICompositeBarModelItem { const options = this.options; return { id, name, pinned, order, visible, diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index 6e59e616bcd..f6763258e5e 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -108,14 +108,14 @@ export class ActivityAction extends Action { } export interface ICompositeBarColors { - activeBackgroundColor: Color; - inactiveBackgroundColor: Color; - activeBorderBottomColor: Color; - activeForegroundColor: Color; - inactiveForegroundColor: Color; - badgeBackground: Color; - badgeForeground: Color; - dragAndDropBackground: Color; + activeBackgroundColor?: Color; + inactiveBackgroundColor?: Color; + activeBorderBottomColor?: Color; + activeForegroundColor?: Color; + inactiveForegroundColor?: Color; + badgeBackground?: Color; + badgeForeground?: Color; + dragAndDropBackground?: Color; } export interface IActivityActionItemOptions extends IBaseActionItemOptions { From b76fecb4138aefb0dc1a86f4fe403c3a19ffbd62 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 15:06:12 -0800 Subject: [PATCH 222/290] Strict null check listCommands --- src/tsconfig.strictNullChecks.json | 1 + src/vs/workbench/browser/actions/listCommands.ts | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index d0df318c885..98fe291b7b1 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -93,6 +93,7 @@ "./vs/workbench/api/shared/tasks.ts", "./vs/workbench/browser/actions.ts", "./vs/workbench/browser/actions/layoutActions.ts", + "./vs/workbench/browser/actions/listCommands.ts", "./vs/workbench/browser/actions/navigationActions.ts", "./vs/workbench/browser/actions/workspaceActions.ts", "./vs/workbench/browser/actions/workspaceCommands.ts", diff --git a/src/vs/workbench/browser/actions/listCommands.ts b/src/vs/workbench/browser/actions/listCommands.ts index e89ad255348..7afe64bfa83 100644 --- a/src/vs/workbench/browser/actions/listCommands.ts +++ b/src/vs/workbench/browser/actions/listCommands.ts @@ -88,10 +88,12 @@ function expandMultiSelection(focused: List | PagedList | ITree | Obje const focus = list.getFocus() ? list.getFocus()[0] : undefined; const selection = list.getSelection(); - if (selection && selection.indexOf(focus) >= 0) { + if (selection && typeof focus === 'number' && selection.indexOf(focus) >= 0) { list.setSelection(selection.filter(s => s !== previousFocus)); } else { - list.setSelection(selection.concat(focus)); + if (typeof focus === 'number') { + list.setSelection(selection.concat(focus)); + } } } @@ -636,7 +638,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const selectedNode = tree.getNode(start); const parentNode = selectedNode.parent; - if (!parentNode.parent) { // root + if (!parentNode || !parentNode.parent) { // root scope = undefined; } else { scope = parentNode.element; From a588a963fa2809363dc42b4f6ae3f62e30f4fbbe Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 15:10:01 -0800 Subject: [PATCH 223/290] Strict null check panelActions --- src/tsconfig.strictNullChecks.json | 3 +++ src/vs/platform/actions/common/actions.ts | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 98fe291b7b1..46e3c38c1d5 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -127,6 +127,8 @@ "./vs/workbench/browser/parts/editor/textDiffEditor.ts", "./vs/workbench/browser/parts/editor/textEditor.ts", "./vs/workbench/browser/parts/editor/textResourceEditor.ts", + "./vs/workbench/browser/parts/panel/panelActions.ts", + "./vs/workbench/browser/parts/panel/panelPart.ts", "./vs/workbench/browser/parts/quickinput/quickInputBox.ts", "./vs/workbench/browser/parts/quickinput/quickInputList.ts", "./vs/workbench/browser/parts/quickinput/quickInputUtils.ts", @@ -337,6 +339,7 @@ "./vs/workbench/contrib/url/common/url.contribution.ts", "./vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts", "./vs/workbench/electron-browser/window.ts", + "./vs/workbench/services/activity/browser/activityService.ts", "./vs/workbench/services/activity/common/activity.ts", "./vs/workbench/services/backup/common/backup.ts", "./vs/workbench/services/backup/node/backupFileService.ts", diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index e615685b30b..b3bc081c9c5 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -281,13 +281,13 @@ export class SyncActionDescriptor { private _descriptor: SyncDescriptor0; private _id: string; - private _label: string; + private _label?: string; private _keybindings: IKeybindings | undefined; private _keybindingContext: ContextKeyExpr | undefined; private _keybindingWeight: number | undefined; constructor(ctor: IConstructorSignature2, - id: string, label: string, keybindings?: IKeybindings, keybindingContext?: ContextKeyExpr, keybindingWeight?: number + id: string, label: string | undefined, keybindings?: IKeybindings, keybindingContext?: ContextKeyExpr, keybindingWeight?: number ) { this._id = id; this._label = label; @@ -305,7 +305,7 @@ export class SyncActionDescriptor { return this._id; } - public get label(): string { + public get label(): string | undefined { return this._label; } From 3183a7a0f04fdf269eef08633545054613763e46 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 15:35:36 -0800 Subject: [PATCH 224/290] Strict null check breadcrumbsControl --- src/tsconfig.strictNullChecks.json | 2 ++ .../parts/editor/breadcrumbsControl.ts | 31 ++++++++++++------- .../browser/parts/editor/breadcrumbsPicker.ts | 18 ++++++++--- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 46e3c38c1d5..408ec1a80a1 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -113,7 +113,9 @@ "./vs/workbench/browser/parts/editor/binaryDiffEditor.ts", "./vs/workbench/browser/parts/editor/binaryEditor.ts", "./vs/workbench/browser/parts/editor/breadcrumbs.ts", + "./vs/workbench/browser/parts/editor/breadcrumbsControl.ts", "./vs/workbench/browser/parts/editor/breadcrumbsModel.ts", + "./vs/workbench/browser/parts/editor/breadcrumbsPicker.ts", "./vs/workbench/browser/parts/editor/editor.ts", "./vs/workbench/browser/parts/editor/editorActions.ts", "./vs/workbench/browser/parts/editor/editorCommands.ts", diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 1b9aad2e2fb..84acd81c48f 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -451,13 +451,15 @@ export class BreadcrumbsControl { } else if (element instanceof OutlineElement) { // open symbol in code editor const model = OutlineModel.get(element); - this._codeEditorService.openCodeEditor({ - resource: model.textModel.uri, - options: { - selection: Range.collapseToStart(element.symbol.selectionRange), - revealInCenterIfOutsideViewport: true - } - }, this._getActiveCodeEditor() || null, group === SIDE_GROUP); + if (model) { + this._codeEditorService.openCodeEditor({ + resource: model.textModel.uri, + options: { + selection: Range.collapseToStart(element.symbol.selectionRange), + revealInCenterIfOutsideViewport: true + } + }, this._getActiveCodeEditor() || null, group === SIDE_GROUP); + } } } @@ -640,7 +642,9 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } widget.setFocused(undefined); widget.setSelection(undefined); - groups.activeGroup.activeControl.focus(); + if (groups.activeGroup.activeControl) { + groups.activeGroup.activeControl.focus(); + } } }); KeybindingsRegistry.registerCommandAndKeybindingRule({ @@ -651,15 +655,20 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ handler(accessor) { const editors = accessor.get(IEditorService); const lists = accessor.get(IListService); - const element = lists.lastFocusedList.getFocus(); + const element = lists.lastFocusedList ? lists.lastFocusedList.getFocus() : undefined; if (element instanceof OutlineElement) { + const outlineElement = OutlineModel.get(element); + if (!outlineElement) { + return undefined; + } + // open symbol in editor return editors.openEditor({ - resource: OutlineModel.get(element).textModel.uri, + resource: outlineElement.textModel.uri, options: { selection: Range.collapseToStart(element.symbol.selectionRange) } }, SIDE_GROUP); - } else if (URI.isUri(element.resource)) { + } else if (element && URI.isUri(element.resource)) { // open file in editor return editors.openEditor({ resource: element.resource, diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index b0d991ac9eb..ff004ddd94a 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -25,9 +25,10 @@ import { ResourceLabels, IResourceLabel, DEFAULT_LABELS_CONTAINER } from 'vs/wor 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'; -import { IAsyncDataSource, ITreeRenderer, ITreeNode, ITreeFilter, TreeVisibility, ITreeSorter } from 'vs/base/browser/ui/tree/tree'; +import { IAsyncDataSource, ITreeRenderer, ITreeNode, ITreeFilter, TreeVisibility, ITreeSorter, IDataSource } from 'vs/base/browser/ui/tree/tree'; import { OutlineVirtualDelegate, OutlineGroupRenderer, OutlineElementRenderer, OutlineItemComparator, OutlineIdentityProvider, OutlineNavigationLabelProvider, OutlineDataSource, OutlineSortOrder, OutlineItem } from 'vs/editor/contrib/documentSymbols/outlineTree'; import { IIdentityProvider, IListVirtualDelegate, IKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/list/list'; +import { IDataTreeOptions } from 'vs/base/browser/ui/tree/dataTree'; export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker { const ctor: IConstructorSignature1 = element instanceof FileElement @@ -156,7 +157,7 @@ export abstract class BreadcrumbsPicker { protected abstract _setInput(element: BreadcrumbElement): Promise; protected abstract _createTree(container: HTMLElement): Tree; - protected abstract _getTargetFromEvent(element: any, payload: UIEvent): any | undefined; + protected abstract _getTargetFromEvent(element: any, payload: UIEvent | undefined): any | undefined; } //#region - Files @@ -329,7 +330,7 @@ class FileFilter implements ITreeFilter { return true; } - const expression = this._cachedExpressions.get(folder.uri.toString()); + const expression = this._cachedExpressions.get(folder.uri.toString())!; return !expression(element.resource.path, basename(element.resource)); } } @@ -450,7 +451,14 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { } protected _createTree(container: HTMLElement) { - return this._instantiationService.createInstance( + return this._instantiationService.createInstance< + HTMLElement, + IListVirtualDelegate, + ITreeRenderer[], + IDataSource, + IDataTreeOptions, + WorkbenchDataTree + >( WorkbenchDataTree, container, new OutlineVirtualDelegate(), @@ -474,7 +482,7 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { protected _setInput(input: BreadcrumbElement): Promise { const element = input as TreeElement; - const model = OutlineModel.get(element); + const model = OutlineModel.get(element)!; const tree = this._tree as WorkbenchDataTree; tree.setInput(model); From 50d502af617d15872b281ec8a6207446917c5497 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 15:42:00 -0800 Subject: [PATCH 225/290] Strict null check title control --- src/tsconfig.strictNullChecks.json | 1 + .../browser/parts/editor/titleControl.ts | 17 +++++++++------- src/vs/workbench/common/resources.ts | 20 +++++++++---------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 408ec1a80a1..7eb6cc2e03d 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -129,6 +129,7 @@ "./vs/workbench/browser/parts/editor/textDiffEditor.ts", "./vs/workbench/browser/parts/editor/textEditor.ts", "./vs/workbench/browser/parts/editor/textResourceEditor.ts", + "./vs/workbench/browser/parts/editor/titleControl.ts", "./vs/workbench/browser/parts/panel/panelActions.ts", "./vs/workbench/browser/parts/panel/panelPart.ts", "./vs/workbench/browser/parts/quickinput/quickInputBox.ts", diff --git a/src/vs/workbench/browser/parts/editor/titleControl.ts b/src/vs/workbench/browser/parts/editor/titleControl.ts index 0a2b6fb57c7..fb31f528691 100644 --- a/src/vs/workbench/browser/parts/editor/titleControl.ts +++ b/src/vs/workbench/browser/parts/editor/titleControl.ts @@ -264,12 +264,14 @@ export abstract class TitleControl extends Themable { } // Drag Image - let label = this.group.activeEditor.getName(); - if (this.accessor.partOptions.showTabs && this.group.count > 1) { - label = localize('draggedEditorGroup', "{0} (+{1})", label, this.group.count - 1); - } + if (this.group.activeEditor) { + let label = this.group.activeEditor.getName(); + if (this.accessor.partOptions.showTabs && this.group.count > 1) { + label = localize('draggedEditorGroup', "{0} (+{1})", label, this.group.count - 1); + } - applyDragImage(e, label, 'monaco-editor-group-drag-image'); + applyDragImage(e, label, 'monaco-editor-group-drag-image'); + } })); // Drag end @@ -304,7 +306,7 @@ export abstract class TitleControl extends Themable { onHide: () => { // restore previous context - this.resourceContext.set(currentContext); + this.resourceContext.set(currentContext || null); // restore focus to active group this.accessor.activeGroup.focus(); @@ -355,7 +357,8 @@ export abstract class TitleControl extends Themable { } dispose(): void { - this.breadcrumbsControl = dispose(this.breadcrumbsControl); + dispose(this.breadcrumbsControl); + this.breadcrumbsControl = undefined; this.editorToolBarMenuDisposables = dispose(this.editorToolBarMenuDisposables); super.dispose(); diff --git a/src/vs/workbench/common/resources.ts b/src/vs/workbench/common/resources.ts index b8cf29b7272..6a597a960ff 100644 --- a/src/vs/workbench/common/resources.ts +++ b/src/vs/workbench/common/resources.ts @@ -25,11 +25,11 @@ export class ResourceContextKey extends Disposable implements IContextKey { static HasResource = new RawContextKey('resourceSet', false); static IsFileSystemResource = new RawContextKey('isFileSystemResource', false); - private readonly _resourceKey: IContextKey; - private readonly _schemeKey: IContextKey; - private readonly _filenameKey: IContextKey; + private readonly _resourceKey: IContextKey; + private readonly _schemeKey: IContextKey; + private readonly _filenameKey: IContextKey; private readonly _langIdKey: IContextKey; - private readonly _extensionKey: IContextKey; + private readonly _extensionKey: IContextKey; private readonly _hasResource: IContextKey; private readonly _isFileSystemResource: IContextKey; @@ -59,15 +59,15 @@ export class ResourceContextKey extends Disposable implements IContextKey { })); } - set(value: URI) { + set(value: URI | null) { if (!ResourceContextKey._uriEquals(this._resourceKey.get(), value)) { this._resourceKey.set(value); - this._schemeKey.set(value && value.scheme); - this._filenameKey.set(value && basename(value)); + this._schemeKey.set(value ? value.scheme : null); + this._filenameKey.set(value ? basename(value) : null); this._langIdKey.set(value ? this._modeService.getModeIdByFilepathOrFirstLine(value.fsPath) : null); - this._extensionKey.set(value && extname(value)); + this._extensionKey.set(value ? extname(value) : null); this._hasResource.set(!!value); - this._isFileSystemResource.set(value && this._fileService.canHandleResource(value)); + this._isFileSystemResource.set(value ? this._fileService.canHandleResource(value) : false); } } @@ -82,7 +82,7 @@ export class ResourceContextKey extends Disposable implements IContextKey { } get(): URI | undefined { - return this._resourceKey.get(); + return this._resourceKey.get() || undefined; } private static _uriEquals(a: URI | undefined | null, b: URI | undefined | null): boolean { From a5d63ae52e4f8cbfddba4dd8151d81834592e7ec Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 15:53:55 -0800 Subject: [PATCH 226/290] Strict null work on tabsTitleControl --- src/tsconfig.strictNullChecks.json | 2 + .../parts/editor/noTabsTitleControl.ts | 26 +++++--- .../browser/parts/editor/tabsTitleControl.ts | 61 ++++++++++++------- src/vs/workbench/common/editor.ts | 2 +- 4 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 7eb6cc2e03d..835e5e859a2 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -123,9 +123,11 @@ "./vs/workbench/browser/parts/editor/editorDropTarget.ts", "./vs/workbench/browser/parts/editor/editorPicker.ts", "./vs/workbench/browser/parts/editor/editorWidgets.ts", + "./vs/workbench/browser/parts/editor/noTabsTitleControl.ts", "./vs/workbench/browser/parts/editor/rangeDecorations.ts", "./vs/workbench/browser/parts/editor/resourceViewer.ts", "./vs/workbench/browser/parts/editor/sideBySideEditor.ts", + "./vs/workbench/browser/parts/editor/tabsTitleControl.ts", "./vs/workbench/browser/parts/editor/textDiffEditor.ts", "./vs/workbench/browser/parts/editor/textEditor.ts", "./vs/workbench/browser/parts/editor/textResourceEditor.ts", diff --git a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts index 4e1e729e2b7..e250e63ab42 100644 --- a/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/noTabsTitleControl.ts @@ -16,7 +16,7 @@ import { CLOSE_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/edito import { Color } from 'vs/base/common/color'; interface IRenderedEditorLabel { - editor: IEditorInput; + editor?: IEditorInput; pinned: boolean; } @@ -72,8 +72,16 @@ export class NoTabsTitleControl extends TitleControl { this._register(addDisposableListener(this.titleContainer, TouchEventType.Tap, (e: GestureEvent) => this.onTitleClick(e))); // Context Menu - this._register(addDisposableListener(this.titleContainer, EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu(this.group.activeEditor, e, this.titleContainer))); - this._register(addDisposableListener(this.titleContainer, TouchEventType.Contextmenu, (e: Event) => this.onContextMenu(this.group.activeEditor, e, this.titleContainer))); + this._register(addDisposableListener(this.titleContainer, EventType.CONTEXT_MENU, (e: Event) => { + if (this.group.activeEditor) { + this.onContextMenu(this.group.activeEditor, e, this.titleContainer); + } + })); + this._register(addDisposableListener(this.titleContainer, TouchEventType.Contextmenu, (e: Event) => { + if (this.group.activeEditor) { + this.onContextMenu(this.group.activeEditor, e, this.titleContainer); + } + })); } private onTitleLabelClick(e: MouseEvent): void { @@ -95,7 +103,9 @@ export class NoTabsTitleControl extends TitleControl { 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); + if (this.group.activeEditor) { + this.group.closeEditor(this.group.activeEditor); + } } } @@ -167,7 +177,7 @@ export class NoTabsTitleControl extends TitleControl { if ( !this.activeLabel.editor && this.group.activeEditor || // active editor changed from null => editor this.activeLabel.editor && !this.group.activeEditor || // active editor changed from editor => null - !this.group.isActive(this.activeLabel.editor) // active editor changed from editorA => editorB + (!this.activeLabel.editor || !this.group.isActive(this.activeLabel.editor)) // active editor changed from editorA => editorB ) { fn(); @@ -197,10 +207,10 @@ export class NoTabsTitleControl extends TitleControl { private redraw(): void { const editor = this.group.activeEditor; - const isEditorPinned = this.group.isPinned(this.group.activeEditor); + const isEditorPinned = this.group.activeEditor ? this.group.isPinned(this.group.activeEditor) : false; const isGroupActive = this.accessor.activeGroup === this.group; - this.activeLabel = { editor, pinned: isEditorPinned }; + this.activeLabel = { editor: editor || undefined, pinned: isEditorPinned }; // Update Breadcrumbs if (this.breadcrumbsControl) { @@ -244,7 +254,7 @@ export class NoTabsTitleControl extends TitleControl { title = ''; // dont repeat what is already shown } - this.editorLabel.setResource({ name, description, resource: resource || undefined }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] }); + this.editorLabel.setResource({ name, description, resource: resource || undefined }, { title: typeof title === 'string' ? title : undefined, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] }); if (isGroupActive) { this.editorLabel.element.style.color = this.getColor(TAB_ACTIVE_FOREGROUND); } else { diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index e2bfb8d2cd7..aa38992e096 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -212,7 +212,7 @@ export class TabsTitleControl extends TitleControl { if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) { isLocalDragAndDrop = true; - const localDraggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier; + const localDraggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)![0].identifier; if (this.group.id === localDraggedEditor.groupId && this.group.getIndexOfEditor(localDraggedEditor.editor) === this.group.count - 1) { e.dataTransfer!.dropEffect = 'none'; return; @@ -469,7 +469,10 @@ export class TabsTitleControl extends TitleControl { } // Open tabs editor - this.group.openEditor(this.group.getEditor(index)); + const input = this.group.getEditor(index); + if (input) { + this.group.openEditor(input); + } return undefined; }; @@ -477,7 +480,10 @@ export class TabsTitleControl extends TitleControl { const showContextMenu = (e: Event) => { EventHelper.stop(e); - this.onContextMenu(this.group.getEditor(index), e, tab); + const input = this.group.getEditor(index); + if (input) { + this.onContextMenu(input, e, tab); + } }; // Open on Click / Touch @@ -524,7 +530,10 @@ export class TabsTitleControl extends TitleControl { // Run action on Enter/Space if (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space)) { handled = true; - this.group.openEditor(this.group.getEditor(index)); + const input = this.group.getEditor(index); + if (input) { + this.group.openEditor(input); + } } // Navigate in editors @@ -569,12 +578,19 @@ export class TabsTitleControl extends TitleControl { disposables.push(addDisposableListener(tab, EventType.CONTEXT_MENU, (e: Event) => { EventHelper.stop(e, true); - this.onContextMenu(this.group.getEditor(index), e, tab); + const input = this.group.getEditor(index); + if (input) { + this.onContextMenu(input, e, tab); + } }, true /* use capture to fix https://github.com/Microsoft/vscode/issues/19145 */)); // Drag support disposables.push(addDisposableListener(tab, EventType.DRAG_START, (e: DragEvent) => { const editor = this.group.getEditor(index); + if (!editor) { + return; + } + this.editorTransfer.setData([new DraggedEditorIdentifier({ editor, groupId: this.group.id })], DraggedEditorIdentifier.prototype); e.dataTransfer!.effectAllowed = 'copyMove'; @@ -608,7 +624,7 @@ export class TabsTitleControl extends TitleControl { if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) { isLocalDragAndDrop = true; - const localDraggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier; + const localDraggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)![0].identifier; if (localDraggedEditor.editor === this.group.getEditor(index) && localDraggedEditor.groupId === this.group.id) { e.dataTransfer!.dropEffect = 'none'; return; @@ -649,7 +665,7 @@ export class TabsTitleControl extends TitleControl { private isSupportedDropTransfer(e: DragEvent): boolean { if (this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype)) { - const group = this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)[0]; + const group = this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)![0]; if (group.identifier === this.group.id) { return false; // groups cannot be dropped on title area it originates from } @@ -764,7 +780,7 @@ export class TabsTitleControl extends TitleControl { // Remove description if all descriptions are identical if (descriptions.length === 1) { - for (const label of mapDescriptionToDuplicates.get(descriptions[0])) { + for (const label of mapDescriptionToDuplicates.get(descriptions[0]) || []) { label.description = ''; } @@ -774,7 +790,7 @@ export class TabsTitleControl extends TitleControl { // Shorten descriptions const shortenedDescriptions = shorten(descriptions); descriptions.forEach((description, i) => { - for (const label of mapDescriptionToDuplicates.get(description)) { + for (const label of mapDescriptionToDuplicates.get(description) || []) { label.description = shortenedDescriptions[i]; } }); @@ -860,7 +876,7 @@ export class TabsTitleControl extends TitleControl { tabContainer.title = title; // Label - tabLabelWidget.setResource({ name, description, resource: toResource(editor, { supportSideBySide: true }) }, { title, extraClasses: ['tab-label'], italic: !this.group.isPinned(editor) }); + tabLabelWidget.setResource({ name, description, resource: toResource(editor, { supportSideBySide: true }) || undefined }, { title, extraClasses: ['tab-label'], italic: !this.group.isPinned(editor) }); } private redrawEditorActiveAndDirty(isGroupActive: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel): void { @@ -963,7 +979,7 @@ export class TabsTitleControl extends TitleControl { layout(dimension: Dimension): void { this.dimension = dimension; - const activeTab = this.getTab(this.group.activeEditor); + const activeTab = this.group.activeEditor ? this.getTab(this.group.activeEditor) : undefined; if (!activeTab || !this.dimension) { return; } @@ -980,7 +996,7 @@ export class TabsTitleControl extends TitleControl { } private doLayout(dimension: Dimension): void { - const activeTab = this.getTab(this.group.activeEditor); + const activeTab = this.group.activeEditor ? this.getTab(this.group.activeEditor) : undefined; if (!activeTab) { return; } @@ -993,8 +1009,8 @@ export class TabsTitleControl extends TitleControl { const visibleContainerWidth = this.tabsContainer.offsetWidth; const totalContainerWidth = this.tabsContainer.scrollWidth; - let activeTabPosX: number | undefined; - let activeTabWidth: number | undefined; + let activeTabPosX: number; + let activeTabWidth: number; if (!this.blockRevealActiveTab) { activeTabPosX = activeTab.offsetLeft; @@ -1015,20 +1031,20 @@ export class TabsTitleControl extends TitleControl { // Reveal the active one const containerScrollPosX = this.tabsScrollbar.getScrollPosition().scrollLeft; - const activeTabFits = activeTabWidth <= visibleContainerWidth; + const activeTabFits = activeTabWidth! <= visibleContainerWidth; // Tab is overflowing to the right: Scroll minimally until the element is fully visible to the right // Note: only try to do this if we actually have enough width to give to show the tab fully! - if (activeTabFits && containerScrollPosX + visibleContainerWidth < activeTabPosX + activeTabWidth) { + if (activeTabFits && containerScrollPosX + visibleContainerWidth < activeTabPosX! + activeTabWidth!) { this.tabsScrollbar.setScrollPosition({ - scrollLeft: containerScrollPosX + ((activeTabPosX + activeTabWidth) /* right corner of tab */ - (containerScrollPosX + visibleContainerWidth) /* right corner of view port */) + scrollLeft: containerScrollPosX + ((activeTabPosX! + activeTabWidth!) /* right corner of tab */ - (containerScrollPosX + visibleContainerWidth) /* right corner of view port */) }); } // Tab is overlflowng to the left or does not fit: Scroll it into view to the left - else if (containerScrollPosX > activeTabPosX || !activeTabFits) { + else if (containerScrollPosX > activeTabPosX! || !activeTabFits) { this.tabsScrollbar.setScrollPosition({ - scrollLeft: activeTabPosX + scrollLeft: activeTabPosX! }); } } @@ -1071,7 +1087,7 @@ export class TabsTitleControl extends TitleControl { // Local Editor DND if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) { - const draggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)[0].identifier; + const draggedEditor = this.editorTransfer.getData(DraggedEditorIdentifier.prototype)![0].identifier; const sourceGroup = this.accessor.getGroup(draggedEditor.groupId); // Move editor to target position and index @@ -1090,7 +1106,7 @@ export class TabsTitleControl extends TitleControl { // Local Editor Group DND else if (this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype)) { - const sourceGroup = this.accessor.getGroup(this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)[0].identifier); + const sourceGroup = this.accessor.getGroup(this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype)![0].identifier); const mergeGroupOptions: IMergeGroupOptions = { index: targetIndex }; if (!this.isMoveOperation(e, sourceGroup.id)) { @@ -1119,7 +1135,8 @@ export class TabsTitleControl extends TitleControl { dispose(): void { super.dispose(); - this.layoutScheduled = dispose(this.layoutScheduled); + dispose(this.layoutScheduled); + this.layoutScheduled = undefined; } } diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index eb745aa83fc..a254b632c2e 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -974,7 +974,7 @@ export interface IResourceOptions { filter?: string | string[]; } -export function toResource(editor: IEditorInput, options?: IResourceOptions): URI | null { +export function toResource(editor: IEditorInput | null, options?: IResourceOptions): URI | null { if (!editor) { return null; } From 0589591234175143ca39cc9363d93a4fb30134ce Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 16:01:57 -0800 Subject: [PATCH 227/290] Strict null work in editorGroupView --- src/vs/base/browser/dom.ts | 2 +- .../actions/browser/menuItemActionItem.ts | 2 +- src/vs/workbench/browser/legacyLayout.ts | 10 ++--- .../parts/editor/editor.contribution.ts | 2 +- .../browser/parts/editor/editorGroupView.ts | 44 ++++++++++++------- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 2ac95d2b9c6..b74f87d67a3 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -615,7 +615,7 @@ export interface IDomNodePagePosition { height: number; } -export function size(element: HTMLElement, width: number, height: number): void { +export function size(element: HTMLElement, width: number | null, height: number | null): void { if (typeof width === 'number') { element.style.width = `${width}px`; } diff --git a/src/vs/platform/actions/browser/menuItemActionItem.ts b/src/vs/platform/actions/browser/menuItemActionItem.ts index 872b66f8e5a..8b0275c16cc 100644 --- a/src/vs/platform/actions/browser/menuItemActionItem.ts +++ b/src/vs/platform/actions/browser/menuItemActionItem.ts @@ -76,7 +76,7 @@ class AlternativeKeyEmitter extends Emitter { } } -export function fillInContextMenuActions(menu: IMenu, options: IMenuActionOptions, target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, contextMenuService: IContextMenuService, isPrimaryGroup?: (group: string) => boolean): void { +export function fillInContextMenuActions(menu: IMenu, options: IMenuActionOptions | undefined, target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, contextMenuService: IContextMenuService, isPrimaryGroup?: (group: string) => boolean): void { const groups = menu.getActions(options); const getAlternativeActions = AlternativeKeyEmitter.getInstance(contextMenuService).isPressed; diff --git a/src/vs/workbench/browser/legacyLayout.ts b/src/vs/workbench/browser/legacyLayout.ts index 1d91550fcab..e47480d7e9f 100644 --- a/src/vs/workbench/browser/legacyLayout.ts +++ b/src/vs/workbench/browser/legacyLayout.ts @@ -388,9 +388,9 @@ export class WorkbenchLegacyLayout extends Disposable implements IVerticalSashLa })); this._register(this.sashXOne.onDidReset(() => { - let activeViewlet = this.viewletService.getActiveViewlet(); - let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth(); - this.sidebarWidth = Math.max(optimalWidth, DEFAULT_SIDEBAR_PART_WIDTH); + const activeViewlet = this.viewletService.getActiveViewlet(); + const optimalWidth = activeViewlet ? activeViewlet.getOptimalWidth() : null; + this.sidebarWidth = typeof optimalWidth === 'number' ? Math.max(optimalWidth, DEFAULT_SIDEBAR_PART_WIDTH) : DEFAULT_SIDEBAR_PART_WIDTH; this.storageService.store(WorkbenchLegacyLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); this.partService.setSideBarHidden(false); @@ -596,10 +596,10 @@ export class WorkbenchLegacyLayout extends Disposable implements IVerticalSashLa size(activitybarContainer, null, activityBarSize.height); if (sidebarPosition === Position.LEFT) { this.parts.activitybar.getContainer().style.right = ''; - position(activitybarContainer, this.titlebarHeight, null, 0, 0); + position(activitybarContainer, this.titlebarHeight, undefined, 0, 0); } else { this.parts.activitybar.getContainer().style.left = ''; - position(activitybarContainer, this.titlebarHeight, 0, 0, null); + position(activitybarContainer, this.titlebarHeight, 0, 0, undefined); } if (isActivityBarHidden) { hide(activitybarContainer); diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 5c1e6ef0f87..2daccc8005a 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -103,7 +103,7 @@ Registry.as(EditorExtensions.Editors).registerEditor( interface ISerializedUntitledEditorInput { resource: string; resourceJSON: object; - modeId: string; + modeId: string | null; encoding: string; } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 0a3d443d567..421352abd2a 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -411,6 +411,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } const activeEditor = this._group.activeEditor; + if (!activeEditor) { + return Promise.resolve(); + } + options.pinned = this._group.isPinned(activeEditor); // preserve pinned state options.preserveFocus = true; // handle focus after editor is opened @@ -561,7 +565,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Pin preview editor once user disables preview if (event.oldPartOptions.enablePreview && !event.newPartOptions.enablePreview) { - this.pinEditor(this._group.previewEditor); + if (this._group.previewEditor) { + this.pinEditor(this._group.previewEditor); + } } } @@ -705,7 +711,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this._onDidFocus.fire(); } - pinEditor(editor: EditorInput = this.activeEditor): void { + pinEditor(editor: EditorInput | undefined = this.activeEditor || undefined): void { if (editor && !this._group.isPinned(editor)) { // Update model @@ -743,7 +749,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return this.doOpenEditor(editor, options); } - private doOpenEditor(editor: EditorInput, options?: EditorOptions): Promise { + private doOpenEditor(editor: EditorInput, options?: EditorOptions): Promise { // Determine options const openEditorOptions: IEditorOpenOptions = { @@ -752,7 +758,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { active: this._group.count === 0 || !options || !options.inactive }; - if (!openEditorOptions.active && !openEditorOptions.pinned && this._group.isPreview(this._group.activeEditor)) { + if (!openEditorOptions.active && !openEditorOptions.pinned && this._group.activeEditor && this._group.isPreview(this._group.activeEditor)) { // Special case: we are to open an editor inactive and not pinned, but the current active // editor is also not pinned, which means it will get replaced with this one. As such, // the editor can only be active. @@ -781,13 +787,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView { this._group.openEditor(editor, openEditorOptions); // Show editor - return this.doShowEditor(editor, openEditorOptions.active, options); + return this.doShowEditor(editor, !!openEditorOptions.active, options); } - private doShowEditor(editor: EditorInput, active: boolean, options?: EditorOptions): Promise { + private doShowEditor(editor: EditorInput, active: boolean, options?: EditorOptions): Promise { // Show in editor control if the active editor changed - let openEditorPromise: Promise; + let openEditorPromise: Promise; if (active) { openEditorPromise = this.editorControl.openEditor(editor, options).then(result => { @@ -830,7 +836,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { actions }); - Event.once(handle.onDidClose)(() => dispose(actions.primary)); + Event.once(handle.onDidClose)(() => actions.primary && dispose(actions.primary)); } // Event @@ -855,7 +861,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Do not modify original array editors = editors.slice(0); - let result: IEditor; + let result: IEditor | null; // Use the first editor as active editor const { editor, options } = editors.shift()!; @@ -958,7 +964,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region closeEditor() - closeEditor(editor: EditorInput = this.activeEditor, options?: ICloseEditorOptions): Promise { + closeEditor(editor: EditorInput | undefined = this.activeEditor || undefined, options?: ICloseEditorOptions): Promise { if (!editor) { return Promise.resolve(); } @@ -1015,7 +1021,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } // Update model - this._group.closeEditor(editorToClose); + if (editorToClose) { + this._group.closeEditor(editorToClose); + } // Open next active if there are more to show const nextActiveEditor = this._group.activeEditor; @@ -1038,7 +1046,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { else { // Forward to editor control - this.editorControl.closeEditor(editorToClose); + if (editorToClose) { + this.editorControl.closeEditor(editorToClose); + } // Restore focus to group container as needed unless group gets closed if (restoreFocus && !closeEmptyGroup) { @@ -1077,7 +1087,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return Promise.resolve(false); // no veto } - const editor = editors.shift(); + const editor = editors.shift()!; // To prevent multiple confirmation dialogs from showing up one after the other // we check if a pending confirmation is currently showing and if so, join that @@ -1376,8 +1386,8 @@ export class EditorGroupView extends Themable implements IEditorGroupView { get maximumWidth(): number { return this.editorControl.maximumWidth; } get maximumHeight(): number { return this.editorControl.maximumHeight; } - private _onDidChange = this._register(new Relay<{ width: number; height: number; }>()); - readonly onDidChange: Event<{ width: number; height: number; }> = this._onDidChange.event; + private _onDidChange = this._register(new Relay<{ width: number; height: number; } | undefined>()); + readonly onDidChange: Event<{ width: number; height: number; } | undefined> = this._onDidChange.event; layout(width: number, height: number): void { this.dimension = new Dimension(width, height); @@ -1422,7 +1432,7 @@ class EditorOpeningEvent implements IEditorOpeningEvent { constructor( private _group: GroupIdentifier, private _editor: EditorInput, - private _options: EditorOptions + private _options: EditorOptions | undefined ) { } @@ -1434,7 +1444,7 @@ class EditorOpeningEvent implements IEditorOpeningEvent { return this._editor; } - get options(): EditorOptions { + get options(): EditorOptions | undefined { return this._options; } From 6937635d1d6e132d5cdbe68f82d3a1e8a36cf712 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 16:28:07 -0800 Subject: [PATCH 228/290] Supress some strict null errors in mainThreadSavePartcipants --- .../api/mainThreadSaveParticipant.test.ts | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts index 2cc91becc3c..6fc405bc679 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts @@ -47,27 +47,27 @@ suite('MainThreadSaveParticipant', function () { // No new line for empty lines let lineContent = ''; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // No new line if last line already empty - lineContent = `Hello New Line${model.textEditorModel.getEOL()}`; - model.textEditorModel.setValue(lineContent); + lineContent = `Hello New Line${model.textEditorModel!.getEOL()}`; + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // New empty line added (single line) lineContent = 'Hello New Line'; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); - assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`); + assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`); // New empty line added (multi line) - lineContent = `Hello New Line${model.textEditorModel.getEOL()}Hello New Line${model.textEditorModel.getEOL()}Hello New Line`; - model.textEditorModel.setValue(lineContent); + lineContent = `Hello New Line${model.textEditorModel!.getEOL()}Hello New Line${model.textEditorModel!.getEOL()}Hello New Line`; + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); - assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`); + assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`); }); test('trim final new lines', async function () { @@ -78,29 +78,29 @@ suite('MainThreadSaveParticipant', function () { configService.setUserConfiguration('files', { 'trimFinalNewlines': true }); const participant = new TrimFinalNewLinesParticipant(configService, undefined!); const textContent = 'Trim New Line'; - const eol = `${model.textEditorModel.getEOL()}`; + const eol = `${model.textEditorModel!.getEOL()}`; // No new line removal if last line is not new line let lineContent = `${textContent}`; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // No new line removal if last line is single new line lineContent = `${textContent}${eol}`; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // Remove new line (single line with two new lines) lineContent = `${textContent}${eol}${eol}`; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`); // Remove new lines (multiple lines with multiple new lines) lineContent = `${textContent}${eol}${textContent}${eol}${eol}${eol}`; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${textContent}${eol}`); }); @@ -116,33 +116,33 @@ suite('MainThreadSaveParticipant', function () { // single line let lineContent = `${textContent}`; - model.textEditorModel.setValue(lineContent); + model.textEditorModel!.setValue(lineContent); // apply edits and push to undo stack. let textEdits = [{ range: new Range(1, 14, 1, 14), text: '.', forceMoveMarkers: false }]; - model.textEditorModel.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; }); + model.textEditorModel!.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; }); // undo - model.textEditorModel.undo(); + model.textEditorModel!.undo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}`); // trim final new lines should not mess the undo stack await participant.participate(model, { reason: SaveReason.EXPLICIT }); - model.textEditorModel.redo(); + model.textEditorModel!.redo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}.`); }); test('trim final new lines bug#46075', async function () { - const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8'); + const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8'); await model.load(); const configService = new TestConfigurationService(); configService.setUserConfiguration('files', { 'trimFinalNewlines': true }); const participant = new TrimFinalNewLinesParticipant(configService, undefined!); const textContent = 'Test'; - const eol = `${model.textEditorModel.getEOL()}`; + const eol = `${model.textEditorModel!.getEOL()}`; let content = `${textContent}${eol}${eol}`; - model.textEditorModel.setValue(content); + model.textEditorModel!.setValue(content); // save many times for (let i = 0; i < 10; i++) { @@ -153,9 +153,9 @@ suite('MainThreadSaveParticipant', function () { assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`); // undo should go back to previous content immediately - model.textEditorModel.undo(); + model.textEditorModel!.undo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${eol}`); - model.textEditorModel.redo(); + model.textEditorModel!.redo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`); }); }); From 6f6aa562755e5b8df57760ad34f741ab6b9827bb Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 16:33:56 -0800 Subject: [PATCH 229/290] Strict null work in keybindingsEditorContribution --- .../browser/keybindingsEditorContribution.ts | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts index 35f7916e436..06dec075f30 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts @@ -14,7 +14,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { registerEditorContribution, ServicesAccessor, registerEditorCommand, EditorCommand } from 'vs/editor/browser/editorExtensions'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2'; import { SmartSnippetInserter } from 'vs/workbench/contrib/preferences/common/smartSnippetInserter'; import { DefineKeybindingOverlayWidget } from 'vs/workbench/contrib/preferences/browser/keybindingWidgets'; @@ -42,8 +42,8 @@ export class DefineKeybindingController extends Disposable implements editorComm return editor.getContribution(DefineKeybindingController.ID); } - private _keybindingWidgetRenderer: KeybindingWidgetRenderer; - private _keybindingDecorationRenderer: KeybindingEditorDecorationsRenderer; + private _keybindingWidgetRenderer?: KeybindingWidgetRenderer; + private _keybindingDecorationRenderer?: KeybindingEditorDecorationsRenderer; constructor( private _editor: ICodeEditor, @@ -51,9 +51,6 @@ export class DefineKeybindingController extends Disposable implements editorComm ) { super(); - this._keybindingWidgetRenderer = null; - this._keybindingDecorationRenderer = null; - this._register(this._editor.onDidChangeModel(e => this._update())); this._update(); } @@ -62,7 +59,7 @@ export class DefineKeybindingController extends Disposable implements editorComm return DefineKeybindingController.ID; } - get keybindingWidgetRenderer(): KeybindingWidgetRenderer { + get keybindingWidgetRenderer(): KeybindingWidgetRenderer | undefined { return this._keybindingWidgetRenderer; } @@ -99,7 +96,7 @@ export class DefineKeybindingController extends Disposable implements editorComm private _disposeKeybindingWidgetRenderer(): void { if (this._keybindingWidgetRenderer) { this._keybindingWidgetRenderer.dispose(); - this._keybindingWidgetRenderer = null; + this._keybindingWidgetRenderer = undefined; } } @@ -112,7 +109,7 @@ export class DefineKeybindingController extends Disposable implements editorComm private _disposeKeybindingDecorationRenderer(): void { if (this._keybindingDecorationRenderer) { this._keybindingDecorationRenderer.dispose(); - this._keybindingDecorationRenderer = null; + this._keybindingDecorationRenderer = undefined; } } } @@ -140,7 +137,7 @@ export class KeybindingWidgetRenderer extends Disposable { private _onAccepted(keybinding: string): void { this._editor.focus(); - if (keybinding) { + if (keybinding && this._editor.hasModel()) { const regexp = new RegExp(/\\/g); const backslash = regexp.test(keybinding); if (backslash) { @@ -169,7 +166,7 @@ export class KeybindingEditorDecorationsRenderer extends Disposable { private _dec: string[] = []; constructor( - private _editor: ICodeEditor, + private _editor: IActiveCodeEditor, @IKeybindingService private readonly _keybindingService: IKeybindingService, ) { super(); @@ -207,7 +204,7 @@ export class KeybindingEditorDecorationsRenderer extends Disposable { this._dec = this._editor.deltaDecorations(this._dec, newDecorations); } - private _getDecorationForEntry(model: ITextModel, entry: Node): IModelDeltaDecoration { + private _getDecorationForEntry(model: ITextModel, entry: Node): IModelDeltaDecoration | null { if (!Array.isArray(entry.children)) { return null; } @@ -239,7 +236,7 @@ export class KeybindingEditorDecorationsRenderer extends Disposable { } if (!resolvedKeybinding.isWYSIWYG()) { const uiLabel = resolvedKeybinding.getLabel(); - if (value.value.toLowerCase() === uiLabel.toLowerCase()) { + if (typeof uiLabel === 'string' && value.value.toLowerCase() === uiLabel.toLowerCase()) { // coincidentally, this is actually WYSIWYG return null; } @@ -249,7 +246,7 @@ export class KeybindingEditorDecorationsRenderer extends Disposable { return this._createDecoration(false, resolvedKeybinding.getLabel(), usLabel, model, value); } const expectedUserSettingsLabel = resolvedKeybinding.getUserSettingsLabel(); - if (!KeybindingEditorDecorationsRenderer._userSettingsFuzzyEquals(value.value, expectedUserSettingsLabel)) { + if (typeof expectedUserSettingsLabel === 'string' && !KeybindingEditorDecorationsRenderer._userSettingsFuzzyEquals(value.value, expectedUserSettingsLabel)) { return this._createDecoration(false, resolvedKeybinding.getLabel(), usLabel, model, value); } return null; @@ -300,7 +297,7 @@ export class KeybindingEditorDecorationsRenderer extends Disposable { return false; } - private _createDecoration(isError: boolean, uiLabel: string, usLabel: string, model: ITextModel, keyNode: Node): IModelDeltaDecoration { + private _createDecoration(isError: boolean, uiLabel: string | null, usLabel: string | null, model: ITextModel, keyNode: Node): IModelDeltaDecoration { let msg: MarkdownString; let className: string; let beforeContentClassName: string; From 243d3a482b65de5cb24df6e8962dc1a17f3b9940 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 21:41:01 -0800 Subject: [PATCH 230/290] Strict null work in menubar --- src/vs/base/browser/ui/menu/menubar.ts | 2 +- src/vs/platform/menubar/common/menubar.ts | 2 +- .../browser/parts/titlebar/menubarControl.ts | 45 +++++++++++-------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 4506ec9f488..289bfd8f369 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -22,7 +22,7 @@ const $ = DOM.$; export interface IMenuBarOptions { enableMnemonics?: boolean; visibility?: string; - getKeybinding?: (action: IAction) => ResolvedKeybinding; + getKeybinding?: (action: IAction) => ResolvedKeybinding | undefined; alwaysOnMnemonics?: boolean; } diff --git a/src/vs/platform/menubar/common/menubar.ts b/src/vs/platform/menubar/common/menubar.ts index 84ceaf14ec2..27294cbb3aa 100644 --- a/src/vs/platform/menubar/common/menubar.ts +++ b/src/vs/platform/menubar/common/menubar.ts @@ -25,7 +25,7 @@ export interface IMenubarMenu { export interface IMenubarKeybinding { label: string; - userSettingsLabel: string; + userSettingsLabel?: string; isNative?: boolean; // Assumed true if missing } diff --git a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts index 254ae288772..0399029f2e6 100644 --- a/src/vs/workbench/browser/parts/titlebar/menubarControl.ts +++ b/src/vs/workbench/browser/parts/titlebar/menubarControl.ts @@ -58,7 +58,7 @@ export class MenubarControl extends Disposable { 'Terminal': IMenu; 'Window'?: IMenu; 'Help': IMenu; - [index: string]: IMenu; + [index: string]: IMenu | undefined; }; private topLevelTitles = { @@ -121,8 +121,11 @@ export class MenubarControl extends Disposable { this.menuUpdater = this._register(new RunOnceScheduler(() => this.doUpdateMenubar(false), 200)); if (isMacintosh || this.currentTitlebarStyleSetting !== 'custom') { - for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { - this._register(this.topLevelMenus[topLevelMenuName].onDidChange(() => this.updateMenubar())); + for (const topLevelMenuName of Object.keys(this.topLevelMenus)) { + const menu = this.topLevelMenus[topLevelMenuName]; + if (menu) { + this._register(menu.onDidChange(() => this.updateMenubar())); + } } this.doUpdateMenubar(true); @@ -441,7 +444,7 @@ export class MenubarControl extends Disposable { return new Action('update.checking', nls.localize('checkingForUpdates', "Checking For Updates..."), undefined, false); case StateType.AvailableForDownload: - return new Action('update.downloadNow', nls.localize({ key: 'download now', comment: ['&& denotes a mnemonic'] }, "D&&ownload Now"), null, true, () => + return new Action('update.downloadNow', nls.localize({ key: 'download now', comment: ['&& denotes a mnemonic'] }, "D&&ownload Now"), undefined, true, () => this.updateService.downloadUpdate()); case StateType.Downloading: @@ -533,9 +536,9 @@ export class MenubarControl extends Disposable { target.pop(); }; - for (let title of Object.keys(this.topLevelMenus)) { + for (const title of Object.keys(this.topLevelMenus)) { const menu = this.topLevelMenus[title]; - if (firstTime) { + if (firstTime && menu) { this._register(menu.onDidChange(() => { const actions = []; updateActions(menu, actions); @@ -544,7 +547,9 @@ export class MenubarControl extends Disposable { } const actions = []; - updateActions(menu, actions); + if (menu) { + updateActions(menu, actions); + } if (!firstTime) { this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) }); @@ -554,7 +559,7 @@ export class MenubarControl extends Disposable { } } - private getMenubarKeybinding(id: string): IMenubarKeybinding { + private getMenubarKeybinding(id: string): IMenubarKeybinding | undefined { const binding = this.keybindingService.lookupKeybinding(id); if (!binding) { return undefined; @@ -563,19 +568,19 @@ export class MenubarControl extends Disposable { // first try to resolve a native accelerator const electronAccelerator = binding.getElectronAccelerator(); if (electronAccelerator) { - return { label: electronAccelerator, userSettingsLabel: binding.getUserSettingsLabel() }; + return { label: electronAccelerator, userSettingsLabel: binding.getUserSettingsLabel() || undefined }; } // we need this fallback to support keybindings that cannot show in electron menus (e.g. chords) const acceleratorLabel = binding.getLabel(); if (acceleratorLabel) { - return { label: acceleratorLabel, isNative: false, userSettingsLabel: binding.getUserSettingsLabel() }; + return { label: acceleratorLabel, isNative: false, userSettingsLabel: binding.getUserSettingsLabel() || undefined }; } - return null; + return undefined; } - private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu, keybindings: { [id: string]: IMenubarKeybinding }) { + private populateMenuItems(menu: IMenu, menuToPopulate: IMenubarMenu, keybindings: { [id: string]: IMenubarKeybinding | undefined }) { let groups = menu.getActions(); for (let group of groups) { const [, actions] = group; @@ -643,15 +648,17 @@ export class MenubarControl extends Disposable { } menubarData.keybindings = this.getAdditionalKeybindings(); - for (let topLevelMenuName of Object.keys(this.topLevelMenus)) { + for (const topLevelMenuName of Object.keys(this.topLevelMenus)) { const menu = this.topLevelMenus[topLevelMenuName]; - let menubarMenu: IMenubarMenu = { items: [] }; - this.populateMenuItems(menu, menubarMenu, menubarData.keybindings); - if (menubarMenu.items.length === 0) { - // Menus are incomplete - return false; + if (menu) { + const menubarMenu: IMenubarMenu = { items: [] }; + this.populateMenuItems(menu, menubarMenu, menubarData.keybindings); + if (menubarMenu.items.length === 0) { + // Menus are incomplete + return false; + } + menubarData.menus[topLevelMenuName] = menubarMenu; } - menubarData.menus[topLevelMenuName] = menubarMenu; } return true; From 3bb9487c4f7ae17d39613e72a9342c7879c64569 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 21:46:27 -0800 Subject: [PATCH 231/290] Strict null check backupModelTracker --- src/tsconfig.strictNullChecks.json | 3 +++ .../contrib/backup/common/backupModelTracker.ts | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 835e5e859a2..218d13ddc5b 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -121,6 +121,7 @@ "./vs/workbench/browser/parts/editor/editorCommands.ts", "./vs/workbench/browser/parts/editor/editorControl.ts", "./vs/workbench/browser/parts/editor/editorDropTarget.ts", + "./vs/workbench/browser/parts/editor/editorGroupView.ts", "./vs/workbench/browser/parts/editor/editorPicker.ts", "./vs/workbench/browser/parts/editor/editorWidgets.ts", "./vs/workbench/browser/parts/editor/noTabsTitleControl.ts", @@ -176,6 +177,8 @@ "./vs/workbench/common/theme.ts", "./vs/workbench/common/viewlet.ts", "./vs/workbench/common/views.ts", + "./vs/workbench/contrib/backup/common/backup.contribution.ts", + "./vs/workbench/contrib/backup/common/backupModelTracker.ts", "./vs/workbench/contrib/backup/common/backupRestorer.ts", "./vs/workbench/contrib/cli/node/cli.contribution.ts", "./vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.ts", diff --git a/src/vs/workbench/contrib/backup/common/backupModelTracker.ts b/src/vs/workbench/contrib/backup/common/backupModelTracker.ts index 68a433394c4..2b245986c9b 100644 --- a/src/vs/workbench/contrib/backup/common/backupModelTracker.ts +++ b/src/vs/workbench/contrib/backup/common/backupModelTracker.ts @@ -65,14 +65,24 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu // Do not backup when auto save after delay is configured if (!this.configuredAutoSaveAfterDelay) { const model = this.textFileService.models.get(event.resource); - this.backupFileService.backupResource(model.getResource(), model.createSnapshot(), model.getVersionId()); + if (model) { + const snapshot = model.createSnapshot(); + if (snapshot) { + this.backupFileService.backupResource(model.getResource(), snapshot, model.getVersionId()); + } + } } } } private onUntitledModelChanged(resource: Uri): void { if (this.untitledEditorService.isDirty(resource)) { - this.untitledEditorService.loadOrCreate({ resource }).then(model => this.backupFileService.backupResource(resource, model.createSnapshot(), model.getVersionId())); + this.untitledEditorService.loadOrCreate({ resource }).then(model => { + const snapshot = model.createSnapshot(); + if (snapshot) { + this.backupFileService.backupResource(resource, snapshot, model.getVersionId()); + } + }); } else { this.discardBackup(resource); } From 713b178898d61d0b68677f41ed58ab2547e68cc5 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 21:50:00 -0800 Subject: [PATCH 232/290] Strict null work openEditor can return null --- .../localizations/browser/localizationsActions.ts | 6 +++--- .../services/editor/browser/editorService.ts | 12 ++++++------ .../services/editor/common/editorService.ts | 8 ++++---- src/vs/workbench/services/history/browser/history.ts | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts b/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts index 62f41d1a3fd..3ee31d1c836 100644 --- a/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts +++ b/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts @@ -36,13 +36,13 @@ export class ConfigureLocaleAction extends Action { super(id, label); } - public run(event?: any): Promise { + public run(event?: any): Promise { const file = URI.file(join(this.environmentService.appSettingsHome, 'locale.json')); return this.fileService.resolveFile(file).then(undefined, (error) => { return this.fileService.createFile(file, ConfigureLocaleAction.DEFAULT_CONTENT); - }).then((stat): Promise | undefined => { + }).then((stat): Promise | null => { if (!stat) { - return undefined; + return null; } return this.editorService.openEditor({ resource: stat.resource diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index b9665358c3b..9e498cf51b4 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -214,11 +214,11 @@ export class EditorService extends Disposable implements EditorServiceImpl { //#region openEditor() - openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IEditorInput | IResourceEditor, optionsOrGroup?: IEditorOptions | ITextEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: GroupIdentifier): Promise { + openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IEditorInput | IResourceEditor, optionsOrGroup?: IEditorOptions | ITextEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: GroupIdentifier): Promise { // Typed Editor Support if (editor instanceof EditorInput) { @@ -241,7 +241,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { return Promise.resolve(null); } - protected doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { + protected doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { return group.openEditor(editor, options); } diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index 18fb4e87975..476c374d219 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -119,10 +119,10 @@ export interface IEditorService { * @returns the editor that opened or NULL if the operation failed or the editor was not * opened to be active. */ - openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; - openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceDiffInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; + openEditor(editor: IResourceSideBySideInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise; /** * Open editors in an editor group. diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index 03234a94c8e..7f52cda2121 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -420,7 +420,7 @@ export class HistoryService extends Disposable implements IHistoryService { this.doNavigate(this.stack[this.index], !acrossEditors).finally(() => this.navigatingInStack = false); } - private doNavigate(location: IStackEntry, withSelection: boolean): Promise { + private doNavigate(location: IStackEntry, withSelection: boolean): Promise { const options: ITextEditorOptions = { revealIfOpened: true // support to navigate across editor groups }; From d3f079fd7ac0b5c81fc66f7b326f37bc24a03a97 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 21:58:13 -0800 Subject: [PATCH 233/290] Mark fields readonly --- src/vs/workbench/common/editor.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index a254b632c2e..2a958ad5466 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -533,7 +533,12 @@ export class SideBySideEditorInput extends EditorInput { static readonly ID: string = 'workbench.editorinputs.sidebysideEditorInput'; - constructor(private name: string, private description: string | null, private _details: EditorInput, private _master: EditorInput) { + constructor( + private readonly name: string, + private readonly description: string | null, + private readonly _details: EditorInput, + private readonly _master: EditorInput + ) { super(); this.registerListeners(); From 181ab9f3db4c7ef2c7be00e6ab6252f36d689308 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 4 Mar 2019 22:00:04 -0800 Subject: [PATCH 234/290] Strict null work on editorService --- src/vs/workbench/common/editor.ts | 4 ++-- src/vs/workbench/services/editor/browser/editorService.ts | 4 ++-- src/vs/workbench/services/editor/common/editorService.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 2a958ad5466..fb00992d23e 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -760,9 +760,9 @@ export class TextEditorOptions extends EditorOptions { private revealInCenterIfOutsideViewport: boolean; private editorViewState: IEditorViewState | null; - static from(input?: IBaseResourceInput): TextEditorOptions | null { + static from(input?: IBaseResourceInput): TextEditorOptions | undefined { if (!input || !input.options) { - return null; + return undefined; } return TextEditorOptions.create(input.options); diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index 9e498cf51b4..d04efc8119d 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -377,7 +377,7 @@ export class EditorService extends Disposable implements EditorServiceImpl { //#region getOpend() - getOpened(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier): IEditorInput { + getOpened(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier): IEditorInput | undefined { return this.doGetOpened(editor); } @@ -626,7 +626,7 @@ export class DelegatingEditorService extends EditorService { this.editorOpenHandler = handler; } - protected doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { + protected doOpenEditor(group: IEditorGroup, editor: IEditorInput, options?: IEditorOptions): Promise { if (!this.editorOpenHandler) { return super.doOpenEditor(group, editor, options); } diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index 476c374d219..e47ffb540bf 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -166,7 +166,7 @@ export interface IEditorService { * * @param group optional to specify a group to check for the editor */ - getOpened(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier): IEditorInput; + getOpened(editor: IResourceInput | IUntitledResourceInput, group?: IEditorGroup | GroupIdentifier): IEditorInput | undefined; /** * Allows to override the opening of editors by installing a handler that will From 7d8845205932983b4029ad58a42385c7a65d3729 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 09:16:17 -0800 Subject: [PATCH 235/290] Strict null check mainThreadSaveParticpants --- src/tsconfig.strictNullChecks.json | 1 + .../mainThreadSaveParticipant.ts | 16 ++++++++-------- .../textfile/common/textFileEditorModel.ts | 4 ++-- .../services/textfile/common/textfiles.ts | 8 ++++++-- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 218d13ddc5b..ff390f15cb9 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -32,6 +32,7 @@ "./vs/workbench/services/timer/**/*.ts" ], "files": [ + "./vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts", "./vs/monaco.d.ts", "./vs/nls.d.ts", "./vs/nls.mock.ts", diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index 2c4068005f8..36490d0f2fe 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -34,7 +34,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress'; import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; -import { ISaveParticipant, ITextFileEditorModel, SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; +import { ISaveParticipant, SaveReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../node/extHost.protocol'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -51,7 +51,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(model: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO); } @@ -113,7 +113,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(model: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doInsertFinalNewLine(model.textEditorModel); } @@ -151,7 +151,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant // Nothing } - async participate(model: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO); } @@ -222,7 +222,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(editorModel: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { const model = editorModel.textEditorModel; if (env.reason === SaveReason.AUTO @@ -293,7 +293,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant { @IConfigurationService private readonly _configurationService: IConfigurationService ) { } - async participate(editorModel: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { if (env.reason === SaveReason.AUTO) { return undefined; } @@ -373,7 +373,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentSaveParticipant); } - async participate(editorModel: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { if (!shouldSynchronizeModel(editorModel.textEditorModel)) { // the model never made it to the extension @@ -424,7 +424,7 @@ export class SaveParticipant implements ISaveParticipant { this._saveParticipants.dispose(); } - async participate(model: ITextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { return this._progressService.withProgress({ location: ProgressLocation.Window }, progress => { progress.report({ message: localize('saveParticipants', "Running Save Participants...") }); const promiseFactory = this._saveParticipants.getValue().map(p => () => { diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 64f2a50b4dc..870f66a51f7 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { EncodingMode } from 'vs/workbench/common/editor'; import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; @@ -661,7 +661,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil }; this.blockModelContentChange = true; - saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError); + saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IActiveTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError); } // mark the save participant as current pending save operation diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index a51df6695ac..d9c897b069c 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -10,7 +10,7 @@ import { IEncodingSupport, ConfirmResult, IRevertOptions } from 'vs/workbench/co import { IBaseStat, IResolveContentOptions, ITextSnapshot } from 'vs/platform/files/common/files'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; -import { ITextBufferFactory } from 'vs/editor/common/model'; +import { ITextBufferFactory, ITextModel } from 'vs/editor/common/model'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; /** @@ -29,7 +29,7 @@ export interface ISaveParticipant { /** * Participate in a save of a model. Allows to change the model before it is being saved to disk. */ - participate(model: ITextFileEditorModel, env: { reason: SaveReason }): Promise; + participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise; } /** @@ -255,6 +255,10 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport isDisposed(): boolean; } +export interface IActiveTextFileEditorModel extends ITextFileEditorModel { + readonly textEditorModel: ITextModel; +} + export interface IWillMoveEvent { oldResource: URI; From 3f737ae1c76e2f61f298761ad48ccbf46cbd0b99 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 09:41:28 -0800 Subject: [PATCH 236/290] Strict null check textModelResolver --- src/tsconfig.strictNullChecks.json | 2 ++ .../common/textModelResolverService.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index ff390f15cb9..9a71de6256a 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -446,6 +446,8 @@ "./vs/workbench/services/textfile/common/textFileEditorModelManager.ts", "./vs/workbench/services/textfile/common/textfiles.ts", "./vs/workbench/services/textfile/node/textResourcePropertiesService.ts", + "./vs/workbench/services/textmodelResolver/common/textModelResolverService.ts", + "./vs/workbench/services/timer/electron-browser/timerService.ts", "./vs/workbench/services/title/common/titleService.ts", "./vs/workbench/services/untitled/common/untitledEditorService.ts", "./vs/workbench/services/viewlet/browser/viewlet.ts", diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index 1c6388a5929..1e281d53340 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -12,7 +12,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; import { ITextFileService, LoadReason } from 'vs/workbench/services/textfile/common/textfiles'; import * as network from 'vs/base/common/network'; -import { ITextModelService, ITextModelContentProvider, ITextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { IFileService } from 'vs/platform/files/common/files'; @@ -104,7 +104,7 @@ class ResourceModelCollection extends ReferenceCollection { const resource = URI.parse(key); const providers = this.providers[resource.scheme] || []; - const factories = providers.map(p => () => Promise.resolve(p.provideTextContent(resource))); + const factories = providers.map(p => () => Promise.resolve(p.provideTextContent(resource))); return first(factories).then(model => { if (!model) { @@ -130,15 +130,15 @@ export class TextModelResolverService implements ITextModelService { this.resourceModelCollection = instantiationService.createInstance(ResourceModelCollection); } - createModelReference(resource: URI): Promise> { + createModelReference(resource: URI): Promise> { return this._createModelReference(resource); } - private _createModelReference(resource: URI): Promise> { + private _createModelReference(resource: URI): Promise> { // Untitled Schema: go through cached input if (resource.scheme === network.Schemas.untitled) { - return this.untitledEditorService.loadOrCreate({ resource }).then(model => new ImmortalReference(model)); + return this.untitledEditorService.loadOrCreate({ resource }).then(model => new ImmortalReference(model as IActiveTextEditorModel)); } // InMemory Schema: go through model service cache @@ -149,7 +149,7 @@ export class TextModelResolverService implements ITextModelService { return Promise.reject(new Error('Cant resolve inmemory resource')); } - return Promise.resolve(new ImmortalReference(this.instantiationService.createInstance(ResourceEditorModel, resource))); + return Promise.resolve(new ImmortalReference(this.instantiationService.createInstance(ResourceEditorModel, resource) as IActiveTextEditorModel)); } const ref = this.resourceModelCollection.acquire(resource.toString()); From dd3996661505a0d6e593d0e69abf3a8ad6cf0cc0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 09:53:08 -0800 Subject: [PATCH 237/290] Strict null check mainThreadHeapService --- package.json | 4 ++-- src/tsconfig.strictNullChecks.json | 1 + yarn.lock | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 606c1365c3b..3679da9592b 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ }, "dependencies": { "applicationinsights": "1.0.8", - "gc-signals": "^0.0.1", + "gc-signals": "^0.0.2", "getmac": "1.4.1", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", @@ -150,4 +150,4 @@ "windows-mutex": "0.2.1", "windows-process-tree": "0.2.3" } -} +} \ No newline at end of file diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 9a71de6256a..2ab9b6ec0ca 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -56,6 +56,7 @@ "./vs/workbench/api/electron-browser/mainThreadErrors.ts", "./vs/workbench/api/electron-browser/mainThreadFileSystem.ts", "./vs/workbench/api/electron-browser/mainThreadFileSystemEventService.ts", + "./vs/workbench/api/electron-browser/mainThreadHeapService.ts", "./vs/workbench/api/electron-browser/mainThreadLanguages.ts", "./vs/workbench/api/electron-browser/mainThreadLogService.ts", "./vs/workbench/api/electron-browser/mainThreadMessageService.ts", diff --git a/yarn.lock b/yarn.lock index ee5b960a7e4..654114c0663 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3482,10 +3482,10 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -gc-signals@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/gc-signals/-/gc-signals-0.0.1.tgz#91e3b7904168b58aa3dc78b619b7b4495b4038ab" - integrity sha1-keO3kEFotYqj3Hi2Gbe0SVtAOKs= +gc-signals@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/gc-signals/-/gc-signals-0.0.2.tgz#1cfa8a00adecaeeb93ea0dda72dad9e9f333e62f" + integrity sha512-Ghj4Co6x5bd3dvbAFuiDc6gN+BVK8ic8CBn70dXjzrtbC5hq4a+s4S6acEvftMP7LcQuHKN5v+30PGXhkCLoCQ== generate-function@^2.0.0: version "2.0.0" From 311a05ddf17a9ebe139b2df971324a598c9b8eb8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 09:56:27 -0800 Subject: [PATCH 238/290] Fix merge conflict with rename --- src/tsconfig.strictNullChecks.json | 2 +- .../common/textModelResolverService.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 2ab9b6ec0ca..4b60b2a69b2 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -32,7 +32,6 @@ "./vs/workbench/services/timer/**/*.ts" ], "files": [ - "./vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts", "./vs/monaco.d.ts", "./vs/nls.d.ts", "./vs/nls.mock.ts", @@ -64,6 +63,7 @@ "./vs/workbench/api/electron-browser/mainThreadProgress.ts", "./vs/workbench/api/electron-browser/mainThreadQuickOpen.ts", "./vs/workbench/api/electron-browser/mainThreadSCM.ts", + "./vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts", "./vs/workbench/api/electron-browser/mainThreadSearch.ts", "./vs/workbench/api/electron-browser/mainThreadStatusBar.ts", "./vs/workbench/api/electron-browser/mainThreadStorage.ts", diff --git a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts index 1e281d53340..bc4a2084711 100644 --- a/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts +++ b/src/vs/workbench/services/textmodelResolver/common/textModelResolverService.ts @@ -12,7 +12,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { ResourceEditorModel } from 'vs/workbench/common/editor/resourceEditorModel'; import { ITextFileService, LoadReason } from 'vs/workbench/services/textfile/common/textfiles'; import * as network from 'vs/base/common/network'; -import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IActiveTextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, ITextModelContentProvider, ITextEditorModel, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { IFileService } from 'vs/platform/files/common/files'; @@ -130,15 +130,15 @@ export class TextModelResolverService implements ITextModelService { this.resourceModelCollection = instantiationService.createInstance(ResourceModelCollection); } - createModelReference(resource: URI): Promise> { + createModelReference(resource: URI): Promise> { return this._createModelReference(resource); } - private _createModelReference(resource: URI): Promise> { + private _createModelReference(resource: URI): Promise> { // Untitled Schema: go through cached input if (resource.scheme === network.Schemas.untitled) { - return this.untitledEditorService.loadOrCreate({ resource }).then(model => new ImmortalReference(model as IActiveTextEditorModel)); + return this.untitledEditorService.loadOrCreate({ resource }).then(model => new ImmortalReference(model as IResolvedTextEditorModel)); } // InMemory Schema: go through model service cache @@ -149,7 +149,7 @@ export class TextModelResolverService implements ITextModelService { return Promise.reject(new Error('Cant resolve inmemory resource')); } - return Promise.resolve(new ImmortalReference(this.instantiationService.createInstance(ResourceEditorModel, resource) as IActiveTextEditorModel)); + return Promise.resolve(new ImmortalReference(this.instantiationService.createInstance(ResourceEditorModel, resource) as IResolvedTextEditorModel)); } const ref = this.resourceModelCollection.acquire(resource.toString()); From 9fa249ae94d615d3318fbf1afb075accde129fc0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 10:06:31 -0800 Subject: [PATCH 239/290] Strict null work on mainThreadSaveParticpants test --- .../mainThreadSaveParticipant.ts | 16 +++--- .../textfile/common/textFileEditorModel.ts | 4 +- .../services/textfile/common/textfiles.ts | 4 +- .../api/mainThreadSaveParticipant.test.ts | 52 +++++++++---------- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index 36490d0f2fe..f83e76de7a4 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -34,7 +34,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress'; import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; -import { ISaveParticipant, SaveReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; +import { ISaveParticipant, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../node/extHost.protocol'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -51,7 +51,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO); } @@ -113,7 +113,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doInsertFinalNewLine(model.textEditorModel); } @@ -151,7 +151,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant // Nothing } - async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO); } @@ -222,7 +222,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { // Nothing } - async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { const model = editorModel.textEditorModel; if (env.reason === SaveReason.AUTO @@ -293,7 +293,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant { @IConfigurationService private readonly _configurationService: IConfigurationService ) { } - async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { if (env.reason === SaveReason.AUTO) { return undefined; } @@ -373,7 +373,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentSaveParticipant); } - async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { if (!shouldSynchronizeModel(editorModel.textEditorModel)) { // the model never made it to the extension @@ -424,7 +424,7 @@ export class SaveParticipant implements ISaveParticipant { this._saveParticipants.dispose(); } - async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise { + async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise { return this._progressService.withProgress({ location: ProgressLocation.Window }, progress => { progress.report({ message: localize('saveParticipants', "Running Save Participants...") }); const promiseFactory = this._saveParticipants.getValue().map(p => () => { diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 870f66a51f7..d056cc34156 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { EncodingMode } from 'vs/workbench/common/editor'; import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; @@ -661,7 +661,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil }; this.blockModelContentChange = true; - saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IActiveTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError); + saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IResolvedTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError); } // mark the save participant as current pending save operation diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index d9c897b069c..0e249fb61f7 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -29,7 +29,7 @@ export interface ISaveParticipant { /** * Participate in a save of a model. Allows to change the model before it is being saved to disk. */ - participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise; + participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise; } /** @@ -255,7 +255,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport isDisposed(): boolean; } -export interface IActiveTextFileEditorModel extends ITextFileEditorModel { +export interface IResolvedTextFileEditorModel extends ITextFileEditorModel { readonly textEditorModel: ITextModel; } diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts index 6fc405bc679..eb437ee4f29 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts @@ -13,7 +13,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; -import { ITextFileService, SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; import { snapshotToString } from 'vs/platform/files/common/files'; @@ -38,7 +38,7 @@ suite('MainThreadSaveParticipant', function () { }); test('insert final new line', async function () { - const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8'); + const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel; await model.load(); const configService = new TestConfigurationService(); @@ -47,66 +47,66 @@ suite('MainThreadSaveParticipant', function () { // No new line for empty lines let lineContent = ''; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // No new line if last line already empty - lineContent = `Hello New Line${model.textEditorModel!.getEOL()}`; - model.textEditorModel!.setValue(lineContent); + lineContent = `Hello New Line${model.textEditorModel.getEOL()}`; + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // New empty line added (single line) lineContent = 'Hello New Line'; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); - assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`); + assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`); // New empty line added (multi line) - lineContent = `Hello New Line${model.textEditorModel!.getEOL()}Hello New Line${model.textEditorModel!.getEOL()}Hello New Line`; - model.textEditorModel!.setValue(lineContent); + lineContent = `Hello New Line${model.textEditorModel.getEOL()}Hello New Line${model.textEditorModel.getEOL()}Hello New Line`; + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); - assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`); + assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`); }); test('trim final new lines', async function () { - const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8'); + const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel; await model.load(); const configService = new TestConfigurationService(); configService.setUserConfiguration('files', { 'trimFinalNewlines': true }); const participant = new TrimFinalNewLinesParticipant(configService, undefined!); const textContent = 'Trim New Line'; - const eol = `${model.textEditorModel!.getEOL()}`; + const eol = `${model.textEditorModel.getEOL()}`; // No new line removal if last line is not new line let lineContent = `${textContent}`; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // No new line removal if last line is single new line lineContent = `${textContent}${eol}`; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), lineContent); // Remove new line (single line with two new lines) lineContent = `${textContent}${eol}${eol}`; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`); // Remove new lines (multiple lines with multiple new lines) lineContent = `${textContent}${eol}${textContent}${eol}${eol}${eol}`; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); await participant.participate(model, { reason: SaveReason.EXPLICIT }); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${textContent}${eol}`); }); test('trim final new lines bug#39750', async function () { - const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8'); + const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel; await model.load(); const configService = new TestConfigurationService(); @@ -116,33 +116,33 @@ suite('MainThreadSaveParticipant', function () { // single line let lineContent = `${textContent}`; - model.textEditorModel!.setValue(lineContent); + model.textEditorModel.setValue(lineContent); // apply edits and push to undo stack. let textEdits = [{ range: new Range(1, 14, 1, 14), text: '.', forceMoveMarkers: false }]; - model.textEditorModel!.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; }); + model.textEditorModel.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; }); // undo - model.textEditorModel!.undo(); + model.textEditorModel.undo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}`); // trim final new lines should not mess the undo stack await participant.participate(model, { reason: SaveReason.EXPLICIT }); - model.textEditorModel!.redo(); + model.textEditorModel.redo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}.`); }); test('trim final new lines bug#46075', async function () { - const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8'); + const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel; await model.load(); const configService = new TestConfigurationService(); configService.setUserConfiguration('files', { 'trimFinalNewlines': true }); const participant = new TrimFinalNewLinesParticipant(configService, undefined!); const textContent = 'Test'; - const eol = `${model.textEditorModel!.getEOL()}`; + const eol = `${model.textEditorModel.getEOL()}`; let content = `${textContent}${eol}${eol}`; - model.textEditorModel!.setValue(content); + model.textEditorModel.setValue(content); // save many times for (let i = 0; i < 10; i++) { @@ -153,9 +153,9 @@ suite('MainThreadSaveParticipant', function () { assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`); // undo should go back to previous content immediately - model.textEditorModel!.undo(); + model.textEditorModel.undo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${eol}`); - model.textEditorModel!.redo(); + model.textEditorModel.redo(); assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`); }); }); From 3b451a68ba7a7c17747d6db000e1c83b130d0436 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 10:16:09 -0800 Subject: [PATCH 240/290] Fix strict null conflicts from making openEditor return Promise --- .../common/editor/diffEditorInput.ts | 2 +- .../preferences/browser/preferencesService.ts | 26 +++++++++---------- .../preferences/common/preferences.ts | 12 ++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/common/editor/diffEditorInput.ts b/src/vs/workbench/common/editor/diffEditorInput.ts index 44a8af3658a..ff410762774 100644 --- a/src/vs/workbench/common/editor/diffEditorInput.ts +++ b/src/vs/workbench/common/editor/diffEditorInput.ts @@ -18,7 +18,7 @@ export class DiffEditorInput extends SideBySideEditorInput { private cachedModel: DiffEditorModel | null; - constructor(name: string, description: string, original: EditorInput, modified: EditorInput, private forceOpenAsBinary?: boolean) { + constructor(name: string, description: string | null, original: EditorInput, modified: EditorInput, private forceOpenAsBinary?: boolean) { super(name, description, original, modified); } diff --git a/src/vs/workbench/services/preferences/browser/preferencesService.ts b/src/vs/workbench/services/preferences/browser/preferencesService.ts index 8efc41d7c34..7879f21bc17 100644 --- a/src/vs/workbench/services/preferences/browser/preferencesService.ts +++ b/src/vs/workbench/services/preferences/browser/preferencesService.ts @@ -171,15 +171,15 @@ export class PreferencesService extends Disposable implements IPreferencesServic return Promise.reject(`unknown resource: ${uri.toString()}`); } - openRawDefaultSettings(): Promise { + openRawDefaultSettings(): Promise { return this.editorService.openEditor({ resource: this.defaultSettingsRawResource }); } - openRawUserSettings(): Promise { + openRawUserSettings(): Promise { return this.editorService.openEditor({ resource: this.userSettingsResource }); } - openSettings(jsonEditor?: boolean): Promise { + openSettings(jsonEditor?: boolean): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -200,7 +200,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic .then(() => this.editorGroupService.activeGroup.activeControl!); } - openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -210,7 +210,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.openOrSwitchSettings2(ConfigurationTarget.USER, undefined, options, group); } - openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -225,7 +225,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE, undefined, options, group); } - openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { jsonEditor = typeof jsonEditor === 'undefined' ? this.configurationService.getValue('workbench.settings.editor') === 'json' : jsonEditor; @@ -282,7 +282,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.editorService.openEditor(this.instantiationService.createInstance(KeybindingsEditorInput), { pinned: true, revealIfOpened: true }).then(() => undefined); } - openDefaultKeybindingsFile(): Promise { + openDefaultKeybindingsFile(): Promise { return this.editorService.openEditor({ resource: this.defaultKeybindingsResource, label: nls.localize('defaultKeybindings', "Default Keybindings") }); } @@ -290,7 +290,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic this.openGlobalSettings(true) .then(editor => this.createPreferencesEditorModel(this.userSettingsResource) .then((settingsModel: IPreferencesEditorModel) => { - const codeEditor = getCodeEditor(editor.getControl()); + const codeEditor = editor ? getCodeEditor(editor.getControl()) : null; if (codeEditor) { this.addLanguageOverrideEntry(language, settingsModel, codeEditor) .then(position => { @@ -304,7 +304,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic })); } - private openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { + private openOrSwitchSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { const editorInput = this.getActiveSettingsEditorInput(group); if (editorInput) { const editorInputResource = editorInput.master.getResource(); @@ -315,11 +315,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.doOpenSettings(configurationTarget, resource, options, group); } - private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, folderUri?: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { + private openOrSwitchSettings2(configurationTarget: ConfigurationTarget, folderUri?: URI, options?: ISettingsEditorOptions, group: IEditorGroup = this.editorGroupService.activeGroup): Promise { return this.doOpenSettings2(configurationTarget, folderUri, options, group); } - private doOpenSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + private doOpenSettings(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { const openSplitJSON = !!this.configurationService.getValue(USE_SPLIT_JSON_SETTING); if (openSplitJSON) { return this.doOpenSplitJSON(configurationTarget, resource, options, group); @@ -348,7 +348,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic }); } - private doOpenSplitJSON(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { + private doOpenSplitJSON(configurationTarget: ConfigurationTarget, resource: URI, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise { return this.getOrCreateEditableSettingsEditorInput(configurationTarget, resource) .then(editableSettingsEditorInput => { if (!options) { @@ -368,7 +368,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic return this.instantiationService.createInstance(Settings2EditorModel, this.getDefaultSettings(ConfigurationTarget.USER)); } - private doOpenSettings2(target: ConfigurationTarget, folderUri: URI | undefined, options?: IEditorOptions, group?: IEditorGroup): Promise { + private doOpenSettings2(target: ConfigurationTarget, folderUri: URI | undefined, options?: IEditorOptions, group?: IEditorGroup): Promise { const input = this.settingsEditor2Input; const settingsOptions: ISettingsEditorOptions = { ...options, diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index b1d1d0a4a99..7dc27694012 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -198,14 +198,14 @@ export interface IPreferencesService { createPreferencesEditorModel(uri: URI): Promise>; createSettings2EditorModel(): Settings2EditorModel; // TODO - openRawDefaultSettings(): Promise; - openSettings(jsonEditor?: boolean): Promise; - openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; - openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; - openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; + openRawDefaultSettings(): Promise; + openSettings(jsonEditor?: boolean): Promise; + openGlobalSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; + openWorkspaceSettings(jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; + openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise; switchSettings(target: ConfigurationTarget, resource: URI, jsonEditor?: boolean): Promise; openGlobalKeybindingSettings(textual: boolean): Promise; - openDefaultKeybindingsFile(): Promise; + openDefaultKeybindingsFile(): Promise; configureSettingsForLanguage(language: string): void; } From 928947812732d1f08a39abbf06282d2a3439293a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 5 Mar 2019 18:43:51 +0000 Subject: [PATCH 241/290] Interpret NO_PROXY (#68260) --- .../services/extensions/node/proxyResolver.ts | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 98fed1fac42..1643badcc71 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -8,6 +8,7 @@ import * as https from 'https'; import * as nodeurl from 'url'; import { assign } from 'vs/base/common/objects'; +import { endsWith } from 'vs/base/common/strings'; import { IExtHostWorkspaceProvider } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostConfigProvider } from 'vs/workbench/api/node/extHostConfiguration'; import { ProxyAgent } from 'vscode-proxy-agent'; @@ -44,15 +45,18 @@ function setupProxyResolution( extHostLogService: ExtHostLogService, mainThreadTelemetry: MainThreadTelemetryShape ) { + const env = process.env; + let settingsProxy = proxyFromConfigURL(configProvider.getConfiguration('http') .get('proxy')); configProvider.onDidChangeConfiguration(e => { settingsProxy = proxyFromConfigURL(configProvider.getConfiguration('http') .get('proxy')); }); - const env = process.env; let envProxy = proxyFromConfigURL(env.https_proxy || env.HTTPS_PROXY || env.http_proxy || env.HTTP_PROXY); // Not standardized. + let envNoProxy = noProxyFromEnv(env.no_proxy || env.NO_PROXY); // Not standardized. + let cacheRolls = 0; let oldCache = new Map(); let cache = new Map(); @@ -90,6 +94,7 @@ function setupProxyResolution( let envCount = 0; let settingsCount = 0; let localhostCount = 0; + let envNoProxyCount = 0; let results: ConnectionResult[] = []; function logEvent() { timeout = undefined; @@ -104,11 +109,12 @@ function setupProxyResolution( "envCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "settingsCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "localhostCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, + "envNoProxyCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }, "results": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } } */ - mainThreadTelemetry.$publicLog('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount, results }); - count = duration = errorCount = cacheCount = envCount = settingsCount = localhostCount = 0; + mainThreadTelemetry.$publicLog('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount, envNoProxyCount, results }); + count = duration = errorCount = cacheCount = envCount = settingsCount = localhostCount = envNoProxyCount = 0; results = []; } @@ -127,6 +133,13 @@ function setupProxyResolution( return; } + if (envNoProxy(hostname, String(parsedUrl.port || (opts.agent).defaultPort))) { + envNoProxyCount++; + callback('DIRECT'); + extHostLogService.trace('ProxyResolver#resolveProxy envNoProxy', url, 'DIRECT'); + return; + } + if (settingsProxy) { settingsCount++; callback(settingsProxy); @@ -214,6 +227,32 @@ function proxyFromConfigURL(configURL: string | undefined) { return undefined; } +function noProxyFromEnv(envValue?: string) { + const value = (envValue || '') + .trim() + .toLowerCase(); + + if (value === '*') { + return () => true; + } + + const filters = value + .split(',') + .map(s => s.trim().split(':', 2)) + .map(([name, port]) => ({ name, port })) + .filter(filter => !!filter.name) + .map(({ name, port }) => { + const domain = name[0] === '.' ? name : `.${name}`; + return { domain, port }; + }); + if (!filters.length) { + return () => false; + } + return (hostname: string, port: string) => filters.some(({ domain, port: filterPort }) => { + return endsWith(`.${hostname.toLowerCase()}`, domain) && (!filterPort || port === filterPort); + }); +} + function createPatchedModules(configProvider: ExtHostConfigProvider, resolveProxy: ReturnType) { const setting = { config: configProvider.getConfiguration('http') From 81b713fe6bb9a6c368f3601df31d7be83c15fd1b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 10:34:30 -0800 Subject: [PATCH 242/290] Strict null work in extensionEditor --- src/tsconfig.strictNullChecks.json | 18 +++++++++++++++-- .../electron-browser/extensionEditor.ts | 16 +++++++++------ .../extensions.contribution.ts | 4 ++-- .../extensionsAutoProfiler.ts | 2 +- .../electron-browser/extensionsViewlet.ts | 2 +- .../electron-browser/extensionsViews.ts | 12 ++++++++--- .../runtimeExtensionsEditor.ts | 20 +++++++++---------- 7 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 4b60b2a69b2..beef6f1b918 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -67,6 +67,7 @@ "./vs/workbench/api/electron-browser/mainThreadSearch.ts", "./vs/workbench/api/electron-browser/mainThreadStatusBar.ts", "./vs/workbench/api/electron-browser/mainThreadStorage.ts", + "./vs/workbench/api/electron-browser/mainThreadTask.ts", "./vs/workbench/api/electron-browser/mainThreadTelemetry.ts", "./vs/workbench/api/electron-browser/mainThreadTerminalService.ts", "./vs/workbench/api/electron-browser/mainThreadTreeViews.ts", @@ -146,6 +147,7 @@ "./vs/workbench/browser/parts/sidebar/sidebarPart.ts", "./vs/workbench/browser/parts/statusbar/statusbar.ts", "./vs/workbench/browser/parts/statusbar/statusbarPart.ts", + "./vs/workbench/browser/parts/titlebar/menubarControl.ts", "./vs/workbench/browser/parts/views/customView.ts", "./vs/workbench/browser/parts/views/panelViewlet.ts", "./vs/workbench/browser/parts/views/views.ts", @@ -236,11 +238,14 @@ "./vs/workbench/contrib/extensions/common/extensionsFileTemplate.ts", "./vs/workbench/contrib/extensions/common/extensionsInput.ts", "./vs/workbench/contrib/extensions/common/extensionsUtils.ts", + "./vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActivationProgress.ts", + "./vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsList.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts", + "./vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts", "./vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput.ts", "./vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts", "./vs/workbench/contrib/extensions/test/common/extensionQuery.test.ts", @@ -281,7 +286,9 @@ "./vs/workbench/contrib/output/electron-browser/output.contribution.ts", "./vs/workbench/contrib/output/electron-browser/outputServices.ts", "./vs/workbench/contrib/output/node/outputAppender.ts", + "./vs/workbench/contrib/preferences/browser/settingsLayout.ts", "./vs/workbench/contrib/preferences/browser/settingsWidgets.ts", + "./vs/workbench/contrib/preferences/common/preferences.ts", "./vs/workbench/contrib/preferences/common/smartSnippetInserter.ts", "./vs/workbench/contrib/preferences/test/common/smartSnippetInserter.test.ts", "./vs/workbench/contrib/quickopen/browser/commandsHandler.ts", @@ -291,12 +298,12 @@ "./vs/workbench/contrib/quickopen/browser/quickopen.contribution.ts", "./vs/workbench/contrib/quickopen/browser/viewPickerHandler.ts", "./vs/workbench/contrib/relauncher/electron-browser/relauncher.contribution.ts", - "./vs/workbench/contrib/scm/common/scm.ts", - "./vs/workbench/contrib/scm/common/scmService.ts", "./vs/workbench/contrib/scm/browser/dirtydiffDecorator.ts", "./vs/workbench/contrib/scm/browser/scmActivity.ts", "./vs/workbench/contrib/scm/browser/scmMenus.ts", "./vs/workbench/contrib/scm/browser/scmUtil.ts", + "./vs/workbench/contrib/scm/common/scm.ts", + "./vs/workbench/contrib/scm/common/scmService.ts", "./vs/workbench/contrib/search/browser/openAnythingHandler.ts", "./vs/workbench/contrib/search/browser/openFileHandler.ts", "./vs/workbench/contrib/search/browser/openSymbolHandler.ts", @@ -318,6 +325,9 @@ "./vs/workbench/contrib/stats/test/workspaceStats.test.ts", "./vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts", "./vs/workbench/contrib/surveys/electron-browser/nps.contribution.ts", + "./vs/workbench/contrib/telemetry/browser/telemetry.contribution.ts", + "./vs/workbench/contrib/terminal/browser/terminal.contribution.ts", + "./vs/workbench/contrib/terminal/browser/terminal.ts", "./vs/workbench/contrib/terminal/browser/terminalActions.ts", "./vs/workbench/contrib/terminal/browser/terminalCommandTracker.ts", "./vs/workbench/contrib/terminal/browser/terminalConfigHelper.ts", @@ -327,6 +337,7 @@ "./vs/workbench/contrib/terminal/browser/terminalPanel.ts", "./vs/workbench/contrib/terminal/browser/terminalProcessManager.ts", "./vs/workbench/contrib/terminal/browser/terminalQuickOpen.ts", + "./vs/workbench/contrib/terminal/browser/terminalService.ts", "./vs/workbench/contrib/terminal/browser/terminalTab.ts", "./vs/workbench/contrib/terminal/browser/terminalWidgetManager.ts", "./vs/workbench/contrib/terminal/common/terminal.ts", @@ -336,6 +347,9 @@ "./vs/workbench/contrib/terminal/common/terminalMenu.ts", "./vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts", "./vs/workbench/contrib/terminal/common/terminalService.ts", + "./vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts", + "./vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts", + "./vs/workbench/contrib/terminal/electron-browser/terminalService.ts", "./vs/workbench/contrib/terminal/node/terminal.ts", "./vs/workbench/contrib/terminal/node/terminalProcess.ts", "./vs/workbench/contrib/terminal/node/windowsShellHelper.ts", diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts index 54f6af6c0d4..cee2fd121d7 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts @@ -89,8 +89,8 @@ function removeEmbeddedSVGs(documentContent: string): string { class NavBar { - private _onChange = new Emitter<{ id: string, focus: boolean }>(); - get onChange(): Event<{ id: string, focus: boolean }> { return this._onChange.event; } + private _onChange = new Emitter<{ id: string | null, focus: boolean }>(); + get onChange(): Event<{ id: string | null, focus: boolean }> { return this._onChange.event; } private currentId: string | null = null; private actions: Action[]; @@ -564,17 +564,21 @@ export class ExtensionEditor extends BaseEditor { } private openReadme(): Promise { - return this.openMarkdown(this.extensionReadme.get(), localize('noReadme', "No README available.")); + return this.openMarkdown(this.extensionReadme!.get(), localize('noReadme', "No README available.")); } private openChangelog(): Promise { - return this.openMarkdown(this.extensionChangelog.get(), localize('noChangelog', "No Changelog available.")); + return this.openMarkdown(this.extensionChangelog!.get(), localize('noChangelog', "No Changelog available.")); } private openContributions(): Promise { const content = $('div', { class: 'subcontent', tabindex: '0' }); - return this.loadContents(() => this.extensionManifest.get()) + return this.loadContents(() => this.extensionManifest!.get()) .then(manifest => { + if (!manifest) { + return content; + } + const scrollableContent = new DomScrollableElement(content, {}); const layout = () => scrollableContent.scanDomNode(); @@ -619,7 +623,7 @@ export class ExtensionEditor extends BaseEditor { return Promise.resolve(this.content); } - return this.loadContents(() => this.extensionDependencies.get()) + return this.loadContents(() => this.extensionDependencies!.get()) .then(extensionDependencies => { if (extensionDependencies) { const content = $('div', { class: 'subcontent' }); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts index 9611f624c74..689e0509b46 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts @@ -70,7 +70,7 @@ Registry.as(Extensions.Quickopen).registerQuickOpenHandler( ExtensionsHandler, ExtensionsHandler.ID, 'ext ', - null, + undefined, localize('extensionsCommands', "Manage Extensions"), true ) @@ -81,7 +81,7 @@ Registry.as(Extensions.Quickopen).registerQuickOpenHandler( GalleryExtensionsHandler, GalleryExtensionsHandler.ID, 'ext install ', - null, + undefined, localize('galleryExtensionsCommands', "Install Gallery Extensions"), true ) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts index 5fb573a33a3..154964ca211 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts @@ -49,7 +49,7 @@ export class ExtensionsAutoProfiler extends Disposable implements IWorkbenchCont if (event.isResponsive && this._session.has(target)) { // stop profiling when responsive again - this._session.get(target).cancel(); + this._session.get(target)!.cancel(); } else if (!event.isResponsive && !this._session.has(target)) { // start profiling if not yet profiling diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts index d3dfeb19447..1a2d50168ba 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts @@ -275,7 +275,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private searchBox: SuggestEnabledInput; private extensionsBox: HTMLElement; private primaryActions: IAction[]; - private secondaryActions: IAction[]; + private secondaryActions: IAction[] | null; private disposables: IDisposable[] = []; private searchViewletState: object; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts index 51177b7ca33..696f13d9b52 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts @@ -68,7 +68,7 @@ export class ExtensionsListView extends ViewletPanel { private extensionsList: HTMLElement; private badge: CountBadge; protected badgeContainer: HTMLElement; - private list: WorkbenchPagedList; + private list: WorkbenchPagedList | null; constructor( private options: IViewletViewOptions, @@ -133,7 +133,9 @@ export class ExtensionsListView extends ViewletPanel { protected layoutBody(height: number, width: number): void { this.extensionsList.style.height = height + 'px'; - this.list.layout(height, width); + if (this.list) { + this.list.layout(height, width); + } } async show(query: string): Promise> { @@ -168,7 +170,7 @@ export class ExtensionsListView extends ViewletPanel { } count(): number { - return this.list.length; + return this.list ? this.list.length : 0; } protected showEmptyModel(): Promise> { @@ -728,6 +730,10 @@ export class ExtensionsListView extends ViewletPanel { focus(): void { super.focus(); + if (!this.list) { + return; + } + if (!(this.list.getFocus().length || this.list.getSelection().length)) { this.list.focusNext(); } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts index 6bfbb3da3c9..da6880ff9b7 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -100,7 +100,7 @@ export class RuntimeExtensionsEditor extends BaseEditor { public static readonly ID: string = 'workbench.editor.runtimeExtensions'; private _list: WorkbenchList | null; - private _profileInfo: IExtensionHostProfile; + private _profileInfo: IExtensionHostProfile | null; private _elements: IRuntimeExtension[] | null; private _extensionsDescriptions: IExtensionDescription[]; @@ -385,7 +385,7 @@ export class RuntimeExtensionsEditor extends BaseEditor { } } - if (this._profileInfo) { + if (this._profileInfo && element.profileInfo) { data.profileTime.textContent = `Profile: ${(element.profileInfo.totalTime / 1000).toFixed(2)}ms`; } else { data.profileTime.textContent = ''; @@ -471,18 +471,18 @@ export class ReportExtensionIssueAction extends Action { private static _label = nls.localize('reportExtensionIssue', "Report Issue"); private readonly _url: string; - private readonly _task: () => Promise; + private readonly _task?: () => Promise; constructor(extension: { description: IExtensionDescription; marketplaceInfo: IExtension; - status: IExtensionsStatus; + status?: IExtensionsStatus; unresponsiveProfile?: IExtensionHostProfile }) { super(ReportExtensionIssueAction._id, ReportExtensionIssueAction._label, 'extension-action report-issue'); this.enabled = extension.marketplaceInfo && extension.marketplaceInfo.type === ExtensionType.User - && Boolean(extension.description.repository) && Boolean(extension.description.repository.url); + && !!extension.description.repository && !!extension.description.repository.url; const { url, task } = ReportExtensionIssueAction._generateNewIssueUrl(extension); this._url = url; @@ -499,11 +499,11 @@ export class ReportExtensionIssueAction extends Action { private static _generateNewIssueUrl(extension: { description: IExtensionDescription; marketplaceInfo: IExtension; - status: IExtensionsStatus; + status?: IExtensionsStatus; unresponsiveProfile?: IExtensionHostProfile }): { url: string, task?: () => Promise } { - let task: () => Promise | undefined; + let task: (() => Promise) | undefined; let baseUrl = extension.marketplaceInfo && extension.marketplaceInfo.type === ExtensionType.User && extension.description.repository ? extension.description.repository.url : undefined; if (!!baseUrl) { baseUrl = `${baseUrl.indexOf('.git') !== -1 ? baseUrl.substr(0, baseUrl.length - 4) : baseUrl}/issues/new/`; @@ -521,7 +521,7 @@ export class ReportExtensionIssueAction extends Action { let path = join(os.homedir(), `${extension.description.identifier.value}-unresponsive.cpuprofile.txt`); task = async () => { const profiler = await import('v8-inspect-profiler'); - const data = profiler.rewriteAbsolutePaths({ profile: extension.unresponsiveProfile.data }, 'pii_removed'); + const data = profiler.rewriteAbsolutePaths({ profile: extension.unresponsiveProfile!.data }, 'pii_removed'); profiler.writeProfile(data, path).then(undefined, onUnexpectedError); }; message = `:warning: Make sure to **attach** this file from your *home*-directory: \`${path}\` :warning:\n\nFind more details here: https://github.com/Microsoft/vscode/wiki/Explain:-extension-causes-high-cpu-load`; @@ -661,7 +661,7 @@ export class SaveExtensionHostProfileAction extends Action { } const profileInfo = this._extensionHostProfileService.lastProfile; - let dataToWrite: object = profileInfo.data; + let dataToWrite: object = profileInfo ? profileInfo.data : {}; if (this._environmentService.isBuilt) { const profiler = await import('v8-inspect-profiler'); @@ -676,6 +676,6 @@ export class SaveExtensionHostProfileAction extends Action { picked = picked + '.txt'; } - return writeFile(picked, JSON.stringify(profileInfo.data, null, '\t')); + return writeFile(picked, JSON.stringify(profileInfo ? profileInfo.data : {}, null, '\t')); } } From bde0b864004a602fccf127308530de224e65a168 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 10:53:43 -0800 Subject: [PATCH 243/290] Strict null work in contrib/preferences --- src/tsconfig.strictNullChecks.json | 7 +++- .../editor/common/services/resolverService.ts | 2 +- .../common/jsonContributionRegistry.ts | 2 +- .../preferences/browser/preferencesActions.ts | 4 ++- .../preferences/browser/preferencesWidgets.ts | 33 ++++++++++++------- .../contrib/preferences/common/preferences.ts | 4 +-- .../common/preferencesContribution.ts | 6 ++-- .../electron-browser/preferencesSearch.ts | 14 ++++---- .../services/editor/common/editorService.ts | 2 +- .../preferences/common/preferences.ts | 12 +++---- .../preferences/common/preferencesModels.ts | 4 ++- 11 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index beef6f1b918..5e51fd727b6 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -67,7 +67,6 @@ "./vs/workbench/api/electron-browser/mainThreadSearch.ts", "./vs/workbench/api/electron-browser/mainThreadStatusBar.ts", "./vs/workbench/api/electron-browser/mainThreadStorage.ts", - "./vs/workbench/api/electron-browser/mainThreadTask.ts", "./vs/workbench/api/electron-browser/mainThreadTelemetry.ts", "./vs/workbench/api/electron-browser/mainThreadTerminalService.ts", "./vs/workbench/api/electron-browser/mainThreadTreeViews.ts", @@ -244,6 +243,8 @@ "./vs/workbench/contrib/extensions/electron-browser/extensionsActivationProgress.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsList.ts", + "./vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts", + "./vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts", "./vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts", "./vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsInput.ts", @@ -286,10 +287,14 @@ "./vs/workbench/contrib/output/electron-browser/output.contribution.ts", "./vs/workbench/contrib/output/electron-browser/outputServices.ts", "./vs/workbench/contrib/output/node/outputAppender.ts", + "./vs/workbench/contrib/preferences/browser/preferencesActions.ts", + "./vs/workbench/contrib/preferences/browser/preferencesWidgets.ts", "./vs/workbench/contrib/preferences/browser/settingsLayout.ts", "./vs/workbench/contrib/preferences/browser/settingsWidgets.ts", "./vs/workbench/contrib/preferences/common/preferences.ts", + "./vs/workbench/contrib/preferences/common/preferencesContribution.ts", "./vs/workbench/contrib/preferences/common/smartSnippetInserter.ts", + "./vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts", "./vs/workbench/contrib/preferences/test/common/smartSnippetInserter.test.ts", "./vs/workbench/contrib/quickopen/browser/commandsHandler.ts", "./vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts", diff --git a/src/vs/editor/common/services/resolverService.ts b/src/vs/editor/common/services/resolverService.ts index ef65b34685e..d87baf65a43 100644 --- a/src/vs/editor/common/services/resolverService.ts +++ b/src/vs/editor/common/services/resolverService.ts @@ -36,7 +36,7 @@ export interface ITextModelContentProvider { /** * Given a resource, return the content of the resource as `ITextModel`. */ - provideTextContent(resource: URI): Promise | null; + provideTextContent(resource: URI): Promise | null | undefined; } export interface ITextEditorModel extends IEditorModel { diff --git a/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts b/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts index 3206c7ba3de..972566d2b48 100644 --- a/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts +++ b/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts @@ -12,7 +12,7 @@ export const Extensions = { }; export interface ISchemaContributions { - schemas?: { [id: string]: IJSONSchema }; + schemas: { [id: string]: IJSONSchema }; } export interface IJSONContributionRegistry { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts b/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts index 0a52f70fb78..fd8600260b5 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesActions.ts @@ -260,7 +260,9 @@ export class ConfigureLanguageBasedSettingsAction extends Action { .then(pick => { if (pick) { const modeId = this.modeService.getModeIdForLanguageName(pick.label.toLowerCase()); - return this.preferencesService.configureSettingsForLanguage(modeId); + if (typeof modeId === 'string') { + return this.preferencesService.configureSettingsForLanguage(modeId); + } } return undefined; }); diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts index 04a1058cd26..55c8f055069 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts @@ -226,13 +226,17 @@ export class SettingsGroupTitleWidget extends Widget implements IViewZone { if (this.settingsGroup.range.startLineNumber - 3 !== 1) { this.editor.focus(); const lineNumber = this.settingsGroup.range.startLineNumber - 2; - this.editor.setPosition({ lineNumber, column: this.editor.getModel().getLineMinColumn(lineNumber) }); + if (this.editor.hasModel()) { + this.editor.setPosition({ lineNumber, column: this.editor.getModel().getLineMinColumn(lineNumber) }); + } } break; case KeyCode.DownArrow: const lineNumber = this.isCollapsed() ? this.settingsGroup.range.startLineNumber : this.settingsGroup.range.startLineNumber - 1; this.editor.focus(); - this.editor.setPosition({ lineNumber, column: this.editor.getModel().getLineMinColumn(lineNumber) }); + if (this.editor.hasModel()) { + this.editor.setPosition({ lineNumber, column: this.editor.getModel().getLineMinColumn(lineNumber) }); + } break; } } @@ -286,7 +290,7 @@ export class SettingsGroupTitleWidget extends Widget implements IViewZone { export class FolderSettingsActionItem extends BaseActionItem { - private _folder: IWorkspaceFolder; + private _folder: IWorkspaceFolder | null; private _folderSettingCounts = new Map(); private container: HTMLElement; @@ -308,17 +312,21 @@ export class FolderSettingsActionItem extends BaseActionItem { this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged())); } - get folder(): IWorkspaceFolder { + get folder(): IWorkspaceFolder | null { return this._folder; } - set folder(folder: IWorkspaceFolder) { + set folder(folder: IWorkspaceFolder | null) { this._folder = folder; this.update(); } setCount(settingsTarget: URI, count: number): void { - const folder = this.contextService.getWorkspaceFolder(settingsTarget).uri; + const workspaceFolder = this.contextService.getWorkspaceFolder(settingsTarget); + if (!workspaceFolder) { + throw new Error('unknown folder'); + } + const folder = workspaceFolder.uri; this._folderSettingCounts.set(folder.toString(), count); this.update(); } @@ -374,8 +382,8 @@ export class FolderSettingsActionItem extends BaseActionItem { private onWorkspaceFoldersChanged(): void { const oldFolder = this._folder; const workspace = this.contextService.getWorkspace(); - if (this._folder) { - this._folder = workspace.folders.filter(folder => folder.uri.toString() === this._folder.uri.toString())[0] || workspace.folders[0]; + if (oldFolder) { + this._folder = workspace.folders.filter(folder => folder.uri.toString() === oldFolder.uri.toString())[0] || workspace.folders[0]; } this._folder = this._folder ? this._folder : workspace.folders.length === 1 ? workspace.folders[0] : null; @@ -384,7 +392,7 @@ export class FolderSettingsActionItem extends BaseActionItem { if (this._action.checked) { if ((oldFolder || !this._folder) || (!oldFolder || this._folder) - || (oldFolder && this._folder && oldFolder.uri.toString() === this._folder.uri.toString())) { + || (oldFolder && this._folder && (oldFolder as IWorkspaceFolder).uri.toString() === (this._folder as IWorkspaceFolder).uri.toString())) { this._action.run(this._folder); } } @@ -625,9 +633,10 @@ export class SearchWidget extends Widget { const focusTracker = this._register(DOM.trackFocus(this.inputBox.inputElement)); this._register(focusTracker.onDidFocus(() => this._onFocus.fire())); - if (this.options.focusKey) { - this._register(focusTracker.onDidFocus(() => this.options.focusKey.set(true))); - this._register(focusTracker.onDidBlur(() => this.options.focusKey.set(false))); + const focusKey = this.options.focusKey; + if (focusKey) { + this._register(focusTracker.onDidFocus(() => focusKey.set(true))); + this._register(focusTracker.onDidBlur(() => focusKey.set(false))); } } diff --git a/src/vs/workbench/contrib/preferences/common/preferences.ts b/src/vs/workbench/contrib/preferences/common/preferences.ts index 26985c7b847..bdc2c48a344 100644 --- a/src/vs/workbench/contrib/preferences/common/preferences.ts +++ b/src/vs/workbench/contrib/preferences/common/preferences.ts @@ -36,11 +36,11 @@ export interface IPreferencesSearchService { _serviceBrand: any; getLocalSearchProvider(filter: string): ISearchProvider; - getRemoteSearchProvider(filter: string, newExtensionsOnly?: boolean): ISearchProvider; + getRemoteSearchProvider(filter: string, newExtensionsOnly?: boolean): ISearchProvider | undefined; } export interface ISearchProvider { - searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): Promise; + searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): Promise; } export interface IKeybindingsEditor extends IEditor { diff --git a/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts b/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts index c1a65046bc1..4fe4d12d136 100644 --- a/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts +++ b/src/vs/workbench/contrib/preferences/common/preferencesContribution.ts @@ -61,7 +61,7 @@ export class PreferencesContribution implements IWorkbenchContribution { } } - private onEditorOpening(editor: IEditorInput, options: IEditorOptions | ITextEditorOptions, group: IEditorGroup): IOpenEditorOverride { + private onEditorOpening(editor: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup): IOpenEditorOverride | undefined { const resource = editor.getResource(); if ( !resource || @@ -108,7 +108,7 @@ export class PreferencesContribution implements IWorkbenchContribution { private start(): void { this.textModelResolverService.registerTextModelContentProvider('vscode', { - provideTextContent: (uri: URI): Promise => { + provideTextContent: (uri: URI): Promise | null => { if (uri.scheme !== 'vscode') { return null; } @@ -123,7 +123,7 @@ export class PreferencesContribution implements IWorkbenchContribution { }); } - private getSchemaModel(uri: URI): ITextModel { + private getSchemaModel(uri: URI): ITextModel | null { let schema = schemaRegistry.getSchemaContributions().schemas[uri.toString()]; if (schema) { const modelContent = JSON.stringify(schema); diff --git a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts index c72c3d6c1ee..e01930681bd 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/preferencesSearch.ts @@ -26,7 +26,7 @@ import { nullRange } from 'vs/workbench/services/preferences/common/preferencesM import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export interface IEndpointDetails { - urlBase: string; + urlBase?: string; key?: string; } @@ -77,14 +77,14 @@ export class PreferencesSearchService extends Disposable implements IPreferences } } - getRemoteSearchProvider(filter: string, newExtensionsOnly = false): ISearchProvider { + getRemoteSearchProvider(filter: string, newExtensionsOnly = false): ISearchProvider | undefined { const opts: IRemoteSearchProviderOptions = { filter, newExtensionsOnly, endpoint: this._endpoint }; - return this.remoteSearchAllowed && this.instantiationService.createInstance(RemoteSearchProvider, opts, this._installedExtensions); + return this.remoteSearchAllowed ? this.instantiationService.createInstance(RemoteSearchProvider, opts, this._installedExtensions) : undefined; } getLocalSearchProvider(filter: string): LocalSearchProvider { @@ -165,7 +165,7 @@ class RemoteSearchProvider implements ISearchProvider { private static readonly MAX_REQUESTS = 10; private static readonly NEW_EXTENSIONS_MIN_SCORE = 1; - private _remoteSearchP: Promise; + private _remoteSearchP: Promise; constructor(private options: IRemoteSearchProviderOptions, private installedExtensions: Promise, @IEnvironmentService private readonly environmentService: IEnvironmentService, @@ -177,8 +177,8 @@ class RemoteSearchProvider implements ISearchProvider { Promise.resolve(null); } - searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): Promise { - return this._remoteSearchP.then(remoteResult => { + searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): Promise { + return this._remoteSearchP.then((remoteResult) => { if (!remoteResult) { return null; } @@ -278,7 +278,7 @@ class RemoteSearchProvider implements ISearchProvider { headers, timeout: 5000 }, CancellationToken.None).then(context => { - if (context.res.statusCode >= 300) { + if (typeof context.res.statusCode === 'number' && context.res.statusCode >= 300) { throw new Error(`${JSON.stringify(details)} returned status code: ${context.res.statusCode}`); } diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index e47ffb540bf..a0f2e0006a1 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -36,7 +36,7 @@ export interface IOpenEditorOverride { * If defined, will prevent the opening of an editor and replace the resulting * promise with the provided promise for the openEditor() call. */ - override?: Promise; + override?: Promise; } export interface IActiveEditor extends IEditor { diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index 7dc27694012..06b0a00d28e 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -69,8 +69,8 @@ export interface ISetting { } export interface IExtensionSetting extends ISetting { - extensionName: string; - extensionPublisher: string; + extensionName?: string; + extensionPublisher?: string; } export interface ISearchResult { @@ -97,7 +97,7 @@ export interface IFilterResult { export interface ISettingMatch { setting: ISetting; - matches: IRange[]; + matches: IRange[] | null; score: number; } @@ -136,8 +136,8 @@ export interface IPreferencesEditorModel { dispose(): void; } -export type IGroupFilter = (group: ISettingsGroup) => boolean; -export type ISettingMatcher = (setting: ISetting, group: ISettingsGroup) => { matches: IRange[], score: number }; +export type IGroupFilter = (group: ISettingsGroup) => boolean | null; +export type ISettingMatcher = (setting: ISetting, group: ISettingsGroup) => { matches: IRange[], score: number } | null; export interface ISettingsEditorModel extends IPreferencesEditorModel { readonly onDidChangeGroups: Event; @@ -207,7 +207,7 @@ export interface IPreferencesService { openGlobalKeybindingSettings(textual: boolean): Promise; openDefaultKeybindingsFile(): Promise; - configureSettingsForLanguage(language: string): void; + configureSettingsForLanguage(language: string | null): void; } export function getSettingsTargetName(target: ConfigurationTarget, resource: URI, workspaceContextService: IWorkspaceContextService): string { diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 1c7936e9096..e49a53b39c8 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -178,7 +178,9 @@ export class SettingsEditorModel extends AbstractSettingsModel implements ISetti resultGroups.forEach(group => { group.result.filterMatches.forEach(filterMatch => { filteredSettings.push(filterMatch.setting); - matches.push(...filterMatch.matches); + if (filterMatch.matches) { + matches.push(...filterMatch.matches); + } }); }); From 39e7e1f339d50896d08a29b5b1a749d71e924ed1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 11:08:41 -0800 Subject: [PATCH 244/290] Strict null work on markers panel --- src/tsconfig.strictNullChecks.json | 3 +++ .../contrib/markers/browser/markersPanel.ts | 13 +++++++------ .../contrib/markers/browser/markersTreeViewer.ts | 12 ++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 5e51fd727b6..45b6c97b069 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -271,11 +271,14 @@ "./vs/workbench/contrib/logs/common/logs.contribution.ts", "./vs/workbench/contrib/logs/common/logsActions.ts", "./vs/workbench/contrib/markers/browser/constants.ts", + "./vs/workbench/contrib/markers/browser/markers.contribution.ts", "./vs/workbench/contrib/markers/browser/markers.ts", "./vs/workbench/contrib/markers/browser/markersFileDecorations.ts", "./vs/workbench/contrib/markers/browser/markersFilterOptions.ts", "./vs/workbench/contrib/markers/browser/markersModel.ts", + "./vs/workbench/contrib/markers/browser/markersPanel.ts", "./vs/workbench/contrib/markers/browser/markersPanelActions.ts", + "./vs/workbench/contrib/markers/browser/markersTreeViewer.ts", "./vs/workbench/contrib/markers/browser/messages.ts", "./vs/workbench/contrib/markers/test/electron-browser/markersModel.test.ts", "./vs/workbench/contrib/output/browser/logViewer.ts", diff --git a/src/vs/workbench/contrib/markers/browser/markersPanel.ts b/src/vs/workbench/contrib/markers/browser/markersPanel.ts index 435e6ed6500..3c7a8de1582 100644 --- a/src/vs/workbench/contrib/markers/browser/markersPanel.ts +++ b/src/vs/workbench/contrib/markers/browser/markersPanel.ts @@ -187,7 +187,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { public openFileAtElement(element: any, preserveFocus: boolean, sideByside: boolean, pinned: boolean): boolean { const { resource, selection, event, data } = element instanceof Marker ? { resource: element.resource, selection: element.range, event: 'problems.selectDiagnostic', data: this.getTelemetryData(element.marker) } : element instanceof RelatedInformation ? { resource: element.raw.resource, selection: element.raw, event: 'problems.selectRelatedInformation', data: this.getTelemetryData(element.marker) } : { resource: null, selection: null, event: null, data: null }; - if (resource && selection) { + if (resource && selection && event) { /* __GDPR__ "problems.selectDiagnostic" : { "source": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }, @@ -465,7 +465,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { private onSelected(): void { let selection = this.tree.getSelection(); if (selection && selection.length > 0) { - this.lastSelectedRelativeTop = this.tree.getRelativeTop(selection[0]); + this.lastSelectedRelativeTop = this.tree.getRelativeTop(selection[0]) || 0; } } @@ -612,7 +612,8 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { } private onContextMenu(e: ITreeContextMenuEvent): void { - if (!e.element) { + const element = e.element; + if (!element) { return; } @@ -620,8 +621,8 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { e.browserEvent.stopPropagation(); this.contextMenuService.showContextMenu({ - getAnchor: () => e.anchor, - getActions: () => this.getMenuActions(e.element), + getAnchor: () => e.anchor!, + getActions: () => this.getMenuActions(element), getActionItem: (action) => { const keybinding = this.keybindingService.lookupKeybinding(action.id); if (keybinding) { @@ -665,7 +666,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController { return result; } - public getFocusElement(): TreeElement { + public getFocusElement() { return this.tree.getFocus()[0]; } diff --git a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts index c7e69cc7584..b61a76f1283 100644 --- a/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/contrib/markers/browser/markersTreeViewer.ts @@ -67,7 +67,7 @@ export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider< constructor(@ILabelService private readonly labelService: ILabelService) { } - public getAriaLabel(element: TreeElement): string { + public getAriaLabel(element: TreeElement): string | null { if (element instanceof ResourceMarkers) { const path = this.labelService.getUriLabel(element.resource, { relative: true }) || element.resource.fsPath; return Messages.MARKERS_TREE_ARIA_LABEL_RESOURCE(element.markers.length, element.name, paths.dirname(path)); @@ -262,7 +262,7 @@ class MarkerWidget extends Disposable { this._register(toDisposable(() => this.disposables = dispose(this.disposables))); } - render(element: Marker, filterData: MarkerFilterData): void { + render(element: Marker, filterData: MarkerFilterData | undefined): void { this.actionBar.clear(); this.multilineActionbar.clear(); if (this.disposables.length) { @@ -310,7 +310,7 @@ class MarkerWidget extends Disposable { this.multilineActionbar.push([action], { icon: true, label: false }); } - private renderMessageAndDetails(element: Marker, filterData: MarkerFilterData) { + private renderMessageAndDetails(element: Marker, filterData: MarkerFilterData | undefined) { const { marker, lines } = element; const viewState = this.markersViewModel.getViewModel(element); const multiline = !viewState || viewState.multiline; @@ -330,7 +330,7 @@ class MarkerWidget extends Disposable { this.renderDetails(marker, filterData, multiline ? lastLineElement : this.messageAndDetailsContainer); } - private renderDetails(marker: IMarker, filterData: MarkerFilterData, parent: HTMLElement): void { + private renderDetails(marker: IMarker, filterData: MarkerFilterData | undefined, parent: HTMLElement): void { dom.addClass(parent, 'details-container'); const sourceMatches = filterData && filterData.sourceMatches || []; const codeMatches = filterData && filterData.codeMatches || []; @@ -557,7 +557,7 @@ export class MarkerViewModel extends Disposable { return this.codeActionsPromise; } return this.getModel(waitForModel) - .then(model => { + .then(model => { if (model) { if (!this.codeActionsPromise) { this.codeActionsPromise = createCancelablePromise(cancellationToken => { @@ -629,7 +629,7 @@ export class MarkersViewModel extends Disposable { private bulkUpdate: boolean = false; - private hoveredMarker: Marker; + private hoveredMarker: Marker | null; private hoverDelayer: Delayer = new Delayer(300); constructor( From 13e394ff45191c972a4849ab17f3ce910914e71b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 11:25:32 -0800 Subject: [PATCH 245/290] Strict null fixes for tests --- src/vs/workbench/api/node/extHost.protocol.ts | 6 +++--- .../common/editor/untitledEditorInput.ts | 5 +++-- .../common/editor/untitledEditorModel.ts | 5 +++-- .../test/common/editor/untitledEditor.test.ts | 18 +++++++++--------- .../api/mainThreadEditors.test.ts | 8 ++++---- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 2e74617076a..07a015c08d7 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -860,9 +860,9 @@ export interface WorkspaceSymbolsDto extends IdObject { } export interface ResourceFileEditDto { - oldUri: UriComponents; - newUri: UriComponents; - options: IFileOperationOptions; + oldUri?: UriComponents; + newUri?: UriComponents; + options?: IFileOperationOptions; } export interface ResourceTextEditDto { diff --git a/src/vs/workbench/common/editor/untitledEditorInput.ts b/src/vs/workbench/common/editor/untitledEditorInput.ts index 9d3ebed0a01..637ea614ee6 100644 --- a/src/vs/workbench/common/editor/untitledEditorInput.ts +++ b/src/vs/workbench/common/editor/untitledEditorInput.ts @@ -17,6 +17,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils'; import { IHashService } from 'vs/workbench/services/hash/common/hashService'; import { ILabelService } from 'vs/platform/label/common/label'; +import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; /** * An editor input to be used for untitled text buffers. @@ -27,7 +28,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport private _hasAssociatedFilePath: boolean; private cachedModel: UntitledEditorModel; - private modelResolve?: Promise; + private modelResolve?: Promise; private readonly _onDidModelChangeContent: Emitter = this._register(new Emitter()); get onDidModelChangeContent(): Event { return this._onDidModelChangeContent.event; } @@ -199,7 +200,7 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport } } - resolve(): Promise { + resolve(): Promise { // Join a model resolve if we have had one before if (this.modelResolve) { diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index a19c5e64cf2..15c9bd51637 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -16,6 +16,7 @@ import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { ITextBufferFactory } from 'vs/editor/common/model'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; +import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; export class UntitledEditorModel extends BaseTextEditorModel implements IEncodingSupport { @@ -136,7 +137,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin this.contentChangeEventScheduler.schedule(); } - load(): Promise { + load(): Promise { // Check for backups first return this.backupFileService.loadBackupResource(this.resource).then((backupResource) => { @@ -180,7 +181,7 @@ export class UntitledEditorModel extends BaseTextEditorModel implements IEncodin // Listen to mode changes this._register(textEditorModel.onDidChangeLanguage(() => this.onConfigurationChange())); // mode change can have impact on config - return this; + return this as UntitledEditorModel & IResolvedTextEditorModel; }); } diff --git a/src/vs/workbench/test/common/editor/untitledEditor.test.ts b/src/vs/workbench/test/common/editor/untitledEditor.test.ts index 5ce1d30ace9..62403c94f5c 100644 --- a/src/vs/workbench/test/common/editor/untitledEditor.test.ts +++ b/src/vs/workbench/test/common/editor/untitledEditor.test.ts @@ -68,7 +68,7 @@ suite('Workbench untitled editors', () => { assert.equal(service.getAll().length, 1); // dirty - input2.resolve().then((model: UntitledEditorModel) => { + input2.resolve().then(model => { assert.ok(!service.isDirty(input2.getResource())); const listener = service.onDidChangeDirty(resource => { @@ -112,7 +112,7 @@ suite('Workbench untitled editors', () => { const input = service.createOrGet(); // dirty - return input.resolve().then((model: UntitledEditorModel) => { + return input.resolve().then(model => { model.textEditorModel.setValue('foo bar'); assert.ok(model.isDirty()); @@ -126,14 +126,14 @@ suite('Workbench untitled editors', () => { test('Untitled via loadOrCreate', function () { const service = accessor.untitledEditorService; service.loadOrCreate().then(model1 => { - model1.textEditorModel.setValue('foo bar'); + model1.textEditorModel!.setValue('foo bar'); assert.ok(model1.isDirty()); - model1.textEditorModel.setValue(''); + model1.textEditorModel!.setValue(''); assert.ok(!model1.isDirty()); return service.loadOrCreate({ initialValue: 'Hello World' }).then(model2 => { - assert.equal(snapshotToString(model2.createSnapshot()), 'Hello World'); + assert.equal(snapshotToString(model2.createSnapshot()!), 'Hello World'); const input = service.createOrGet(); @@ -169,7 +169,7 @@ suite('Workbench untitled editors', () => { const input = service.createOrGet(file); // dirty - return input.resolve().then((model: UntitledEditorModel) => { + return input.resolve().then(model => { model.textEditorModel.setValue('foo bar'); assert.ok(model.isDirty()); @@ -223,7 +223,7 @@ suite('Workbench untitled editors', () => { }); // dirty - return input.resolve().then((model: UntitledEditorModel) => { + return input.resolve().then(model => { model.setEncoding('utf16'); assert.equal(counter, 1); @@ -245,7 +245,7 @@ suite('Workbench untitled editors', () => { assert.equal(r.toString(), input.getResource().toString()); }); - return input.resolve().then((model: UntitledEditorModel) => { + return input.resolve().then(model => { model.textEditorModel.setValue('foo'); assert.equal(counter, 0, 'Dirty model should not trigger event immediately'); @@ -288,7 +288,7 @@ suite('Workbench untitled editors', () => { assert.equal(r.toString(), input.getResource().toString()); }); - return input.resolve().then((model: UntitledEditorModel) => { + return input.resolve().then(model => { assert.equal(counter, 0); input.dispose(); assert.equal(counter, 1); 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 fb0d2c8e3aa..74633e4d5ac 100644 --- a/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts +++ b/src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts @@ -23,7 +23,7 @@ import { TestFileService, TestEditorService, TestEditorGroupsService, TestEnviro import { ResourceTextEdit } from 'vs/editor/common/modes'; import { BulkEditService } from 'vs/workbench/services/bulkEdit/browser/bulkEditService'; import { NullLogService } from 'vs/platform/log/common/log'; -import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { IReference, ImmortalReference } from 'vs/base/common/lifecycle'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { LabelService } from 'vs/workbench/services/label/common/labelService'; @@ -73,9 +73,9 @@ suite('MainThreadEditors', () => { const workbenchEditorService = new TestEditorService(); const editorGroupService = new TestEditorGroupsService(); const textModelService = new class extends mock() { - createModelReference(resource: URI): Promise> { - const textEditorModel: ITextEditorModel = new class extends mock() { - textEditorModel = modelService.getModel(resource); + createModelReference(resource: URI): Promise> { + const textEditorModel = new class extends mock() { + textEditorModel = modelService.getModel(resource)!; }; textEditorModel.isReadonly = () => false; return Promise.resolve(new ImmortalReference(textEditorModel)); From 1f2dca36d9660f36506d636457a10973b6310c57 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 11:26:52 -0800 Subject: [PATCH 246/290] Strict null check textFileEditor --- src/tsconfig.strictNullChecks.json | 1 + src/vs/editor/common/services/resourceConfiguration.ts | 10 +++++----- .../contrib/files/browser/editors/textFileEditor.ts | 7 +++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 45b6c97b069..b97d15467c0 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -255,6 +255,7 @@ "./vs/workbench/contrib/feedback/electron-browser/feedbackStatusbarItem.ts", "./vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts", "./vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts", + "./vs/workbench/contrib/files/browser/editors/textFileEditor.ts", "./vs/workbench/contrib/files/browser/files.ts", "./vs/workbench/contrib/files/browser/views/emptyView.ts", "./vs/workbench/contrib/files/browser/views/explorerDecorationsProvider.ts", diff --git a/src/vs/editor/common/services/resourceConfiguration.ts b/src/vs/editor/common/services/resourceConfiguration.ts index e0926ee9fda..02e63369296 100644 --- a/src/vs/editor/common/services/resourceConfiguration.ts +++ b/src/vs/editor/common/services/resourceConfiguration.ts @@ -24,13 +24,13 @@ export interface ITextResourceConfigurationService { * Fetches the value of the section for the given resource by applying language overrides. * Value can be of native type or an object keyed off the section name. * - * @param resource - Resource for which the configuration has to be fetched. Can be `null` or `undefined`. - * @param postion - Position in the resource for which configuration has to be fetched. Can be `null` or `undefined`. - * @param section - Section of the configuraion. Can be `null` or `undefined`. + * @param resource - Resource for which the configuration has to be fetched. + * @param postion - Position in the resource for which configuration has to be fetched. + * @param section - Section of the configuraion. * */ - getValue(resource: URI, section?: string): T; - getValue(resource: URI, position?: IPosition, section?: string): T; + getValue(resource: URI | undefined, section?: string): T; + getValue(resource: URI | undefined, position?: IPosition, section?: string): T; } diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts index c5c6bcb72ca..c8241f591cb 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts @@ -82,7 +82,7 @@ export class TextFileEditor extends BaseTextEditor { } private updateRestoreViewStateConfiguration(): void { - this.restoreViewState = this.configurationService.getValue(null, 'workbench.editor.restoreViewState'); + this.restoreViewState = this.configurationService.getValue(undefined, 'workbench.editor.restoreViewState'); } getTitle(): string { @@ -198,7 +198,7 @@ export class TextFileEditor extends BaseTextEditor { } if ((error).fileOperationResult === FileOperationResult.FILE_EXCEED_MEMORY_LIMIT) { - const memoryLimit = Math.max(MIN_MAX_MEMORY_SIZE_MB, +this.configurationService.getValue(null, 'files.maxMemoryForLargeFilesMB') || FALLBACK_MAX_MEMORY_SIZE_MB); + const memoryLimit = Math.max(MIN_MAX_MEMORY_SIZE_MB, +this.configurationService.getValue(undefined, 'files.maxMemoryForLargeFilesMB') || FALLBACK_MAX_MEMORY_SIZE_MB); return Promise.reject(createErrorWithActions(toErrorMessage(error), { actions: [ @@ -228,6 +228,9 @@ export class TextFileEditor extends BaseTextEditor { } private openAsFolder(input: FileEditorInput): void { + if (!this.group) { + return; + } // Since we cannot open a folder, we have to restore the previous input if any and close the editor this.group.closeEditor(this.input).then(() => { From a6c498b74a33b3e219ff957cee1b7d37170c2102 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 11:38:28 -0800 Subject: [PATCH 247/290] Strict null check fileService --- src/tsconfig.strictNullChecks.json | 1 + .../workbench/services/files/node/encoding.ts | 2 +- .../services/files/node/fileService.ts | 36 ++++++++++--------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index b97d15467c0..c4464341e9b 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -409,6 +409,7 @@ "./vs/workbench/services/extensions/node/rpcProtocol.ts", "./vs/workbench/services/extensions/test/node/rpcProtocol.test.ts", "./vs/workbench/services/files/node/encoding.ts", + "./vs/workbench/services/files/node/fileService.ts", "./vs/workbench/services/files/node/streams.ts", "./vs/workbench/services/files/test/electron-browser/utils.ts", "./vs/workbench/services/files/test/electron-browser/watcher.test.ts", diff --git a/src/vs/workbench/services/files/node/encoding.ts b/src/vs/workbench/services/files/node/encoding.ts index b600d76c684..62067cb504f 100644 --- a/src/vs/workbench/services/files/node/encoding.ts +++ b/src/vs/workbench/services/files/node/encoding.ts @@ -49,7 +49,7 @@ export class ResourceEncodings extends Disposable implements IResourceEncodings })); } - getReadEncoding(resource: uri, options: IResolveContentOptions, detected: encoding.IDetectedEncodingResult): string { + getReadEncoding(resource: uri, options: IResolveContentOptions | undefined, detected: encoding.IDetectedEncodingResult): string { let preferredEncoding: string | undefined; // Encoding passed in as option diff --git a/src/vs/workbench/services/files/node/fileService.ts b/src/vs/workbench/services/files/node/fileService.ts index f9b20baae2e..3302a7b90a0 100644 --- a/src/vs/workbench/services/files/node/fileService.ts +++ b/src/vs/workbench/services/files/node/fileService.ts @@ -70,7 +70,7 @@ export class FileService extends Disposable implements IFileService { protected readonly _onDidChangeFileSystemProviderRegistrations = this._register(new Emitter()); get onDidChangeFileSystemProviderRegistrations(): Event { return this._onDidChangeFileSystemProviderRegistrations.event; } - private activeWorkspaceFileChangeWatcher: IDisposable; + private activeWorkspaceFileChangeWatcher: IDisposable | null; private activeFileChangesWatchers: ResourceMap<{ unwatch: Function, count: number }>; private fileChangesWatchDelayer: ThrottledDelayer; private undeliveredRawFileChangesEvents: IRawFileChange[]; @@ -262,7 +262,7 @@ export class FileService extends Disposable implements IFileService { )); } - const result: IStreamContent = { + const result: Partial = { resource: undefined, name: undefined, mtime: undefined, @@ -311,7 +311,7 @@ export class FileService extends Disposable implements IFileService { // Return early if file is too large to load if (typeof stat.size === 'number') { - if (stat.size > Math.max(parseInt(this.environmentService.args['max-memory']) * 1024 * 1024 || 0, MAX_HEAP_SIZE)) { + if (stat.size > Math.max(typeof this.environmentService.args['max-memory'] === 'string' ? parseInt(this.environmentService.args['max-memory']) * 1024 * 1024 || 0 : 0, MAX_HEAP_SIZE)) { return onStatError(new FileOperationError( nls.localize('fileTooLargeForHeapError', "To open a file of this size, you need to restart VS Code and allow it to use more memory"), FileOperationResult.FILE_EXCEED_MEMORY_LIMIT @@ -391,17 +391,17 @@ export class FileService extends Disposable implements IFileService { }); } - private fillInContents(content: IStreamContent, resource: uri, options: IResolveContentOptions, token: CancellationToken): Promise { + private fillInContents(content: Partial, resource: uri, options: IResolveContentOptions | undefined, token: CancellationToken): Promise { return this.resolveFileData(resource, options, token).then(data => { content.encoding = data.encoding; content.value = data.stream; }); } - private resolveFileData(resource: uri, options: IResolveContentOptions, token: CancellationToken): Promise { + private resolveFileData(resource: uri, options: IResolveContentOptions | undefined, token: CancellationToken): Promise { const chunkBuffer = Buffer.allocUnsafe(64 * 1024); - const result: IContentData = { + const result: Partial = { encoding: undefined, stream: undefined }; @@ -473,7 +473,7 @@ export class FileService extends Disposable implements IFileService { } }; - let currentPosition: number = (options && options.position) || null; + let currentPosition: number | null = (options && options.position) || null; const readChunk = () => { fs.read(fd, chunkBuffer, 0, chunkBuffer.length, currentPosition, (err, bytesRead) => { @@ -485,7 +485,7 @@ export class FileService extends Disposable implements IFileService { currentPosition += bytesRead; } - if (totalBytesRead > Math.max(parseInt(this.environmentService.args['max-memory']) * 1024 * 1024 || 0, MAX_HEAP_SIZE)) { + if (totalBytesRead > Math.max(typeof this.environmentService.args['max-memory'] === 'number' ? parseInt(this.environmentService.args['max-memory']) * 1024 * 1024 || 0 : 0, MAX_HEAP_SIZE)) { finish(new FileOperationError( nls.localize('fileTooLargeForHeapError', "To open a file of this size, you need to restart VS Code and allow it to use more memory"), FileOperationResult.FILE_EXCEED_MEMORY_LIMIT @@ -525,7 +525,7 @@ export class FileService extends Disposable implements IFileService { } else { result.encoding = this._encoding.getReadEncoding(resource, options, detected); result.stream = decoder = encoding.decodeStream(result.encoding); - resolve(result); + resolve(result as IContentData); handleChunk(bytesRead); } }).then(undefined, err => { @@ -1168,16 +1168,18 @@ export class StatResolver { let absoluteTargetPaths: string[] | null = null; if (options && options.resolveTo) { absoluteTargetPaths = []; - options.resolveTo.forEach(resource => { + for (const resource of options.resolveTo) { absoluteTargetPaths.push(resource.fsPath); - }); + } } return new Promise(resolve => { // Load children - this.resolveChildren(this.resource.fsPath, absoluteTargetPaths, options && options.resolveSingleChildDescendants, children => { - children = arrays.coalesce(children); // we don't want those null children (could be permission denied when reading a child) + this.resolveChildren(this.resource.fsPath, absoluteTargetPaths, !!(options && options.resolveSingleChildDescendants), children => { + if (children) { + children = arrays.coalesce(children); // we don't want those null children (could be permission denied when reading a child) + } fileStat.children = children || []; resolve(fileStat); @@ -1186,7 +1188,7 @@ export class StatResolver { } } - private resolveChildren(absolutePath: string, absoluteTargetPaths: string[], resolveSingleChildDescendants: boolean, callback: (children: IFileStat[]) => void): void { + private resolveChildren(absolutePath: string, absoluteTargetPaths: string[] | null, resolveSingleChildDescendants: boolean, callback: (children: IFileStat[] | null) => void): void { extfs.readdir(absolutePath, (error: Error, files: string[]) => { if (error) { if (this.errorLogger) { @@ -1197,7 +1199,7 @@ export class StatResolver { } // for each file in the folder - flow.parallel(files, (file: string, clb: (error: Error, children: IFileStat) => void) => { + flow.parallel(files, (file: string, clb: (error: Error | null, children: IFileStat | null) => void) => { const fileResource = uri.file(paths.resolve(absolutePath, file)); let fileStat: fs.Stats; let isSymbolicLink = false; @@ -1257,7 +1259,9 @@ export class StatResolver { // Continue resolving children based on condition if (resolveFolderChildren) { $this.resolveChildren(fileResource.fsPath, absoluteTargetPaths, resolveSingleChildDescendants, children => { - children = arrays.coalesce(children); // we don't want those null children + if (children) { + children = arrays.coalesce(children); // we don't want those null children + } childStat.children = children || []; clb(null, childStat); From f521072eccde9f258a20740a7ce5d98407de7530 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 12:01:14 -0800 Subject: [PATCH 248/290] Strict null check configurationEditingService --- src/tsconfig.strictNullChecks.json | 1 + .../node/configurationEditingService.ts | 52 ++++++++++++------- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index c4464341e9b..5e4c68bfe68 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -381,6 +381,7 @@ "./vs/workbench/services/configuration/common/configurationModels.ts", "./vs/workbench/services/configuration/common/jsonEditing.ts", "./vs/workbench/services/configuration/node/configuration.ts", + "./vs/workbench/services/configuration/node/configurationEditingService.ts", "./vs/workbench/services/configuration/node/jsonEditingService.ts", "./vs/workbench/services/configuration/test/common/configurationModels.test.ts", "./vs/workbench/services/configurationResolver/common/configurationResolver.ts", diff --git a/src/vs/workbench/services/configuration/node/configurationEditingService.ts b/src/vs/workbench/services/configuration/node/configurationEditingService.ts index 6943c5b3819..d559ff78819 100644 --- a/src/vs/workbench/services/configuration/node/configurationEditingService.ts +++ b/src/vs/workbench/services/configuration/node/configurationEditingService.ts @@ -22,7 +22,7 @@ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfile import { IConfigurationService, IConfigurationOverrides, keyFromOverrideIdentifier, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { FOLDER_SETTINGS_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY } from 'vs/workbench/services/configuration/common/configuration'; import { IFileService } from 'vs/platform/files/common/files'; -import { ITextModelService, ITextEditorModel } from 'vs/editor/common/services/resolverService'; +import { ITextModelService, IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; import { OVERRIDE_PROPERTY_PATTERN, IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextModel } from 'vs/editor/common/model'; @@ -106,7 +106,7 @@ export interface IConfigurationEditingOptions { interface IConfigurationEditOperation extends IConfigurationValue { target: ConfigurationTarget; jsonPath: json.JSONPath; - resource: URI; + resource?: URI; workspaceStandAloneConfigurationKey?: string; } @@ -158,7 +158,7 @@ export class ConfigurationEditingService { private async writeToBuffer(model: ITextModel, operation: IConfigurationEditOperation, save: boolean): Promise { const edit = this.getEdits(model, operation)[0]; if (edit && this.applyEditsToBuffer(edit, model) && save) { - return this.textFileService.save(operation.resource, { skipSaveParticipants: true /* programmatic change */ }); + return this.textFileService.save(operation.resource!, { skipSaveParticipants: true /* programmatic change */ }); } } @@ -175,7 +175,7 @@ export class ConfigurationEditingService { return false; } - private onError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides): void { + private onError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides | undefined): void { switch (error.code) { case ConfigurationEditingErrorCode.ERROR_INVALID_CONFIGURATION: this.onInvalidConfigurationError(error, operation); @@ -196,7 +196,7 @@ export class ConfigurationEditingService { this.notificationService.prompt(Severity.Error, error.message, [{ label: openStandAloneConfigurationActionLabel, - run: () => this.openFile(operation.resource) + run: () => this.openFile(operation.resource!) }] ); } else { @@ -209,7 +209,7 @@ export class ConfigurationEditingService { } } - private onConfigurationFileDirtyError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides): void { + private onConfigurationFileDirtyError(error: ConfigurationEditingError, operation: IConfigurationEditOperation, scopes: IConfigurationOverrides | undefined): void { const openStandAloneConfigurationActionLabel = operation.workspaceStandAloneConfigurationKey === TASKS_CONFIGURATION_KEY ? nls.localize('openTasksConfiguration', "Open Tasks Configuration") : operation.workspaceStandAloneConfigurationKey === LAUNCH_CONFIGURATION_KEY ? nls.localize('openLaunchConfiguration', "Open Launch Configuration") : null; @@ -218,13 +218,13 @@ export class ConfigurationEditingService { [{ label: nls.localize('saveAndRetry', "Save and Retry"), run: () => { - const key = operation.key ? `${operation.workspaceStandAloneConfigurationKey}.${operation.key}` : operation.workspaceStandAloneConfigurationKey; + const key = operation.key ? `${operation.workspaceStandAloneConfigurationKey}.${operation.key}` : operation.workspaceStandAloneConfigurationKey!; this.writeConfiguration(operation.target, { key, value: operation.value }, { force: true, scopes }); } }, { label: openStandAloneConfigurationActionLabel, - run: () => this.openFile(operation.resource) + run: () => this.openFile(operation.resource!) }] ); } else { @@ -296,7 +296,13 @@ export class ConfigurationEditingService { case ConfigurationTarget.WORKSPACE: return nls.localize('errorInvalidConfigurationWorkspace', "Unable to write into workspace settings. Please open the workspace settings to correct errors/warnings in the file and try again."); case ConfigurationTarget.WORKSPACE_FOLDER: - const workspaceFolderName = this.contextService.getWorkspaceFolder(operation.resource).name; + let workspaceFolderName: string = '<>'; + if (operation.resource) { + const folder = this.contextService.getWorkspaceFolder(operation.resource); + if (folder) { + workspaceFolderName = folder.name; + } + } return nls.localize('errorInvalidConfigurationFolder', "Unable to write into folder settings. Please open the '{0}' folder settings to correct errors/warnings in it and try again.", workspaceFolderName); } return ''; @@ -314,7 +320,13 @@ export class ConfigurationEditingService { case ConfigurationTarget.WORKSPACE: return nls.localize('errorConfigurationFileDirtyWorkspace', "Unable to write into workspace settings because the file is dirty. Please save the workspace settings file first and then try again."); case ConfigurationTarget.WORKSPACE_FOLDER: - const workspaceFolderName = this.contextService.getWorkspaceFolder(operation.resource).name; + let workspaceFolderName: string = '<>'; + if (operation.resource) { + const folder = this.contextService.getWorkspaceFolder(operation.resource); + if (folder) { + workspaceFolderName = folder.name; + } + } return nls.localize('errorConfigurationFileDirtyFolder', "Unable to write into folder settings because the file is dirty. Please save the '{0}' folder settings file first and then try again.", workspaceFolderName); } return ''; @@ -352,7 +364,7 @@ export class ConfigurationEditingService { return setProperty(model.getValue(), jsonPath, value, { tabSize, insertSpaces, eol }); } - private async resolveModelReference(resource: URI): Promise> { + private async resolveModelReference(resource: URI): Promise> { const exists = await this.fileService.existsFile(resource); if (!exists) { await this.fileService.updateContent(resource, '{}', { encoding: encoding.UTF8 }); @@ -371,7 +383,7 @@ export class ConfigurationEditingService { return parseErrors.length > 0; } - private resolveAndValidate(target: ConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise> { + private resolveAndValidate(target: ConfigurationTarget, operation: IConfigurationEditOperation, checkDirty: boolean, overrides: IConfigurationOverrides): Promise> { // Any key must be a known setting from the registry (unless this is a standalone config) if (!operation.workspaceStandAloneConfigurationKey) { @@ -420,6 +432,10 @@ export class ConfigurationEditingService { } } + if (!operation.resource) { + return this.reject(ConfigurationEditingErrorCode.ERROR_INVALID_FOLDER_TARGET, target, operation); + } + return this.resolveModelReference(operation.resource) .then(reference => { const model = reference.object.textEditorModel; @@ -447,14 +463,14 @@ export class ConfigurationEditingService { // Check for prefix if (config.key === key) { const jsonPath = this.isWorkspaceConfigurationResource(resource) ? [key] : []; - return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource, workspaceStandAloneConfigurationKey: key, target }; + return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource: resource || undefined, workspaceStandAloneConfigurationKey: key, target }; } // Check for prefix. const keyPrefix = `${key}.`; if (config.key.indexOf(keyPrefix) === 0) { const jsonPath = this.isWorkspaceConfigurationResource(resource) ? [key, config.key.substr(keyPrefix.length)] : [config.key.substr(keyPrefix.length)]; - return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource, workspaceStandAloneConfigurationKey: key, target }; + return { key: jsonPath[jsonPath.length - 1], jsonPath, value: config.value, resource: resource || undefined, workspaceStandAloneConfigurationKey: key, target }; } } } @@ -469,15 +485,15 @@ export class ConfigurationEditingService { if (this.isWorkspaceConfigurationResource(resource)) { jsonPath = ['settings', ...jsonPath]; } - return { key, jsonPath, value: config.value, resource, target }; + return { key, jsonPath, value: config.value, resource: resource || undefined, target }; } - private isWorkspaceConfigurationResource(resource: URI): boolean { + private isWorkspaceConfigurationResource(resource: URI | null | undefined): boolean { const workspace = this.contextService.getWorkspace(); return !!(workspace.configuration && resource && workspace.configuration.fsPath === resource.fsPath); } - private getConfigurationFileResource(target: ConfigurationTarget, relativePath: string, resource: URI): URI { + private getConfigurationFileResource(target: ConfigurationTarget, relativePath: string, resource: URI | null | undefined): URI | null { if (target === ConfigurationTarget.USER) { return URI.file(this.environmentService.appSettingsPath); } @@ -489,7 +505,7 @@ export class ConfigurationEditingService { if (target === ConfigurationTarget.WORKSPACE) { if (workbenchState === WorkbenchState.WORKSPACE) { - return workspace.configuration; + return workspace.configuration || null; } if (workbenchState === WorkbenchState.FOLDER) { return workspace.folders[0].toResource(relativePath); From 37732e9cedbb5de49e5b1af3ae4656a420f8892e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 13:01:27 -0800 Subject: [PATCH 249/290] Strict null check titlebarPart --- src/tsconfig.strictNullChecks.json | 1 + src/vs/base/common/labels.ts | 2 +- .../workbench/browser/parts/titlebar/titlebarPart.ts | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 5e4c68bfe68..472a84395ad 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -147,6 +147,7 @@ "./vs/workbench/browser/parts/statusbar/statusbar.ts", "./vs/workbench/browser/parts/statusbar/statusbarPart.ts", "./vs/workbench/browser/parts/titlebar/menubarControl.ts", + "./vs/workbench/browser/parts/titlebar/titlebarPart.ts", "./vs/workbench/browser/parts/views/customView.ts", "./vs/workbench/browser/parts/views/panelViewlet.ts", "./vs/workbench/browser/parts/views/views.ts", diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index dc55a8db24a..aea4b726f2f 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -283,7 +283,7 @@ interface ISegment { * @param value string to which templating is applied * @param values the values of the templates to use */ -export function template(template: string, values: { [key: string]: string | ISeparator } = Object.create(null)): string { +export function template(template: string, values: { [key: string]: string | ISeparator | null } = Object.create(null)): string { const segments: ISegment[] = []; let inVariable = false; diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 768cbe3ef10..9bb6b629cf9 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -180,7 +180,7 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi } private updateRepresentedFilename(): void { - const file = toResource(this.editorService.activeEditor, { supportSideBySide: true, filter: 'file' }); + const file = toResource(this.editorService.activeEditor || null, { supportSideBySide: true, filter: 'file' }); const path = file ? file.fsPath : ''; // Apply to window @@ -283,7 +283,7 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi // Compute folder resource // Single Root Workspace: always the root single workspace in this case // Otherwise: root folder of the currently active file if any - const folder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(editor, { supportSideBySide: true })); + const folder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER ? workspace.folders[0] : this.contextService.getWorkspaceFolder(toResource(editor || null, { supportSideBySide: true })!); // Variables const activeEditorShort = editor ? editor.getTitle(Verbosity.SHORT) : ''; @@ -473,7 +473,7 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi const titleBackground = this.getColor(this.isInactive ? TITLE_BAR_INACTIVE_BACKGROUND : TITLE_BAR_ACTIVE_BACKGROUND); this.element.style.backgroundColor = titleBackground; - if (Color.fromHex(titleBackground).isLighter()) { + if (titleBackground && Color.fromHex(titleBackground).isLighter()) { addClass(this.element, 'light'); } else { removeClass(this.element, 'light'); @@ -582,7 +582,7 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter()); if (this.menubarPart) { - const menubarDimension = new Dimension(undefined, dimension.height); + const menubarDimension = new Dimension(0, dimension.height); this.menubarPart.layout(menubarDimension); } } @@ -597,7 +597,7 @@ export class TitlebarPart extends Part implements ITitleService, ISerializableVi return super.layout(dim1); } - const dimensions = new Dimension(dim1, dim2); + const dimensions = new Dimension(dim1, dim2!); this.updateLayout(dimensions); super.layout(dimensions); From d862e3217a5b3b96935b22c6d2c1d6f3f242cddd Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 12:16:08 -0800 Subject: [PATCH 250/290] Fix #66796 - previously there was weird listener behavior described in that issue but it has disappeared --- .../preferences/electron-browser/settingsEditor2.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts index 522b03a65a2..e33e245fe49 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts @@ -583,11 +583,8 @@ export class SettingsEditor2 extends BaseEditor { if (this.searchResultModel) { if (this.viewState.filterToCategory !== element) { this.viewState.filterToCategory = element; - // see https://github.com/Microsoft/vscode/issues/66796 - setTimeout(() => { - this.renderTree(); - this.settingsTree.scrollTop = 0; - }, 0); + this.renderTree(); + this.settingsTree.scrollTop = 0; } } else if (element && (!e.browserEvent || !(e.browserEvent).fromScroll)) { this.settingsTree.reveal(element, 0); From b7673fb6f4f280c4ea6b9e7bdd22fb5dabebdc45 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 12:18:56 -0800 Subject: [PATCH 251/290] :lipstick: --- .../preferences/electron-browser/settingsEditor2.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts index e33e245fe49..e30905c2ebe 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts @@ -56,6 +56,10 @@ function createGroupIterator(group: SettingsTreeGroupElement): Iteratore.browserEvent).fromScroll)) { + } else if (element && (!e.browserEvent || !(e.browserEvent).fromScroll)) { this.settingsTree.reveal(element, 0); } })); @@ -709,7 +713,7 @@ export class SettingsEditor2 extends BaseEditor { this.tocTree.setSelection([element]); const fakeKeyboardEvent = new KeyboardEvent('keydown'); - (fakeKeyboardEvent).fromScroll = true; + (fakeKeyboardEvent).fromScroll = true; this.tocTree.setFocus([element], fakeKeyboardEvent); } } From 8764eaf579c40396438d260573f9f002c774204e Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 12:43:17 -0800 Subject: [PATCH 252/290] Fix #64749 - firstVisibleIndex in tree should consider element midpoint --- src/vs/base/browser/ui/list/listView.ts | 9 +++++ .../electron-browser/settingsEditor2.ts | 33 ++----------------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index ac85245b2fe..a4f93a958c7 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -445,6 +445,15 @@ export class ListView implements ISpliceable, IDisposable { get firstVisibleIndex(): number { const range = this.getRenderRange(this.lastRenderTop, this.lastRenderHeight); + const firstElTop = this.rangeMap.positionAt(range.start); + const nextElTop = this.rangeMap.positionAt(range.start + 1); + if (nextElTop !== -1) { + const firstElMidpoint = (nextElTop - firstElTop) / 2 + firstElTop; + if (firstElMidpoint < this.scrollTop) { + return range.start + 1; + } + } + return range.start; } diff --git a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts index e30905c2ebe..efdfdce5654 100644 --- a/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/electron-browser/settingsEditor2.ts @@ -273,9 +273,6 @@ export class SettingsEditor2 extends BaseEditor { } layout(dimension: DOM.Dimension): void { - // const firstEl = this.settingsTree.getFirstVisibleElement(); - // const firstElTop = this.settingsTree.getRelativeTop(firstEl); - this.layoutTrees(dimension); const innerWidth = dimension.width - 24 * 2; // 24px padding on left and right @@ -497,7 +494,7 @@ export class SettingsEditor2 extends BaseEditor { e => { if (DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) { if (this.settingsTree.scrollTop > 0) { - const firstElement = this.getFirstVisibleElement(); + const firstElement = this.settingsTree.firstVisibleElement; this.settingsTree.reveal(firstElement, 0.1); return true; } @@ -519,7 +516,7 @@ export class SettingsEditor2 extends BaseEditor { e => { if (DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) { if (this.settingsTree.scrollTop < this.settingsTree.scrollHeight) { - const lastElement = this.getLastVisibleElement(); + const lastElement = this.settingsTree.lastVisibleElement; this.settingsTree.reveal(lastElement, 0.9); return true; } @@ -531,30 +528,6 @@ export class SettingsEditor2 extends BaseEditor { ); } - private getFirstVisibleElement(nth = 0): SettingsTreeElement | null { - // Hack, see https://github.com/Microsoft/vscode/issues/64749 - const settingItems = this.settingsTree.getHTMLElement().querySelectorAll(AbstractSettingRenderer.CONTENTS_SELECTOR); - const firstEl = settingItems[nth] || settingItems[0]; - if (!firstEl) { - return null; - } - - const firstSettingId = this.settingRenderers.getIdForDOMElementInSetting(firstEl); - return this.settingsTreeModel.getElementById(firstSettingId); - } - - private getLastVisibleElement(): SettingsTreeElement | null { - // Hack, see https://github.com/Microsoft/vscode/issues/64749 - const settingItems = this.settingsTree.getHTMLElement().querySelectorAll(AbstractSettingRenderer.CONTENTS_SELECTOR); - const firstEl = settingItems[settingItems.length - 1]; - if (!firstEl) { - return null; - } - - const firstSettingId = this.settingRenderers.getIdForDOMElementInSetting(firstEl); - return this.settingsTreeModel.getElementById(firstSettingId); - } - 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); @@ -688,7 +661,7 @@ export class SettingsEditor2 extends BaseEditor { return; } - const elementToSync = this.getFirstVisibleElement(1); + const elementToSync = this.settingsTree.firstVisibleElement; const element = elementToSync instanceof SettingsTreeSettingElement ? elementToSync.parent : elementToSync instanceof SettingsTreeGroupElement ? elementToSync : null; From f3b73b1abc694c9d61b5c58832e02c1f2a0792a8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 11:07:44 -0800 Subject: [PATCH 253/290] Fix #69862 - don't split comma-separated globs when expandPatterns is disabled (for findFiles) --- src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts | 1 + src/vs/workbench/contrib/search/common/queryBuilder.ts | 4 ++-- .../contrib/search/test/common/queryBuilder.test.ts | 5 ++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index 63d67c6aa05..fa5e5cc13b8 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -181,6 +181,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { const query = queryBuilder.file(folders, { _reason: 'checkExists', includePattern: includes.join(', '), + expandPatterns: true, exists: true }); diff --git a/src/vs/workbench/contrib/search/common/queryBuilder.ts b/src/vs/workbench/contrib/search/common/queryBuilder.ts index ccf08d86b81..2cc16e6d342 100644 --- a/src/vs/workbench/contrib/search/common/queryBuilder.ts +++ b/src/vs/workbench/contrib/search/common/queryBuilder.ts @@ -152,14 +152,14 @@ export class QueryBuilder { if (options.includePattern) { includeSearchPathsInfo = options.expandPatterns ? this.parseSearchPaths(options.includePattern) : - { pattern: patternListToIExpression(...splitGlobPattern(options.includePattern)) }; + { pattern: patternListToIExpression(options.includePattern) }; } let excludeSearchPathsInfo: ISearchPathsInfo = {}; if (options.excludePattern) { excludeSearchPathsInfo = options.expandPatterns ? this.parseSearchPaths(options.excludePattern) : - { pattern: patternListToIExpression(...splitGlobPattern(options.excludePattern)) }; + { pattern: patternListToIExpression(options.excludePattern) }; } // Build folderQueries from searchPaths, if given, otherwise folderResources diff --git a/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts b/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts index 5fc42bc4901..aaa35bae3db 100644 --- a/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts +++ b/src/vs/workbench/contrib/search/test/common/queryBuilder.test.ts @@ -85,7 +85,7 @@ suite('QueryBuilder', () => { }); }); - test('splits glob pattern even with expandPatterns disabled', () => { + test('does not split glob pattern when expandPatterns disabled', () => { assertEqualQueries( queryBuilder.file([ROOT_1_URI], { includePattern: '**/foo, **/bar' }), { @@ -94,8 +94,7 @@ suite('QueryBuilder', () => { }], type: QueryType.File, includePattern: { - '**/foo': true, - '**/bar': true + '**/foo, **/bar': true } }); }); From 10fdea204aec021914d473d6ac019c6064ce4620 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 10:36:18 -0800 Subject: [PATCH 254/290] Fix #69840 --- .../src/singlefolder-tests/workspace.test.ts | 9 ++++++++- .../api/electron-browser/mainThreadWorkspace.ts | 1 + 2 files changed, 9 insertions(+), 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 1deca1ad443..2f46c461b3f 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -488,7 +488,14 @@ suite('workspace-namespace', () => { }); test('findFiles', () => { - return vscode.workspace.findFiles('*.png').then((res) => { + return vscode.workspace.findFiles('**/*.png').then((res) => { + assert.equal(res.length, 2); + assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); + }); + }); + + test('findFiles, exclude', () => { + return vscode.workspace.findFiles('**/*.png', '**/sub/**').then((res) => { assert.equal(res.length, 1); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index fa5e5cc13b8..fe39eeef61a 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -134,6 +134,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { disregardSearchExcludeSettings: true, disregardIgnoreFiles: true, includePattern, + excludePattern: typeof excludePatternOrDisregardExcludes === 'string' ? excludePatternOrDisregardExcludes : undefined, _reason: 'startFileSearch' }); From 6770dd762d5ce0293ea9b58611a4f922979d4b5a Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Tue, 5 Mar 2019 16:02:39 -0800 Subject: [PATCH 255/290] fix/69830 --- src/vs/base/browser/ui/menu/menubar.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index 289bfd8f369..a4283053ab0 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -954,6 +954,16 @@ class ModifierKeyEmitter extends Emitter { this._keyStatus.lastKeyPressed = undefined; })); + this._subscriptions.push(domEvent(document.body, 'mouseup', true)(e => { + this._keyStatus.lastKeyPressed = undefined; + })); + + this._subscriptions.push(domEvent(document.body, 'mousemove', true)(e => { + if (e.buttons) { + this._keyStatus.lastKeyPressed = undefined; + } + })); + this._subscriptions.push(domEvent(window, 'blur')(e => { this._keyStatus.lastKeyPressed = undefined; this._keyStatus.lastKeyReleased = undefined; From e3964c95d232688eeb9585d96d4382be9c728537 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 14:14:06 -0800 Subject: [PATCH 256/290] Strict null check webview --- src/tsconfig.strictNullChecks.json | 9 +++++++-- .../webview/electron-browser/webviewEditorService.ts | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 472a84395ad..d35a1a5d671 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -29,7 +29,8 @@ "./vs/workbench/services/bulkEdit/**/*.ts", "./vs/workbench/services/progress/**/*.ts", "./vs/workbench/services/preferences/**/*.ts", - "./vs/workbench/services/timer/**/*.ts" + "./vs/workbench/services/timer/**/*.ts", + "./vs/workbench/contrib/webview/**/*.ts" ], "files": [ "./vs/monaco.d.ts", @@ -238,8 +239,10 @@ "./vs/workbench/contrib/extensions/common/extensionsFileTemplate.ts", "./vs/workbench/contrib/extensions/common/extensionsInput.ts", "./vs/workbench/contrib/extensions/common/extensionsUtils.ts", + "./vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts", + "./vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsActivationProgress.ts", "./vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler.ts", @@ -370,8 +373,10 @@ "./vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts", "./vs/workbench/contrib/themes/browser/themes.contribution.ts", "./vs/workbench/contrib/themes/test/electron-browser/themes.test.contribution.ts", + "./vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts", + "./vs/workbench/contrib/update/electron-browser/update.contribution.ts", + "./vs/workbench/contrib/update/electron-browser/update.ts", "./vs/workbench/contrib/url/common/url.contribution.ts", - "./vs/workbench/contrib/webview/electron-browser/webviewProtocols.ts", "./vs/workbench/electron-browser/window.ts", "./vs/workbench/services/activity/browser/activityService.ts", "./vs/workbench/services/activity/common/activity.ts", diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts index 234d1a1bcad..4fdb9469e84 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewEditorService.ts @@ -12,6 +12,7 @@ import * as vscode from 'vscode'; import { WebviewEditorInput, RevivedWebviewEditorInput } from './webviewEditorInput'; import { GroupIdentifier } from 'vs/workbench/common/editor'; import { equals } from 'vs/base/common/arrays'; +import { values } from 'vs/base/common/map'; export const IWebviewEditorService = createDecorator('webviewEditorService'); @@ -169,7 +170,7 @@ export class WebviewEditorService implements IWebviewEditorService { canRevive( webview: WebviewEditorInput ): boolean { - for (const reviver of this._revivers) { + for (const reviver of values(this._revivers)) { if (reviver.canRevive(webview)) { return true; } @@ -180,7 +181,7 @@ export class WebviewEditorService implements IWebviewEditorService { private async tryRevive( webview: WebviewEditorInput ): Promise { - for (const reviver of this._revivers) { + for (const reviver of values(this._revivers)) { if (reviver.canRevive(webview)) { await reviver.reviveWebview(webview); return true; From 480b838ef2e1851aeb80c2cd965140e09c831b27 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 14:26:03 -0800 Subject: [PATCH 257/290] Strict null check apiCommands --- src/tsconfig.strictNullChecks.json | 1 + src/vs/editor/common/core/editOperation.ts | 4 ++-- src/vs/editor/common/model.ts | 2 +- src/vs/editor/contrib/format/formattingEdit.ts | 2 +- src/vs/monaco.d.ts | 2 +- .../mainThreadSaveParticipant.ts | 12 ++++++------ .../api/node/extHostDocumentsAndEditors.ts | 14 +++++++------- src/vs/workbench/api/node/extHostTextEditor.ts | 18 +++++++++--------- 8 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index d35a1a5d671..1dc078954e6 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -74,6 +74,7 @@ "./vs/workbench/api/electron-browser/mainThreadUrls.ts", "./vs/workbench/api/electron-browser/mainThreadWindow.ts", "./vs/workbench/api/electron-browser/mainThreadWorkspace.ts", + "./vs/workbench/api/node/apiCommands.ts", "./vs/workbench/api/node/extHost.protocol.ts", "./vs/workbench/api/node/extHostClipboard.ts", "./vs/workbench/api/node/extHostConfiguration.ts", diff --git a/src/vs/editor/common/core/editOperation.ts b/src/vs/editor/common/core/editOperation.ts index fe3cf2e6084..9029c7a3cf4 100644 --- a/src/vs/editor/common/core/editOperation.ts +++ b/src/vs/editor/common/core/editOperation.ts @@ -24,14 +24,14 @@ export class EditOperation { }; } - public static replace(range: Range, text: string): IIdentifiedSingleEditOperation { + public static replace(range: Range, text: string | null): IIdentifiedSingleEditOperation { return { range: range, text: text }; } - public static replaceMove(range: Range, text: string): IIdentifiedSingleEditOperation { + public static replaceMove(range: Range, text: string | null): IIdentifiedSingleEditOperation { return { range: range, text: text, diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index a15dd004bef..48a268b0bd6 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -289,7 +289,7 @@ export interface ISingleEditOperation { /** * The text to replace with. This can be null to emulate a simple delete. */ - text: string; + text: string | null; /** * This indicates that this operation has "insert" semantics. * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. diff --git a/src/vs/editor/contrib/format/formattingEdit.ts b/src/vs/editor/contrib/format/formattingEdit.ts index 23bab3f1830..27dbbd06762 100644 --- a/src/vs/editor/contrib/format/formattingEdit.ts +++ b/src/vs/editor/contrib/format/formattingEdit.ts @@ -45,7 +45,7 @@ export class FormattingEdit { static execute(editor: ICodeEditor, _edits: TextEdit[]) { editor.pushUndoStop(); - let edits = FormattingEdit._handleEolEdits(editor, _edits); + const edits = FormattingEdit._handleEolEdits(editor, _edits); if (edits.length === 1 && FormattingEdit._isFullModelReplaceEdit(editor, edits[0])) { // We use replace semantics and hope that markers stay put... editor.executeEdits('formatEditsCommand', edits.map(edit => EditOperation.replace(Range.lift(edit.range), edit.text))); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 3f279a4527c..af4d3f7f0d6 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1387,7 +1387,7 @@ declare namespace monaco.editor { /** * The text to replace with. This can be null to emulate a simple delete. */ - text: string; + text: string | null; /** * This indicates that this operation has "insert" semantics. * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index f83e76de7a4..32c7b8403af 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -16,8 +16,8 @@ import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; -import { IIdentifiedSingleEditOperation, ISingleEditOperation, ITextModel } from 'vs/editor/common/model'; -import { CodeAction } from 'vs/editor/common/modes'; +import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model'; +import { CodeAction, TextEdit } from 'vs/editor/common/modes'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService'; import { shouldSynchronizeModel } from 'vs/editor/common/services/modelService'; import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction'; @@ -234,7 +234,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { const timeout = this._configurationService.getValue('editor.formatOnSaveTimeout', { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() }); - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { let source = new CancellationTokenSource(); let request = getDocumentFormattingEdits(this._telemetryService, this._editorWorkerService, model, model.getFormattingOptions(), FormatMode.Auto, source.token); @@ -257,11 +257,11 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { }); } - private _editsWithEditor(editor: ICodeEditor, edits: ISingleEditOperation[]): void { + private _editsWithEditor(editor: ICodeEditor, edits: TextEdit[]): void { FormattingEdit.execute(editor, edits); } - private _editWithModel(model: ITextModel, edits: ISingleEditOperation[]): void { + private _editWithModel(model: ITextModel, edits: TextEdit[]): void { const [{ range }] = edits; const initialSelection = new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn); @@ -276,7 +276,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { }); } - private static _asIdentEdit({ text, range }: ISingleEditOperation): IIdentifiedSingleEditOperation { + private static _asIdentEdit({ text, range }: TextEdit): IIdentifiedSingleEditOperation { return { text, range: Range.lift(range), diff --git a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts index 57868da0161..c0e26886a58 100644 --- a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts @@ -17,7 +17,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha private _disposables: Disposable[] = []; - private _activeEditorId: string; + private _activeEditorId: string | null; private readonly _editors = new Map(); private readonly _documents = new Map(); @@ -25,12 +25,12 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha private readonly _onDidAddDocuments = new Emitter(); private readonly _onDidRemoveDocuments = new Emitter(); private readonly _onDidChangeVisibleTextEditors = new Emitter(); - private readonly _onDidChangeActiveTextEditor = new Emitter(); + private readonly _onDidChangeActiveTextEditor = new Emitter(); readonly onDidAddDocuments: Event = this._onDidAddDocuments.event; readonly onDidRemoveDocuments: Event = this._onDidRemoveDocuments.event; readonly onDidChangeVisibleTextEditors: Event = this._onDidChangeVisibleTextEditors.event; - readonly onDidChangeActiveTextEditor: Event = this._onDidChangeActiveTextEditor.event; + readonly onDidChangeActiveTextEditor: Event = this._onDidChangeActiveTextEditor.event; constructor( private readonly _mainContext: IMainContext, @@ -93,14 +93,14 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha assert.ok(this._documents.has(resource.toString()), `document '${resource}' does not exist`); assert.ok(!this._editors.has(data.id), `editor '${data.id}' already exists!`); - const documentData = this._documents.get(resource.toString()); + const documentData = this._documents.get(resource.toString())!; const editor = new ExtHostTextEditor( this._mainContext.getProxy(MainContext.MainThreadTextEditors), data.id, documentData, data.selections.map(typeConverters.Selection.to), data.options, - data.visibleRanges.map(typeConverters.Range.to), + data.visibleRanges.map(range => typeConverters.Range.to(range)), typeof data.editorPosition === 'number' ? typeConverters.ViewColumn.to(data.editorPosition) : undefined ); this._editors.set(data.id, editor); @@ -131,7 +131,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha } } - getDocument(uri: URI): ExtHostDocumentData { + getDocument(uri: URI): ExtHostDocumentData | undefined { return this._documents.get(uri.toString()); } @@ -141,7 +141,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha return result; } - getEditor(id: string): ExtHostTextEditor { + getEditor(id: string): ExtHostTextEditor | undefined { return this._editors.get(id); } diff --git a/src/vs/workbench/api/node/extHostTextEditor.ts b/src/vs/workbench/api/node/extHostTextEditor.ts index 3cb2231f1b8..ae9ea2f67cf 100644 --- a/src/vs/workbench/api/node/extHostTextEditor.ts +++ b/src/vs/workbench/api/node/extHostTextEditor.ts @@ -35,7 +35,7 @@ export class TextEditorDecorationType implements vscode.TextEditorDecorationType export interface ITextEditOperation { range: vscode.Range; - text: string; + text: string | null; forceMoveMarkers: boolean; } @@ -105,7 +105,7 @@ export class TextEditorEdit { this._pushEdit(range, null, true); } - private _pushEdit(range: Range, text: string, forceMoveMarkers: boolean): void { + private _pushEdit(range: Range, text: string | null, forceMoveMarkers: boolean): void { let validRange = this._document.validateRange(range); this._collectedEdits.push({ range: validRange, @@ -373,7 +373,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { private _selections: Selection[]; private _options: ExtHostTextEditorOptions; private _visibleRanges: Range[]; - private _viewColumn: vscode.ViewColumn; + private _viewColumn: vscode.ViewColumn | undefined; private _disposed: boolean = false; private _hasDecorationsForKey: { [key: string]: boolean; }; @@ -382,7 +382,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { constructor( proxy: MainThreadTextEditorsShape, id: string, document: ExtHostDocumentData, selections: Selection[], options: IResolvedTextEditorConfiguration, - visibleRanges: Range[], viewColumn: vscode.ViewColumn + visibleRanges: Range[], viewColumn: vscode.ViewColumn | undefined ) { this._proxy = proxy; this._id = id; @@ -451,7 +451,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { // ---- view column - get viewColumn(): vscode.ViewColumn { + get viewColumn(): vscode.ViewColumn | undefined { return this._viewColumn; } @@ -538,7 +538,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { ); } - private _trySetSelection(): Promise { + private _trySetSelection(): Promise { let selection = this._selections.map(TypeConverters.Selection.from); return this._runOnProxy(() => this._proxy.$trySetSelections(this._id, selection)); } @@ -598,7 +598,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { } // prepare data for serialization - let edits: ISingleEditOperation[] = editData.edits.map((edit) => { + const edits = editData.edits.map((edit): ISingleEditOperation => { return { range: TypeConverters.Range.from(edit.range), text: edit.text, @@ -620,7 +620,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { let ranges: IRange[]; if (!where || (Array.isArray(where) && where.length === 0)) { - ranges = this._selections.map(TypeConverters.Range.from); + ranges = this._selections.map(range => TypeConverters.Range.from(range)); } else if (where instanceof Position) { const { lineNumber, column } = TypeConverters.Position.from(where); @@ -645,7 +645,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { // ---- util - private _runOnProxy(callback: () => Promise): Promise { + private _runOnProxy(callback: () => Promise): Promise { if (this._disposed) { console.warn('TextEditor is closed/disposed'); return Promise.resolve(undefined); From 733a1cd8417309e1009e2eb28f5378cd63059c0a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 14:32:57 -0800 Subject: [PATCH 258/290] Strict null check extHostDocuments --- src/tsconfig.strictNullChecks.json | 9 ++++++++ src/vs/workbench/api/node/extHostDocuments.ts | 21 ++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 1dc078954e6..4028b21f89c 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -80,17 +80,26 @@ "./vs/workbench/api/node/extHostConfiguration.ts", "./vs/workbench/api/node/extHostDecorations.ts", "./vs/workbench/api/node/extHostDialogs.ts", + "./vs/workbench/api/node/extHostDocumentContentProviders.ts", "./vs/workbench/api/node/extHostDocumentData.ts", + "./vs/workbench/api/node/extHostDocuments.ts", + "./vs/workbench/api/node/extHostDocumentsAndEditors.ts", "./vs/workbench/api/node/extHostExtensionActivator.ts", + "./vs/workbench/api/node/extHostFileSystemEventService.ts", "./vs/workbench/api/node/extHostHeapService.ts", + "./vs/workbench/api/node/extHostLanguages.ts", "./vs/workbench/api/node/extHostLogService.ts", "./vs/workbench/api/node/extHostMessageService.ts", "./vs/workbench/api/node/extHostOutputService.ts", + "./vs/workbench/api/node/extHostProgress.ts", "./vs/workbench/api/node/extHostSearch.fileIndex.ts", "./vs/workbench/api/node/extHostSearch.ts", "./vs/workbench/api/node/extHostStorage.ts", + "./vs/workbench/api/node/extHostTextEditor.ts", + "./vs/workbench/api/node/extHostTypeConverters.ts", "./vs/workbench/api/node/extHostTypes.ts", "./vs/workbench/api/node/extHostUrls.ts", + "./vs/workbench/api/node/extHostWebview.ts", "./vs/workbench/api/node/extHostWindow.ts", "./vs/workbench/api/node/extHostWorkspace.ts", "./vs/workbench/api/shared/editor.ts", diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index a053696d1cf..40ae4c8a371 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -103,8 +103,10 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public $acceptModelModeChanged(uriComponents: UriComponents, oldModeId: string, newModeId: string): void { const uri = URI.revive(uriComponents); - let data = this._documentsAndEditors.getDocument(uri); - + const data = this._documentsAndEditors.getDocument(uri); + if (!data) { + throw new Error('unknown document'); + } // Treat a mode change as a remove + add this._onDidRemoveDocument.fire(data.document); @@ -114,14 +116,20 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public $acceptModelSaved(uriComponents: UriComponents): void { const uri = URI.revive(uriComponents); - let data = this._documentsAndEditors.getDocument(uri); + const data = this._documentsAndEditors.getDocument(uri); + if (!data) { + throw new Error('unknown document'); + } this.$acceptDirtyStateChanged(uriComponents, false); this._onDidSaveDocument.fire(data.document); } public $acceptDirtyStateChanged(uriComponents: UriComponents, isDirty: boolean): void { const uri = URI.revive(uriComponents); - let data = this._documentsAndEditors.getDocument(uri); + const data = this._documentsAndEditors.getDocument(uri); + if (!data) { + throw new Error('unknown document'); + } data._acceptIsDirty(isDirty); this._onDidChangeDocument.fire({ document: data.document, @@ -131,7 +139,10 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public $acceptModelChanged(uriComponents: UriComponents, events: IModelChangedEvent, isDirty: boolean): void { const uri = URI.revive(uriComponents); - let data = this._documentsAndEditors.getDocument(uri); + const data = this._documentsAndEditors.getDocument(uri); + if (!data) { + throw new Error('unknown document'); + } data._acceptIsDirty(isDirty); data.onEvents(events); this._onDidChangeDocument.fire({ From bb64391ec4ea6d59f6f8664e81e58fe4da734673 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 14:41:15 -0800 Subject: [PATCH 259/290] Strict null work in exthost --- src/tsconfig.strictNullChecks.json | 4 ++++ src/vs/workbench/api/node/extHostCLIServer.ts | 2 +- src/vs/workbench/api/node/extHostCommands.ts | 2 +- .../api/node/extHostDocumentSaveParticipant.ts | 2 +- src/vs/workbench/api/node/extHostTextEditors.ts | 12 +++++++++--- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 4028b21f89c..c8f807a4283 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -76,12 +76,15 @@ "./vs/workbench/api/electron-browser/mainThreadWorkspace.ts", "./vs/workbench/api/node/apiCommands.ts", "./vs/workbench/api/node/extHost.protocol.ts", + "./vs/workbench/api/node/extHostCLIServer.ts", "./vs/workbench/api/node/extHostClipboard.ts", + "./vs/workbench/api/node/extHostCommands.ts", "./vs/workbench/api/node/extHostConfiguration.ts", "./vs/workbench/api/node/extHostDecorations.ts", "./vs/workbench/api/node/extHostDialogs.ts", "./vs/workbench/api/node/extHostDocumentContentProviders.ts", "./vs/workbench/api/node/extHostDocumentData.ts", + "./vs/workbench/api/node/extHostDocumentSaveParticipant.ts", "./vs/workbench/api/node/extHostDocuments.ts", "./vs/workbench/api/node/extHostDocumentsAndEditors.ts", "./vs/workbench/api/node/extHostExtensionActivator.ts", @@ -96,6 +99,7 @@ "./vs/workbench/api/node/extHostSearch.ts", "./vs/workbench/api/node/extHostStorage.ts", "./vs/workbench/api/node/extHostTextEditor.ts", + "./vs/workbench/api/node/extHostTextEditors.ts", "./vs/workbench/api/node/extHostTypeConverters.ts", "./vs/workbench/api/node/extHostTypes.ts", "./vs/workbench/api/node/extHostUrls.ts", diff --git a/src/vs/workbench/api/node/extHostCLIServer.ts b/src/vs/workbench/api/node/extHostCLIServer.ts index 89f6c02d448..a2311b7f69e 100644 --- a/src/vs/workbench/api/node/extHostCLIServer.ts +++ b/src/vs/workbench/api/node/extHostCLIServer.ts @@ -39,7 +39,7 @@ export class CLIServer { console.error('Could not start open from terminal server.'); } - return this.ipcHandlePath; + return this._ipcHandlePath; } private collectURIToOpen(strs: string[], typeHint: URIType, result: IURIToOpen[]): void { if (Array.isArray(strs)) { diff --git a/src/vs/workbench/api/node/extHostCommands.ts b/src/vs/workbench/api/node/extHostCommands.ts index cc707471087..acf75cefcfb 100644 --- a/src/vs/workbench/api/node/extHostCommands.ts +++ b/src/vs/workbench/api/node/extHostCommands.ts @@ -22,7 +22,7 @@ import { URI } from 'vs/base/common/uri'; interface CommandHandler { callback: Function; thisArg: any; - description: ICommandHandlerDescription; + description?: ICommandHandlerDescription; } export interface ArgumentProcessor { diff --git a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts index 065e9e61a48..d8a99d2aaee 100644 --- a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts @@ -60,7 +60,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic if (didTimeout) { // timeout - no more listeners - return undefined; + return Promise.resolve(); } const document = this._documents.getDocument(resource); diff --git a/src/vs/workbench/api/node/extHostTextEditors.ts b/src/vs/workbench/api/node/extHostTextEditors.ts index 3b316662afb..5e6e2dfb5a1 100644 --- a/src/vs/workbench/api/node/extHostTextEditors.ts +++ b/src/vs/workbench/api/node/extHostTextEditors.ts @@ -97,6 +97,9 @@ export class ExtHostEditors implements ExtHostEditorsShape { $acceptEditorPropertiesChanged(id: string, data: IEditorPropertiesChangeData): void { const textEditor = this._extHostDocumentsAndEditors.getEditor(id); + if (!textEditor) { + throw new Error('unknown text editor'); + } // (1) set all properties if (data.options) { @@ -137,9 +140,12 @@ export class ExtHostEditors implements ExtHostEditorsShape { } $acceptEditorPositionData(data: ITextEditorPositionData): void { - for (let id in data) { - let textEditor = this._extHostDocumentsAndEditors.getEditor(id); - let viewColumn = TypeConverters.ViewColumn.to(data[id]); + for (const id in data) { + const textEditor = this._extHostDocumentsAndEditors.getEditor(id); + if (!textEditor) { + throw new Error('Unknown text editor'); + } + const viewColumn = TypeConverters.ViewColumn.to(data[id]); if (textEditor.viewColumn !== viewColumn) { textEditor._acceptViewColumn(viewColumn); this._onDidChangeTextEditorViewColumn.fire({ textEditor, viewColumn }); From 8f3cda12e475c810f77c737b590b67b1c7546f1b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 14:49:10 -0800 Subject: [PATCH 260/290] Strict null check extHostFileSystem --- .../workbench/api/node/extHostFileSystem.ts | 82 +++++++++++-------- .../api/node/extHostLanguageFeatures.ts | 4 +- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 20f4f98a453..29cf43d41a3 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -20,7 +20,7 @@ import { CharCode } from 'vs/base/common/charCode'; class FsLinkProvider { private _schemes: string[] = []; - private _stateMachine: StateMachine; + private _stateMachine?: StateMachine; add(scheme: string): void { this._stateMachine = undefined; @@ -190,6 +190,8 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { case FileChangeType.Deleted: newType = files.FileChangeType.DELETED; break; + default: + throw new Error('Unknown FileChangeType'); } mapped.push({ resource, type: newType }); } @@ -219,60 +221,46 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { return { type, ctime, mtime, size }; } - private _checkProviderExists(handle: number): void { - if (!this._fsProvider.has(handle)) { - const err = new Error(); - err.name = 'ENOPRO'; - err.message = `no provider`; - throw err; - } - } - $stat(handle: number, resource: UriComponents): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat); + return Promise.resolve(this.getProvider(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat); } $readdir(handle: number, resource: UriComponents): Promise<[string, files.FileType][]> { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).readDirectory(URI.revive(resource))); + return Promise.resolve(this.getProvider(handle).readDirectory(URI.revive(resource))); } $readFile(handle: number, resource: UriComponents): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).readFile(URI.revive(resource))).then(data => { + return Promise.resolve(this.getProvider(handle).readFile(URI.revive(resource))).then(data => { return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength); }); } $writeFile(handle: number, resource: UriComponents, content: Buffer, opts: files.FileWriteOptions): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).writeFile(URI.revive(resource), content, opts)); + return Promise.resolve(this.getProvider(handle).writeFile(URI.revive(resource), content, opts)); } $delete(handle: number, resource: UriComponents, opts: files.FileDeleteOptions): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).delete(URI.revive(resource), opts)); + return Promise.resolve(this.getProvider(handle).delete(URI.revive(resource), opts)); } $rename(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts)); + return Promise.resolve(this.getProvider(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts)); } $copy(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).copy(URI.revive(oldUri), URI.revive(newUri), opts)); + const provider = this.getProvider(handle); + if (!provider.copy) { + throw new Error('FileSystemProvider does not implement "copy"'); + } + return Promise.resolve(provider.copy(URI.revive(oldUri), URI.revive(newUri), opts)); } $mkdir(handle: number, resource: UriComponents): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).createDirectory(URI.revive(resource))); + return Promise.resolve(this.getProvider(handle).createDirectory(URI.revive(resource))); } $watch(handle: number, session: number, resource: UriComponents, opts: files.IWatchOptions): void { - this._checkProviderExists(handle); - let subscription = this._fsProvider.get(handle).watch(URI.revive(resource), opts); + let subscription = this.getProvider(handle).watch(URI.revive(resource), opts); this._watches.set(session, subscription); } @@ -285,26 +273,48 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $open(handle: number, resource: UriComponents, opts: files.FileOpenOptions): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).open(URI.revive(resource), opts)); + const provider = this.getProvider(handle); + if (!provider.open) { + throw new Error('FileSystemProvider does not implement "open"'); + } + return Promise.resolve(provider.open(URI.revive(resource), opts)); } $close(handle: number, fd: number): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).close(fd)); + const provider = this.getProvider(handle); + if (!provider.close) { + throw new Error('FileSystemProvider does not implement "close"'); + } + return Promise.resolve(provider.close(fd)); } $read(handle: number, fd: number, pos: number, length: number): Promise { - this._checkProviderExists(handle); + const provider = this.getProvider(handle); + if (!provider.read) { + throw new Error('FileSystemProvider does not implement "read"'); + } const data = Buffer.allocUnsafe(length); - return Promise.resolve(this._fsProvider.get(handle).read(fd, pos, data, 0, length)).then(read => { + return Promise.resolve(provider.read(fd, pos, data, 0, length)).then(read => { return data.slice(0, read); // don't send zeros }); } $write(handle: number, fd: number, pos: number, data: Buffer): Promise { - this._checkProviderExists(handle); - return Promise.resolve(this._fsProvider.get(handle).write(fd, pos, data, 0, data.length)); + const provider = this.getProvider(handle); + if (!provider.write) { + throw new Error('FileSystemProvider does not implement "write"'); + } + return Promise.resolve(provider.write(fd, pos, data, 0, data.length)); } + private getProvider(handle: number): vscode.FileSystemProvider { + const provider = this._fsProvider.get(handle); + if (!provider) { + const err = new Error(); + err.name = 'ENOPRO'; + err.message = `no provider`; + throw err; + } + return provider; + } } diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index b4b5d85a067..54f34709fa2 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -1081,7 +1081,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return Promise.reject(new Error('no adapter found')); } - private _addNewAdapter(adapter: Adapter, extension: IExtensionDescription): number { + private _addNewAdapter(adapter: Adapter, extension: IExtensionDescription | undefined): number { const handle = this._nextHandle(); this._adapter.set(handle, new AdapterData(adapter, extension)); return handle; @@ -1358,7 +1358,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { // --- links - registerDocumentLinkProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { + registerDocumentLinkProvider(extension: IExtensionDescription | undefined, selector: vscode.DocumentSelector, provider: vscode.DocumentLinkProvider): vscode.Disposable { const handle = this._addNewAdapter(new LinkProviderAdapter(this._documents, this._heapService, provider), extension); this._proxy.$registerDocumentLinkProvider(handle, this._transformDocumentSelector(selector)); return this._createDisposable(handle); From 14c4fde6d60ef0a0f312ebb6c313a18aee39183a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 15:02:38 -0800 Subject: [PATCH 261/290] Strict null check extHostQuickOpen --- src/tsconfig.strictNullChecks.json | 1 + .../electron-browser/mainThreadQuickOpen.ts | 2 +- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- .../api/node/extHostExtensionService.ts | 3 +++ src/vs/workbench/api/node/extHostQuickOpen.ts | 24 +++++++++++++------ 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index c8f807a4283..2ea5f975449 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -95,6 +95,7 @@ "./vs/workbench/api/node/extHostMessageService.ts", "./vs/workbench/api/node/extHostOutputService.ts", "./vs/workbench/api/node/extHostProgress.ts", + "./vs/workbench/api/node/extHostQuickOpen.ts", "./vs/workbench/api/node/extHostSearch.fileIndex.ts", "./vs/workbench/api/node/extHostSearch.ts", "./vs/workbench/api/node/extHostStorage.ts", diff --git a/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts b/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts index ab2865d0b32..b9781894eb4 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts @@ -85,7 +85,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape { // ---- input - $input(options: InputBoxOptions, validateInput: boolean, token: CancellationToken): Promise { + $input(options: InputBoxOptions | undefined, validateInput: boolean, token: CancellationToken): Promise { const inputOptions: IInputOptions = Object.create(null); if (options) { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 07a015c08d7..d1568c067e9 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -460,7 +460,7 @@ export interface MainThreadQuickOpenShape extends IDisposable { $show(instance: number, options: IPickOptions, token: CancellationToken): Promise; $setItems(instance: number, items: TransferQuickPickItems[]): Promise; $setError(instance: number, error: Error): Promise; - $input(options: vscode.InputBoxOptions, validateInput: boolean, token: CancellationToken): Promise; + $input(options: vscode.InputBoxOptions | undefined, validateInput: boolean, token: CancellationToken): Promise; $createOrUpdate(params: TransferQuickInput): Promise; $dispose(id: number): Promise; } diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 58ba2e568ef..9eae6df41cf 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -116,6 +116,9 @@ class ExtensionStoragePath { return Promise.resolve(undefined); } + if (!this._environment.appSettingsHome) { + return undefined; + } const storageName = this._workspace.id; const storagePath = path.join(this._environment.appSettingsHome.fsPath, 'workspaceStorage', storageName); diff --git a/src/vs/workbench/api/node/extHostQuickOpen.ts b/src/vs/workbench/api/node/extHostQuickOpen.ts index 7b8dd2432ee..1a8fbce1a76 100644 --- a/src/vs/workbench/api/node/extHostQuickOpen.ts +++ b/src/vs/workbench/api/node/extHostQuickOpen.ts @@ -15,6 +15,7 @@ import { URI } from 'vs/base/common/uri'; import { ThemeIcon, QuickInputButtons } from 'vs/workbench/api/node/extHostTypes'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { coalesce } from 'vs/base/common/arrays'; export type Item = string | QuickPickItem; @@ -24,7 +25,7 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape { private _workspace: IExtHostWorkspaceProvider; private _commands: ExtHostCommands; - private _onDidSelectItem: (handle: number) => void; + private _onDidSelectItem?: (handle: number) => void; private _validateInput?: (input: string) => string | undefined | null | Thenable; private _sessions = new Map(); @@ -158,12 +159,15 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape { // ---- workspace folder picker - showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions, token = CancellationToken.None): Promise { + showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions, token = CancellationToken.None): Promise { return this._commands.executeCommand('_workbench.pickWorkspaceFolder', [options]).then(async (selectedFolder: WorkspaceFolder) => { if (!selectedFolder) { return undefined; } const workspaceFolders = await this._workspace.getWorkspaceFolders2(); + if (!workspaceFolders) { + return undefined; + } return workspaceFolders.filter(folder => folder.uri.toString() === selectedFolder.uri.toString())[0]; }); } @@ -382,7 +386,9 @@ class ExtHostQuickInput implements QuickInput { _fireDidTriggerButton(handle: number) { const button = this._handlesToButtons.get(handle); - this._onDidTriggerButtonEmitter.fire(button); + if (button) { + this._onDidTriggerButtonEmitter.fire(button); + } } _fireDidHide() { @@ -437,9 +443,13 @@ class ExtHostQuickInput implements QuickInput { } } -function getIconUris(iconPath: QuickInputButton['iconPath']) { +function getIconUris(iconPath: QuickInputButton['iconPath']): { dark: URI, light?: URI } | undefined { + const dark = getDarkIconUri(iconPath); const light = getLightIconUri(iconPath); - return { dark: getDarkIconUri(iconPath) || light, light }; + if (!light && !dark) { + return undefined; + } + return { dark: (dark || light)!, light }; } function getLightIconUri(iconPath: QuickInputButton['iconPath']) { @@ -563,13 +573,13 @@ class ExtHostQuickPick extends ExtHostQuickInput implem onDidChangeSelection = this._onDidChangeSelectionEmitter.event; _fireDidChangeActive(handles: number[]) { - const items = handles.map(handle => this._handlesToItems.get(handle)); + const items = coalesce(handles.map(handle => this._handlesToItems.get(handle))); this._activeItems = items; this._onDidChangeActiveEmitter.fire(items); } _fireDidChangeSelection(handles: number[]) { - const items = handles.map(handle => this._handlesToItems.get(handle)); + const items = coalesce(handles.map(handle => this._handlesToItems.get(handle))); this._selectedItems = items; this._onDidChangeSelectionEmitter.fire(items); } From db9a994ded51e3b2e2e15a128cc8dd61fb158171 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 15:08:30 -0800 Subject: [PATCH 262/290] Strict null check extHostDiagnostics --- src/tsconfig.strictNullChecks.json | 1 + src/vs/workbench/api/node/extHost.protocol.ts | 2 +- .../workbench/api/node/extHostDiagnostics.ts | 20 ++++++++++++------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 2ea5f975449..21cb5fb6cae 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -81,6 +81,7 @@ "./vs/workbench/api/node/extHostCommands.ts", "./vs/workbench/api/node/extHostConfiguration.ts", "./vs/workbench/api/node/extHostDecorations.ts", + "./vs/workbench/api/node/extHostDiagnostics.ts", "./vs/workbench/api/node/extHostDialogs.ts", "./vs/workbench/api/node/extHostDocumentContentProviders.ts", "./vs/workbench/api/node/extHostDocumentData.ts", diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index d1568c067e9..e7cb2b72c07 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -142,7 +142,7 @@ export interface MainThreadConfigurationShape extends IDisposable { } export interface MainThreadDiagnosticsShape extends IDisposable { - $changeMany(owner: string, entries: [UriComponents, IMarkerData[]][]): void; + $changeMany(owner: string, entries: [UriComponents, IMarkerData[] | undefined][]): void; $clear(owner: string): void; } diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index e88ae6266c9..fe511a50994 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -37,7 +37,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { if (!this._isDisposed) { this._onDidChangeDiagnostics.fire(keys(this._data)); this._proxy.$clear(this._owner); - this._data = undefined; + this._data = undefined!; this._isDisposed = true; } } @@ -85,7 +85,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { for (const tuple of first) { const [uri, diagnostics] = tuple; if (!lastUri || uri.toString() !== lastUri.toString()) { - if (lastUri && this._data.get(lastUri.toString()).length === 0) { + if (lastUri && this._data.get(lastUri.toString())!.length === 0) { this._data.delete(lastUri.toString()); } lastUri = uri; @@ -95,9 +95,15 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { if (!diagnostics) { // [Uri, undefined] means clear this - this._data.get(uri.toString()).length = 0; + const currentDiagnostics = this._data.get(uri.toString()); + if (currentDiagnostics) { + currentDiagnostics.length = 0; + } } else { - this._data.get(uri.toString()).push(...diagnostics); + const currentDiagnostics = this._data.get(uri.toString()); + if (currentDiagnostics) { + currentDiagnostics.push(...diagnostics); + } } } } @@ -108,7 +114,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { // compute change and send to main side const entries: [URI, IMarkerData[]][] = []; for (let uri of toSync) { - let marker: IMarkerData[] | undefined; + let marker: IMarkerData[] = []; let diagnostics = this._data.get(uri.toString()); if (diagnostics) { @@ -137,7 +143,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { endColumn: marker[marker.length - 1].endColumn }); } else { - marker = diagnostics.map(converter.Diagnostic.from); + marker = diagnostics.map(diag => converter.Diagnostic.from(diag)); } } @@ -175,7 +181,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { if (Array.isArray(result)) { return Object.freeze(result.slice(0)); } - return undefined; + return []; } has(uri: URI): boolean { From ff1d530157d2db44993269c15ac6ab603fc05fa3 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 15:28:08 -0800 Subject: [PATCH 263/290] Strict null work in files/browser --- .../contrib/files/browser/fileActions.ts | 27 ++++++++++++++++--- .../contrib/files/browser/fileCommands.ts | 14 +++++----- .../contrib/files/browser/saveErrorHandler.ts | 4 +-- .../services/editor/common/editorService.ts | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 92f15346a27..c8f8f3e9d7b 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -832,7 +832,7 @@ export class ShowActiveFileInExplorer extends Action { } public run(): Promise { - const resource = toResource(this.editorService.activeEditor, { supportSideBySide: true }); + const resource = toResource(this.editorService.activeEditor || null, { supportSideBySide: true }); if (resource) { this.commandService.executeCommand(REVEAL_IN_EXPLORER_COMMAND_ID, resource); } else { @@ -904,7 +904,7 @@ export class ShowOpenedFileInNewWindow extends Action { } public run(): Promise { - const fileResource = toResource(this.editorService.activeEditor, { supportSideBySide: true }); + const fileResource = toResource(this.editorService.activeEditor || null, { supportSideBySide: true }); if (fileResource) { if (this.fileService.canHandleResource(fileResource)) { this.windowService.openWindow([{ uri: fileResource, typeHint: 'file' }], { forceNewWindow: true, forceOpenWorkspaceAsFile: true }); @@ -1007,7 +1007,7 @@ export class CompareWithClipboardAction extends Action { } public run(): Promise { - const resource = toResource(this.editorService.activeEditor, { supportSideBySide: true }); + const resource = toResource(this.editorService.activeEditor || null, { supportSideBySide: true }); if (resource && (this.fileService.canHandleResource(resource) || resource.scheme === Schemas.untitled)) { if (!this.registrationDisposal) { const provider = this.instantiationService.createInstance(ClipboardContentProvider); @@ -1076,7 +1076,7 @@ function openExplorerAndRunAction(accessor: ServicesAccessor, constructor: ICons return explorerPromise.then((explorer: ExplorerViewlet) => { const explorerView = explorer.getExplorerView(); - if (explorerView && explorerView.isBodyVisible()) { + if (explorerView && explorerView.isBodyVisible() && listService.lastFocusedList) { explorerView.focus(); const { stat } = getContext(listService.lastFocusedList); const action = instantationService.createInstance(constructor, () => stat); @@ -1106,6 +1106,10 @@ export const renameHandler = (accessor: ServicesAccessor) => { const listService = accessor.get(IListService); const explorerService = accessor.get(IExplorerService); const textFileService = accessor.get(ITextFileService); + if (!listService.lastFocusedList) { + return; + } + const { stat } = getContext(listService.lastFocusedList); explorerService.setEditable(stat, { @@ -1124,6 +1128,9 @@ export const renameHandler = (accessor: ServicesAccessor) => { export const moveFileToTrashHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); + if (!listService.lastFocusedList) { + return Promise.resolve(); + } const explorerContext = getContext(listService.lastFocusedList); const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; @@ -1134,6 +1141,9 @@ export const moveFileToTrashHandler = (accessor: ServicesAccessor) => { export const deleteFileHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); + if (!listService.lastFocusedList) { + return Promise.resolve(); + } const explorerContext = getContext(listService.lastFocusedList); const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; @@ -1143,6 +1153,9 @@ export const deleteFileHandler = (accessor: ServicesAccessor) => { export const copyFileHandler = (accessor: ServicesAccessor) => { const listService = accessor.get(IListService); + if (!listService.lastFocusedList) { + return; + } const explorerContext = getContext(listService.lastFocusedList); const explorerService = accessor.get(IExplorerService); const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; @@ -1152,6 +1165,9 @@ export const copyFileHandler = (accessor: ServicesAccessor) => { export const cutFileHandler = (accessor: ServicesAccessor) => { const listService = accessor.get(IListService); + if (!listService.lastFocusedList) { + return; + } const explorerContext = getContext(listService.lastFocusedList); const explorerService = accessor.get(IExplorerService); const stats = explorerContext.selection.length > 1 ? explorerContext.selection : [explorerContext.stat]; @@ -1163,6 +1179,9 @@ export const pasteFileHandler = (accessor: ServicesAccessor) => { const instantationService = accessor.get(IInstantiationService); const listService = accessor.get(IListService); const clipboardService = accessor.get(IClipboardService); + if (!listService.lastFocusedList) { + return Promise.resolve(); + } const explorerContext = getContext(listService.lastFocusedList); return sequence(resources.distinctParents(clipboardService.readResources(), r => r).map(toCopy => { diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index 136bbc9d387..d5483f119d8 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -111,7 +111,7 @@ function save( // Save As (or Save untitled with associated path) if (isSaveAs || resource.scheme === Schemas.untitled) { - let encodingOfSource: string; + let encodingOfSource: string | undefined; if (resource.scheme === Schemas.untitled) { encodingOfSource = untitledEditorService.getEncoding(resource); } else if (fileService.canHandleResource(resource)) { @@ -119,17 +119,17 @@ function save( encodingOfSource = textModel && textModel.getEncoding(); // text model can be null e.g. if this is a binary file! } - let viewStateOfSource: IEditorViewState; + let viewStateOfSource: IEditorViewState | null; const activeTextEditorWidget = getCodeEditor(editorService.activeTextEditorWidget); if (activeTextEditorWidget) { - const activeResource = toResource(editorService.activeEditor, { supportSideBySide: true }); + const activeResource = toResource(editorService.activeEditor || null, { supportSideBySide: true }); if (activeResource && (fileService.canHandleResource(activeResource) || resource.scheme === Schemas.untitled) && activeResource.toString() === resource.toString()) { viewStateOfSource = activeTextEditorWidget.saveViewState(); } } // Special case: an untitled file with associated path gets saved directly unless "saveAs" is true - let savePromise: Promise; + let savePromise: Promise; if (!isSaveAs && resource.scheme === Schemas.untitled && untitledEditorService.hasAssociatedFilePath(resource)) { savePromise = textFileService.save(resource, options).then((result) => { if (result) { @@ -152,7 +152,7 @@ function save( return savePromise.then((target) => { if (!target || target.toString() === resource.toString()) { - return undefined; // save canceled or same resource used + return false; // save canceled or same resource used } const replacement: IResourceInput = { @@ -175,7 +175,7 @@ function save( // Pin the active editor if we are saving it const activeControl = editorService.activeControl; const activeEditorResource = activeControl && activeControl.input && activeControl.input.getResource(); - if (activeEditorResource && activeEditorResource.toString() === resource.toString()) { + if (activeControl && activeEditorResource && activeEditorResource.toString() === resource.toString()) { activeControl.group.pinEditor(activeControl.input); } @@ -203,7 +203,7 @@ function saveAll(saveAllArguments: any, editorService: IEditorService, untitledE groupIdToUntitledResourceInput.set(g.id, []); } - groupIdToUntitledResourceInput.get(g.id).push({ + groupIdToUntitledResourceInput.get(g.id)!.push({ encoding: untitledEditorService.getEncoding(resource), resource, options: { diff --git a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts index c3861633546..2da2752ef21 100644 --- a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts +++ b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts @@ -9,7 +9,7 @@ import { basename } from 'vs/base/common/resources'; import { Action } from 'vs/base/common/actions'; import { URI } from 'vs/base/common/uri'; import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files'; -import { ITextFileService, ISaveErrorHandler, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, ISaveErrorHandler, ITextFileEditorModel, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -321,7 +321,7 @@ export const acceptLocalChangesCommand = (accessor: ServicesAccessor, resource: const group = control.group; resolverService.createModelReference(resource).then(reference => { - const model = reference.object as ITextFileEditorModel; + const model = reference.object as IResolvedTextFileEditorModel; const localModelSnapshot = model.createSnapshot(); clearPendingResolveSaveConflictMessages(); // hide any previously shown message about how to use these actions diff --git a/src/vs/workbench/services/editor/common/editorService.ts b/src/vs/workbench/services/editor/common/editorService.ts index a0f2e0006a1..e9b88ee2c46 100644 --- a/src/vs/workbench/services/editor/common/editorService.ts +++ b/src/vs/workbench/services/editor/common/editorService.ts @@ -36,7 +36,7 @@ export interface IOpenEditorOverride { * If defined, will prevent the opening of an editor and replace the resulting * promise with the provided promise for the openEditor() call. */ - override?: Promise; + override?: Promise; } export interface IActiveEditor extends IEditor { From aef80e8070182c81cacf01a68eaff1731fb67b30 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 16:07:58 -0800 Subject: [PATCH 264/290] Auto marking fields as readonly in mainThread files --- .../electron-browser/mainThreadComments.ts | 22 ++++++++-------- .../mainThreadDebugService.ts | 14 +++++----- .../electron-browser/mainThreadDecorations.ts | 2 +- .../electron-browser/mainThreadDocuments.ts | 18 ++++++------- .../mainThreadDocumentsAndEditors.ts | 4 +-- .../api/electron-browser/mainThreadEditor.ts | 6 ++--- .../api/electron-browser/mainThreadEditors.ts | 6 ++--- .../electron-browser/mainThreadHeapService.ts | 2 +- .../mainThreadLanguageFeatures.ts | 8 +++--- .../mainThreadOutputService.ts | 2 +- .../electron-browser/mainThreadProgress.ts | 4 +-- .../electron-browser/mainThreadQuickOpen.ts | 6 ++--- .../api/electron-browser/mainThreadSCM.ts | 26 +++++++++---------- .../mainThreadSaveParticipant.ts | 2 +- .../api/electron-browser/mainThreadStorage.ts | 8 +++--- .../api/electron-browser/mainThreadTask.ts | 6 ++--- .../electron-browser/mainThreadTreeViews.ts | 12 ++++----- 17 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadComments.ts b/src/vs/workbench/api/electron-browser/mainThreadComments.ts index ebbe7023a9a..0c50eeb40ea 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadComments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadComments.ts @@ -26,9 +26,9 @@ import { IRange } from 'vs/editor/common/core/range'; import { Emitter, Event } from 'vs/base/common/event'; export class MainThreadDocumentCommentProvider implements modes.DocumentCommentProvider { - private _proxy: ExtHostCommentsShape; - private _handle: number; - private _features: CommentProviderFeatures; + private readonly _proxy: ExtHostCommentsShape; + private readonly _handle: number; + private readonly _features: CommentProviderFeatures; get startDraftLabel(): string | undefined { return this._features.startDraftLabel; } get deleteDraftLabel(): string | undefined { return this._features.deleteDraftLabel; } get finishDraftLabel(): string | undefined { return this._features.finishDraftLabel; } @@ -197,14 +197,14 @@ export class MainThreadCommentControl { return this._label; } - private _threads: Map = new Map(); - private _commentingRanges: Map = new Map(); + private readonly _threads: Map = new Map(); + private readonly _commentingRanges: Map = new Map(); constructor( - private _proxy: ExtHostCommentsShape, - private _commentService: ICommentService, - private _handle: number, - private _id: string, - private _label: string + private readonly _proxy: ExtHostCommentsShape, + private readonly _commentService: ICommentService, + private readonly _handle: number, + private readonly _id: string, + private readonly _label: string ) { } createCommentThread(commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, comments: modes.Comment[], commands: modes.Command[], collapseState: modes.CommentThreadCollapsibleState): modes.CommentThread2 { @@ -331,7 +331,7 @@ export class MainThreadCommentControl { export class MainThreadComments extends Disposable implements MainThreadCommentsShape { private _disposables: IDisposable[]; private _activeCommentThreadDisposables: IDisposable[]; - private _proxy: ExtHostCommentsShape; + private readonly _proxy: ExtHostCommentsShape; private _documentProviders = new Map(); private _workspaceProviders = new Map(); private _handlers = new Map(); diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index 395c6b87b0e..fe7631d0a0e 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -19,15 +19,15 @@ import { convertToVSCPaths, convertToDAPaths } from 'vs/workbench/contrib/debug/ @extHostNamedCustomer(MainContext.MainThreadDebugService) export class MainThreadDebugService implements MainThreadDebugServiceShape, IDebugAdapterFactory { - private _proxy: ExtHostDebugServiceShape; + private readonly _proxy: ExtHostDebugServiceShape; private _toDispose: IDisposable[]; private _breakpointEventsActive: boolean; - private _debugAdapters: Map; + private readonly _debugAdapters: Map; private _debugAdaptersHandleCounter = 1; - private _debugConfigurationProviders: Map; - private _debugAdapterDescriptorFactories: Map; - private _debugAdapterTrackerFactories: Map; - private _sessions: Set; + private readonly _debugConfigurationProviders: Map; + private readonly _debugAdapterDescriptorFactories: Map; + private readonly _debugAdapterTrackerFactories: Map; + private readonly _sessions: Set; constructor( extHostContext: IExtHostContext, @@ -343,7 +343,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb */ class ExtensionHostDebugAdapter extends AbstractDebugAdapter { - constructor(private _ds: MainThreadDebugService, private _handle: number, private _proxy: ExtHostDebugServiceShape, private _session: IDebugSession) { + constructor(private readonly _ds: MainThreadDebugService, private _handle: number, private _proxy: ExtHostDebugServiceShape, private _session: IDebugSession) { super(); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadDecorations.ts b/src/vs/workbench/api/electron-browser/mainThreadDecorations.ts index 8847d97283a..84281c3a6c2 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDecorations.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDecorations.ts @@ -21,7 +21,7 @@ class DecorationRequestsQueue { private _timer: any; constructor( - private _proxy: ExtHostDecorationsShape + private readonly _proxy: ExtHostDecorationsShape ) { // } diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts index 7780708d837..ac7e79434ed 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts @@ -24,8 +24,8 @@ export class BoundModelReferenceCollection { private _length = 0; constructor( - private _maxAge: number = 1000 * 60 * 3, - private _maxLength: number = 1024 * 1024 * 80 + private readonly _maxAge: number = 1000 * 60 * 3, + private readonly _maxLength: number = 1024 * 1024 * 80 ) { // } @@ -64,16 +64,16 @@ export class BoundModelReferenceCollection { export class MainThreadDocuments implements MainThreadDocumentsShape { - private _modelService: IModelService; - private _textModelResolverService: ITextModelService; - private _textFileService: ITextFileService; - private _fileService: IFileService; - private _untitledEditorService: IUntitledEditorService; + private readonly _modelService: IModelService; + private readonly _textModelResolverService: ITextModelService; + private readonly _textFileService: ITextFileService; + private readonly _fileService: IFileService; + private readonly _untitledEditorService: IUntitledEditorService; private _toDispose: IDisposable[]; private _modelToDisposeMap: { [modelUrl: string]: IDisposable; }; - private _proxy: ExtHostDocumentsShape; - private _modelIsSynced: { [modelId: string]: boolean; }; + private readonly _proxy: ExtHostDocumentsShape; + private readonly _modelIsSynced: { [modelId: string]: boolean; }; private _modelReferenceCollection = new BoundModelReferenceCollection(); constructor( diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts index dd73c36be3f..eef961784b7 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts @@ -304,8 +304,8 @@ class MainThreadDocumentAndEditorStateComputer { export class MainThreadDocumentsAndEditors { private _toDispose: IDisposable[]; - private _proxy: ExtHostDocumentsAndEditorsShape; - private _stateComputer: MainThreadDocumentAndEditorStateComputer; + private readonly _proxy: ExtHostDocumentsAndEditorsShape; + private readonly _stateComputer: MainThreadDocumentAndEditorStateComputer; private _textEditors = <{ [id: string]: MainThreadTextEditor }>Object.create(null); private _onTextEditorAdd = new Emitter(); diff --git a/src/vs/workbench/api/electron-browser/mainThreadEditor.ts b/src/vs/workbench/api/electron-browser/mainThreadEditor.ts index 30639a78a94..7e221b1b5da 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadEditor.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadEditor.ts @@ -181,12 +181,12 @@ export class MainThreadTextEditorProperties { */ export class MainThreadTextEditor { - private _id: string; + private readonly _id: string; private _model: ITextModel; - private _modelService: IModelService; + private readonly _modelService: IModelService; private _modelListeners: IDisposable[]; private _codeEditor: ICodeEditor | null; - private _focusTracker: IFocusTracker; + private readonly _focusTracker: IFocusTracker; private _codeEditorListeners: IDisposable[]; private _properties: MainThreadTextEditorProperties; diff --git a/src/vs/workbench/api/electron-browser/mainThreadEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadEditors.ts index bd1a7845c05..6e49573d76e 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadEditors.ts @@ -31,9 +31,9 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { private static INSTANCE_COUNT: number = 0; - private _instanceId: string; - private _proxy: ExtHostEditorsShape; - private _documentsAndEditors: MainThreadDocumentsAndEditors; + private readonly _instanceId: string; + private readonly _proxy: ExtHostEditorsShape; + private readonly _documentsAndEditors: MainThreadDocumentsAndEditors; private _toDispose: IDisposable[]; private _textEditorsListenersMap: { [editorId: string]: IDisposable[]; }; private _editorPositionData: ITextEditorPositionData | null; diff --git a/src/vs/workbench/api/electron-browser/mainThreadHeapService.ts b/src/vs/workbench/api/electron-browser/mainThreadHeapService.ts index 1b5d15ee21c..486a290b705 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadHeapService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadHeapService.ts @@ -96,7 +96,7 @@ export class HeapService implements IHeapService { @extHostCustomer export class MainThreadHeapService { - private _toDispose: IDisposable; + private readonly _toDispose: IDisposable; constructor( extHostContext: IExtHostContext, diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts index 0be7720a10f..8abeedd7878 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts @@ -26,10 +26,10 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; @extHostNamedCustomer(MainContext.MainThreadLanguageFeatures) export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesShape { - private _proxy: ExtHostLanguageFeaturesShape; - private _heapService: IHeapService; - private _modeService: IModeService; - private _registrations: { [handle: number]: IDisposable; } = Object.create(null); + private readonly _proxy: ExtHostLanguageFeaturesShape; + private readonly _heapService: IHeapService; + private readonly _modeService: IModeService; + private readonly _registrations: { [handle: number]: IDisposable; } = Object.create(null); constructor( extHostContext: IExtHostContext, diff --git a/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts b/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts index 9665fd33072..7c0308b8bdb 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadOutputService.ts @@ -18,7 +18,7 @@ export class MainThreadOutputService extends Disposable implements MainThreadOut private static _idPool = 1; - private _proxy: ExtHostOutputServiceShape; + private readonly _proxy: ExtHostOutputServiceShape; private readonly _outputService: IOutputService; private readonly _partService: IPartService; private readonly _panelService: IPanelService; diff --git a/src/vs/workbench/api/electron-browser/mainThreadProgress.ts b/src/vs/workbench/api/electron-browser/mainThreadProgress.ts index 5521d8f3854..80944a23128 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadProgress.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadProgress.ts @@ -10,9 +10,9 @@ import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostC @extHostNamedCustomer(MainContext.MainThreadProgress) export class MainThreadProgress implements MainThreadProgressShape { - private _progressService: IProgressService2; + private readonly _progressService: IProgressService2; private _progress = new Map void, progress: IProgress }>(); - private _proxy: ExtHostProgressShape; + private readonly _proxy: ExtHostProgressShape; constructor( extHostContext: IExtHostContext, diff --git a/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts b/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts index b9781894eb4..976b27dc76d 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadQuickOpen.ts @@ -18,9 +18,9 @@ interface QuickInputSession { @extHostNamedCustomer(MainContext.MainThreadQuickOpen) export class MainThreadQuickOpen implements MainThreadQuickOpenShape { - private _proxy: ExtHostQuickOpenShape; - private _quickInputService: IQuickInputService; - private _items: Record = {}; diff --git a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts index 667110d3612..094700da329 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSCM.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSCM.ts @@ -27,8 +27,8 @@ class MainThreadSCMResourceGroup implements ISCMResourceGroup { get onDidChange(): Event { return this._onDidChange.event; } constructor( - private sourceControlHandle: number, - private handle: number, + private readonly sourceControlHandle: number, + private readonly handle: number, public provider: ISCMProvider, public features: SCMGroupFeatures, public label: string, @@ -62,10 +62,10 @@ class MainThreadSCMResourceGroup implements ISCMResourceGroup { class MainThreadSCMResource implements ISCMResource { constructor( - private proxy: ExtHostSCMShape, - private sourceControlHandle: number, - private groupHandle: number, - private handle: number, + private readonly proxy: ExtHostSCMShape, + private readonly sourceControlHandle: number, + private readonly groupHandle: number, + private readonly handle: number, public sourceUri: URI, public resourceGroup: ISCMResourceGroup, public decorations: ISCMResourceDecorations @@ -92,7 +92,7 @@ class MainThreadSCMProvider implements ISCMProvider { get id(): string { return this._id; } readonly groups = new Sequence(); - private _groupsByHandle: { [handle: number]: MainThreadSCMResourceGroup; } = Object.create(null); + private readonly _groupsByHandle: { [handle: number]: MainThreadSCMResourceGroup; } = Object.create(null); // get groups(): ISequence { // return { @@ -129,11 +129,11 @@ class MainThreadSCMProvider implements ISCMProvider { get onDidChange(): Event { return this._onDidChange.event; } constructor( - private proxy: ExtHostSCMShape, - private _handle: number, - private _contextValue: string, - private _label: string, - private _rootUri: URI | undefined, + private readonly proxy: ExtHostSCMShape, + private readonly _handle: number, + private readonly _contextValue: string, + private readonly _label: string, + private readonly _rootUri: URI | undefined, @ISCMService scmService: ISCMService ) { } @@ -265,7 +265,7 @@ class MainThreadSCMProvider implements ISCMProvider { @extHostNamedCustomer(MainContext.MainThreadSCM) export class MainThreadSCM implements MainThreadSCMShape { - private _proxy: ExtHostSCMShape; + private readonly _proxy: ExtHostSCMShape; private _repositories: { [handle: number]: ISCMRepository; } = Object.create(null); private _inputDisposables: { [handle: number]: IDisposable; } = Object.create(null); private _disposables: IDisposable[] = []; diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index 32c7b8403af..e098327460d 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -367,7 +367,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant { class ExtHostSaveParticipant implements ISaveParticipantParticipant { - private _proxy: ExtHostDocumentSaveParticipantShape; + private readonly _proxy: ExtHostDocumentSaveParticipantShape; constructor(extHostContext: IExtHostContext) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentSaveParticipant); diff --git a/src/vs/workbench/api/electron-browser/mainThreadStorage.ts b/src/vs/workbench/api/electron-browser/mainThreadStorage.ts index 96f63fbecba..455cdbcf11e 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadStorage.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadStorage.ts @@ -11,10 +11,10 @@ import { IDisposable } from 'vs/base/common/lifecycle'; @extHostNamedCustomer(MainContext.MainThreadStorage) export class MainThreadStorage implements MainThreadStorageShape { - private _storageService: IStorageService; - private _proxy: ExtHostStorageShape; - private _storageListener: IDisposable; - private _sharedStorageKeysToWatch: Map = new Map(); + private readonly _storageService: IStorageService; + private readonly _proxy: ExtHostStorageShape; + private readonly _storageListener: IDisposable; + private readonly _sharedStorageKeysToWatch: Map = new Map(); constructor( extHostContext: IExtHostContext, diff --git a/src/vs/workbench/api/electron-browser/mainThreadTask.ts b/src/vs/workbench/api/electron-browser/mainThreadTask.ts index 985a5df8556..a769f84ab75 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTask.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTask.ts @@ -382,9 +382,9 @@ namespace TaskFilterDTO { @extHostNamedCustomer(MainContext.MainThreadTask) export class MainThreadTask implements MainThreadTaskShape { - private _extHostContext: IExtHostContext; - private _proxy: ExtHostTaskShape; - private _providers: Map; + private readonly _extHostContext: IExtHostContext; + private readonly _proxy: ExtHostTaskShape; + private readonly _providers: Map; constructor( extHostContext: IExtHostContext, diff --git a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts index 2d6da3314f5..fe4995feb35 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts @@ -15,8 +15,8 @@ import { IMarkdownString } from 'vs/base/common/htmlContent'; @extHostNamedCustomer(MainContext.MainThreadTreeViews) export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape { - private _proxy: ExtHostTreeViewsShape; - private _dataProviders: Map = new Map(); + private readonly _proxy: ExtHostTreeViewsShape; + private readonly _dataProviders: Map = new Map(); constructor( extHostContext: IExtHostContext, @@ -133,11 +133,11 @@ type TreeItemHandle = string; class TreeViewDataProvider implements ITreeViewDataProvider { - private itemsMap: Map = new Map(); + private readonly itemsMap: Map = new Map(); - constructor(private treeViewId: string, - private _proxy: ExtHostTreeViewsShape, - private notificationService: INotificationService + constructor(private readonly treeViewId: string, + private readonly _proxy: ExtHostTreeViewsShape, + private readonly notificationService: INotificationService ) { } From 52556f97425ffbec3b8ba68de0ce8be70b5df167 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 16:25:26 -0800 Subject: [PATCH 265/290] Auto converting `let` -> `const` where possible in mainthread and extHost Const provides better type guards and can make logic clearer --- .../electron-browser/mainThreadCommands.ts | 2 +- .../electron-browser/mainThreadDocuments.ts | 12 ++-- .../mainThreadDocumentsAndEditors.ts | 8 +-- .../api/electron-browser/mainThreadEditor.ts | 12 ++-- .../api/electron-browser/mainThreadEditors.ts | 16 ++--- .../mainThreadFileSystemEventService.ts | 2 +- .../mainThreadLanguageFeatures.ts | 6 +- .../electron-browser/mainThreadLanguages.ts | 2 +- .../mainThreadMessageService.ts | 2 +- .../mainThreadSaveParticipant.ts | 4 +- .../electron-browser/mainThreadStatusBar.ts | 4 +- .../api/electron-browser/mainThreadStorage.ts | 4 +- .../api/electron-browser/mainThreadTask.ts | 62 +++++++++---------- src/vs/workbench/api/node/extHost.api.impl.ts | 8 +-- .../workbench/api/node/extHostApiCommands.ts | 6 +- src/vs/workbench/api/node/extHostCommands.ts | 2 +- src/vs/workbench/api/node/extHostComments.ts | 4 +- .../workbench/api/node/extHostDebugService.ts | 22 +++---- .../workbench/api/node/extHostDiagnostics.ts | 14 ++--- .../workbench/api/node/extHostDocumentData.ts | 18 +++--- .../node/extHostDocumentSaveParticipant.ts | 2 +- src/vs/workbench/api/node/extHostDocuments.ts | 2 +- .../api/node/extHostExtensionActivator.ts | 10 +-- .../api/node/extHostExtensionService.ts | 18 +++--- .../workbench/api/node/extHostFileSystem.ts | 10 +-- .../api/node/extHostFileSystemEventService.ts | 10 +-- .../api/node/extHostLanguageFeatures.ts | 38 ++++++------ .../api/node/extHostMessageService.ts | 4 +- src/vs/workbench/api/node/extHostQuickOpen.ts | 4 +- .../api/node/extHostSearch.fileIndex.ts | 6 +- src/vs/workbench/api/node/extHostStatusBar.ts | 4 +- src/vs/workbench/api/node/extHostTask.ts | 48 +++++++------- .../workbench/api/node/extHostTextEditor.ts | 34 +++++----- .../workbench/api/node/extHostTextEditors.ts | 2 +- src/vs/workbench/api/node/extHostTreeViews.ts | 8 +-- .../api/node/extHostTypeConverters.ts | 4 +- src/vs/workbench/api/node/extHostTypes.ts | 22 +++---- src/vs/workbench/api/node/extHostWorkspace.ts | 2 +- 38 files changed, 219 insertions(+), 219 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadCommands.ts b/src/vs/workbench/api/electron-browser/mainThreadCommands.ts index 061034039c1..4e8d426c589 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadCommands.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadCommands.ts @@ -89,7 +89,7 @@ function _generateMarkdown(description: string | ICommandHandlerDescription): st if (typeof description === 'string') { return description; } else { - let parts = [description.description]; + const parts = [description.description]; parts.push('\n\n'); if (description.args) { for (let arg of description.args) { diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts index ac7e79434ed..651d521c3a8 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts @@ -35,11 +35,11 @@ export class BoundModelReferenceCollection { } add(ref: IReference): void { - let length = ref.object.textEditorModel.getValueLength(); + const length = ref.object.textEditorModel.getValueLength(); let handle: any; let entry: { length: number, dispose(): void }; const dispose = () => { - let idx = this._data.indexOf(entry); + const idx = this._data.indexOf(entry); if (idx >= 0) { this._length -= length; ref.dispose(); @@ -139,7 +139,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { // don't synchronize too large models return; } - let modelUrl = model.uri; + const modelUrl = model.uri; this._modelIsSynced[modelUrl.toString()] = true; this._modelToDisposeMap[modelUrl.toString()] = model.onDidChangeContent((e) => { this._proxy.$acceptModelChanged(modelUrl, e, this._textFileService.isDirty(modelUrl)); @@ -148,7 +148,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { private _onModelModeChanged(event: { model: ITextModel; oldModeId: string; }): void { let { model, oldModeId } = event; - let modelUrl = model.uri; + const modelUrl = model.uri; if (!this._modelIsSynced[modelUrl.toString()]) { return; } @@ -156,7 +156,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { } private _onModelRemoved(modelUrl: URI): void { - let strModelUrl = modelUrl.toString(); + const strModelUrl = modelUrl.toString(); if (!this._modelIsSynced[strModelUrl]) { return; } @@ -214,7 +214,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { } private _handleUntitledScheme(uri: URI): Promise { - let asFileUri = uri.with({ scheme: Schemas.file }); + const asFileUri = uri.with({ scheme: Schemas.file }); return this._fileService.resolveFile(asFileUri).then(stats => { // don't create a new file ontop of an existing file return Promise.reject(new Error('file already exists on disk')); diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts index eef961784b7..18e432e32de 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts @@ -283,7 +283,7 @@ class MainThreadDocumentAndEditorStateComputer { } private _getActiveEditorFromPanel(): IEditor | undefined { - let panel = this._panelService.getActivePanel(); + const panel = this._panelService.getActivePanel(); if (panel instanceof BaseTextEditor && isCodeEditor(panel.getControl())) { return panel.getControl(); } else { @@ -362,8 +362,8 @@ export class MainThreadDocumentsAndEditors { private _onDelta(delta: DocumentAndEditorStateDelta): void { let removedDocuments: URI[]; - let removedEditors: string[] = []; - let addedEditors: MainThreadTextEditor[] = []; + const removedEditors: string[] = []; + const addedEditors: MainThreadTextEditor[] = []; // removed models removedDocuments = delta.removedDocuments.map(m => m.uri); @@ -387,7 +387,7 @@ export class MainThreadDocumentsAndEditors { } } - let extHostDelta: IDocumentsAndEditorsDelta = Object.create(null); + const extHostDelta: IDocumentsAndEditorsDelta = Object.create(null); let empty = true; if (delta.newActiveEditor !== undefined) { empty = false; diff --git a/src/vs/workbench/api/electron-browser/mainThreadEditor.ts b/src/vs/workbench/api/electron-browser/mainThreadEditor.ts index 7e221b1b5da..1ae5dcb8ee7 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadEditor.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadEditor.ts @@ -105,7 +105,7 @@ export class MainThreadTextEditorProperties { } public generateDelta(oldProps: MainThreadTextEditorProperties | null, selectionChangeSource: string | null): IEditorPropertiesChangeData | null { - let delta: IEditorPropertiesChangeData = { + const delta: IEditorPropertiesChangeData = { options: null, selections: null, visibleRanges: null @@ -323,7 +323,7 @@ export class MainThreadTextEditor { } private _setIndentConfiguration(newConfiguration: ITextEditorConfigurationUpdate): void { - let creationOpts = this._modelService.getCreationOptions(this._model.getLanguageIdentifier().language, this._model.uri, this._model.isForSimpleWidget); + const creationOpts = this._modelService.getCreationOptions(this._model.getLanguageIdentifier().language, this._model.uri, this._model.isForSimpleWidget); if (newConfiguration.tabSize === 'auto' || newConfiguration.insertSpaces === 'auto') { // one of the options was set to 'auto' => detect indentation @@ -342,7 +342,7 @@ export class MainThreadTextEditor { return; } - let newOpts: ITextModelUpdateOptions = {}; + const newOpts: ITextModelUpdateOptions = {}; if (typeof newConfiguration.insertSpaces !== 'undefined') { newOpts.insertSpaces = newConfiguration.insertSpaces; } @@ -367,7 +367,7 @@ export class MainThreadTextEditor { } if (newConfiguration.cursorStyle) { - let newCursorStyle = cursorStyleToString(newConfiguration.cursorStyle); + const newCursorStyle = cursorStyleToString(newConfiguration.cursorStyle); this._codeEditor.updateOptions({ cursorStyle: newCursorStyle }); @@ -402,7 +402,7 @@ export class MainThreadTextEditor { if (!this._codeEditor) { return; } - let ranges: Range[] = []; + const ranges: Range[] = []; for (let i = 0, len = Math.floor(_ranges.length / 4); i < len; i++) { ranges[i] = new Range(_ranges[4 * i], _ranges[4 * i + 1], _ranges[4 * i + 2], _ranges[4 * i + 3]); } @@ -464,7 +464,7 @@ export class MainThreadTextEditor { this._model.pushEOL(EndOfLineSequence.LF); } - let transformedEdits = edits.map((edit): IIdentifiedSingleEditOperation => { + const transformedEdits = edits.map((edit): IIdentifiedSingleEditOperation => { return { range: Range.lift(edit.range), text: edit.text, diff --git a/src/vs/workbench/api/electron-browser/mainThreadEditors.ts b/src/vs/workbench/api/electron-browser/mainThreadEditors.ts index 6e49573d76e..d1d7e1cd812 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadEditors.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadEditors.ts @@ -77,8 +77,8 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { } private _onTextEditorAdd(textEditor: MainThreadTextEditor): void { - let id = textEditor.getId(); - let toDispose: IDisposable[] = []; + const id = textEditor.getId(); + const toDispose: IDisposable[] = []; toDispose.push(textEditor.onPropertiesChanged((data) => { this._proxy.$acceptEditorPropertiesChanged(id, data); })); @@ -94,7 +94,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { private _updateActiveAndVisibleTextEditors(): void { // editor columns - let editorPositionData = this._getTextEditorPositionData(); + const editorPositionData = this._getTextEditorPositionData(); if (!objectEquals(this._editorPositionData, editorPositionData)) { this._editorPositionData = editorPositionData; this._proxy.$acceptEditorPositionData(this._editorPositionData); @@ -102,7 +102,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { } private _getTextEditorPositionData(): ITextEditorPositionData { - let result: ITextEditorPositionData = Object.create(null); + const result: ITextEditorPositionData = Object.create(null); for (let workbenchEditor of this._editorService.visibleControls) { const id = this._documentsAndEditors.findTextEditorIdFor(workbenchEditor); if (id) { @@ -137,9 +137,9 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { } $tryShowEditor(id: string, position?: EditorViewColumn): Promise { - let mainThreadEditor = this._documentsAndEditors.getEditor(id); + const mainThreadEditor = this._documentsAndEditors.getEditor(id); if (mainThreadEditor) { - let model = mainThreadEditor.getModel(); + const model = mainThreadEditor.getModel(); return this._editorService.openEditor({ resource: model.uri, options: { preserveFocus: false } @@ -149,9 +149,9 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape { } $tryHideEditor(id: string): Promise { - let mainThreadEditor = this._documentsAndEditors.getEditor(id); + const mainThreadEditor = this._documentsAndEditors.getEditor(id); if (mainThreadEditor) { - let editors = this._editorService.visibleControls; + const editors = this._editorService.visibleControls; for (let editor of editors) { if (mainThreadEditor.matches(editor)) { return editor.group.closeEditor(editor.input).then(() => { return; }); diff --git a/src/vs/workbench/api/electron-browser/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/electron-browser/mainThreadFileSystemEventService.ts index 1e9d568863e..351edd07f6d 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadFileSystemEventService.ts @@ -57,7 +57,7 @@ export class MainThreadFileSystemEventService { }, undefined, this._listener); textfileService.onWillMove(e => { - let promise = proxy.$onWillRename(e.oldResource, e.newResource); + const promise = proxy.$onWillRename(e.oldResource, e.newResource); e.waitUntil(promise); }, undefined, this._listener); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts index 8abeedd7878..3de39e6a654 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts @@ -48,7 +48,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha } $unregister(handle: number): void { - let registration = this._registrations[handle]; + const registration = this._registrations[handle]; if (registration) { registration.dispose(); delete this._registrations[handle]; @@ -506,7 +506,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha $setLanguageConfiguration(handle: number, languageId: string, _configuration: ISerializedLanguageConfiguration): void { - let configuration: LanguageConfiguration = { + const configuration: LanguageConfiguration = { comments: _configuration.comments, brackets: _configuration.brackets, wordPattern: MainThreadLanguageFeatures._reviveRegExp(_configuration.wordPattern), @@ -532,7 +532,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha }; } - let languageIdentifier = this._modeService.getLanguageIdentifier(languageId); + const languageIdentifier = this._modeService.getLanguageIdentifier(languageId); if (languageIdentifier) { this._registrations[handle] = LanguageConfigurationRegistry.register(languageIdentifier, configuration); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguages.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguages.ts index 88925d6bceb..392903a9e16 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguages.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguages.ts @@ -29,7 +29,7 @@ export class MainThreadLanguages implements MainThreadLanguagesShape { $changeLanguage(resource: UriComponents, languageId: string): Promise { const uri = URI.revive(resource); - let model = this._modelService.getModel(uri); + const model = this._modelService.getModel(uri); if (!model) { return Promise.reject(new Error('Invalid uri')); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadMessageService.ts b/src/vs/workbench/api/electron-browser/mainThreadMessageService.ts index 68cf1ff4c04..be0157d8b5f 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadMessageService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadMessageService.ts @@ -44,7 +44,7 @@ export class MainThreadMessageService implements MainThreadMessageServiceShape { return new Promise(resolve => { - let primaryActions: MessageItemAction[] = []; + const primaryActions: MessageItemAction[] = []; class MessageItemAction extends Action { constructor(id: string, label: string, handle: number) { diff --git a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts index e098327460d..fd647ecfe68 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts @@ -235,8 +235,8 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant { const timeout = this._configurationService.getValue('editor.formatOnSaveTimeout', { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() }); return new Promise((resolve, reject) => { - let source = new CancellationTokenSource(); - let request = getDocumentFormattingEdits(this._telemetryService, this._editorWorkerService, model, model.getFormattingOptions(), FormatMode.Auto, source.token); + const source = new CancellationTokenSource(); + const request = getDocumentFormattingEdits(this._telemetryService, this._editorWorkerService, model, model.getFormattingOptions(), FormatMode.Auto, source.token); setTimeout(() => { reject(localize('timeout.formatOnSave', "Aborted format on save after {0}ms", timeout)); diff --git a/src/vs/workbench/api/electron-browser/mainThreadStatusBar.ts b/src/vs/workbench/api/electron-browser/mainThreadStatusBar.ts index f002ffb6889..e6f2d2f3635 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadStatusBar.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadStatusBar.ts @@ -34,12 +34,12 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape { this.$dispose(id); // Add new - let entry = this._statusbarService.addEntry({ text, tooltip, command, color, extensionId }, alignment, priority); + const entry = this._statusbarService.addEntry({ text, tooltip, command, color, extensionId }, alignment, priority); this._entries[id] = entry; } $dispose(id: number) { - let disposeable = this._entries[id]; + const disposeable = this._entries[id]; if (disposeable) { disposeable.dispose(); } diff --git a/src/vs/workbench/api/electron-browser/mainThreadStorage.ts b/src/vs/workbench/api/electron-browser/mainThreadStorage.ts index 455cdbcf11e..04aae06d817 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadStorage.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadStorage.ts @@ -24,7 +24,7 @@ export class MainThreadStorage implements MainThreadStorageShape { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostStorage); this._storageListener = this._storageService.onDidChangeStorage(e => { - let shared = e.scope === StorageScope.GLOBAL; + const shared = e.scope === StorageScope.GLOBAL; if (shared && this._sharedStorageKeysToWatch.has(e.key)) { try { this._proxy.$acceptValue(shared, e.key, this._getValue(shared, e.key)); @@ -51,7 +51,7 @@ export class MainThreadStorage implements MainThreadStorageShape { } private _getValue(shared: boolean, key: string): T | undefined { - let jsonValue = this._storageService.get(key, shared ? StorageScope.GLOBAL : StorageScope.WORKSPACE); + const jsonValue = this._storageService.get(key, shared ? StorageScope.GLOBAL : StorageScope.WORKSPACE); if (!jsonValue) { return undefined; } diff --git a/src/vs/workbench/api/electron-browser/mainThreadTask.ts b/src/vs/workbench/api/electron-browser/mainThreadTask.ts index a769f84ab75..47bc0be5ea3 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTask.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTask.ts @@ -70,7 +70,7 @@ namespace TaskProcessEndedDTO { namespace TaskDefinitionDTO { export function from(value: KeyedTaskIdentifier): TaskDefinitionDTO { - let result = Objects.assign(Object.create(null), value); + const result = Objects.assign(Object.create(null), value); delete result._key; return result; } @@ -139,13 +139,13 @@ namespace ProcessExecutionOptionsDTO { namespace ProcessExecutionDTO { export function is(value: ShellExecutionDTO | ProcessExecutionDTO): value is ProcessExecutionDTO { - let candidate = value as ProcessExecutionDTO; + const candidate = value as ProcessExecutionDTO; return candidate && !!candidate.process; } export function from(value: CommandConfiguration): ProcessExecutionDTO { - let process: string = Types.isString(value.name) ? value.name : value.name.value; - let args: string[] = value.args ? value.args.map(value => Types.isString(value) ? value : value.value) : []; - let result: ProcessExecutionDTO = { + const process: string = Types.isString(value.name) ? value.name : value.name.value; + const args: string[] = value.args ? value.args.map(value => Types.isString(value) ? value : value.value) : []; + const result: ProcessExecutionDTO = { process: process, args: args }; @@ -155,7 +155,7 @@ namespace ProcessExecutionDTO { return result; } export function to(value: ProcessExecutionDTO): CommandConfiguration { - let result: CommandConfiguration = { + const result: CommandConfiguration = { runtime: RuntimeType.Process, name: value.process, args: value.args, @@ -171,7 +171,7 @@ namespace ShellExecutionOptionsDTO { if (value === undefined || value === null) { return undefined; } - let result: ShellExecutionOptionsDTO = { + const result: ShellExecutionOptionsDTO = { cwd: value.cwd || CommandOptions.defaults.cwd, env: value.env }; @@ -186,7 +186,7 @@ namespace ShellExecutionOptionsDTO { if (value === undefined || value === null) { return undefined; } - let result: CommandOptions = { + const result: CommandOptions = { cwd: value.cwd, env: value.env }; @@ -207,11 +207,11 @@ namespace ShellExecutionOptionsDTO { namespace ShellExecutionDTO { export function is(value: ShellExecutionDTO | ProcessExecutionDTO): value is ShellExecutionDTO { - let candidate = value as ShellExecutionDTO; + const candidate = value as ShellExecutionDTO; return candidate && (!!candidate.commandLine || !!candidate.command); } export function from(value: CommandConfiguration): ShellExecutionDTO { - let result: ShellExecutionDTO = {}; + const result: ShellExecutionDTO = {}; if (value.name && Types.isString(value.name) && (value.args === undefined || value.args === null || value.args.length === 0)) { result.commandLine = value.name; } else { @@ -224,7 +224,7 @@ namespace ShellExecutionDTO { return result; } export function to(value: ShellExecutionDTO): CommandConfiguration { - let result: CommandConfiguration = { + const result: CommandConfiguration = { runtime: RuntimeType.Shell, name: value.commandLine ? value.commandLine : value.command, args: value.args, @@ -239,7 +239,7 @@ namespace ShellExecutionDTO { namespace TaskSourceDTO { export function from(value: TaskSource): TaskSourceDTO { - let result: TaskSourceDTO = { + const result: TaskSourceDTO = { label: value.label }; if (value.kind === TaskSourceKind.Extension) { @@ -285,7 +285,7 @@ namespace TaskSourceDTO { namespace TaskHandleDTO { export function is(value: any): value is TaskHandleDTO { - let candidate: TaskHandleDTO = value; + const candidate: TaskHandleDTO = value; return candidate && Types.isString(candidate.id) && !!candidate.workspaceFolder; } } @@ -295,7 +295,7 @@ namespace TaskDTO { if (task === undefined || task === null || (!CustomTask.is(task) && !ContributedTask.is(task))) { return undefined; } - let result: TaskDTO = { + const result: TaskDTO = { _id: task._id, name: task.configurationProperties.name, definition: TaskDefinitionDTO.from(task.getDefinition()), @@ -344,12 +344,12 @@ namespace TaskDTO { return undefined; } command.presentation = TaskPresentationOptionsDTO.to(task.presentationOptions); - let source = TaskSourceDTO.to(task.source, workspace); + const source = TaskSourceDTO.to(task.source, workspace); - let label = nls.localize('task.label', '{0}: {1}', source.label, task.name); - let definition = TaskDefinitionDTO.to(task.definition, executeOnly); - let id = `${task.source.extensionId}.${definition._key}`; - let result: ContributedTask = new ContributedTask( + const label = nls.localize('task.label', '{0}: {1}', source.label, task.name); + const definition = TaskDefinitionDTO.to(task.definition, executeOnly); + const id = `${task.source.extensionId}.${definition._key}`; + const result: ContributedTask = new ContributedTask( id, // uuidMap.getUUID(identifier) source, label, @@ -416,12 +416,12 @@ export class MainThreadTask implements MainThreadTaskShape { } public $registerTaskProvider(handle: number): Promise { - let provider: ITaskProvider = { + const provider: ITaskProvider = { provideTasks: (validTypes: IStringDictionary) => { return Promise.resolve(this._proxy.$provideTasks(handle, validTypes)).then((value) => { - let tasks: Task[] = []; + const tasks: Task[] = []; for (let dto of value.tasks) { - let task = TaskDTO.to(dto, this._workspaceContextServer, true); + const task = TaskDTO.to(dto, this._workspaceContextServer, true); if (task) { tasks.push(task); } else { @@ -435,7 +435,7 @@ export class MainThreadTask implements MainThreadTaskShape { }); } }; - let disposable = this._taskService.registerTaskProvider(provider); + const disposable = this._taskService.registerTaskProvider(provider); this._providers.set(handle, { disposable, provider }); return Promise.resolve(undefined); } @@ -448,9 +448,9 @@ export class MainThreadTask implements MainThreadTaskShape { public $fetchTasks(filter?: TaskFilterDTO): Promise { return this._taskService.tasks(TaskFilterDTO.to(filter)).then((tasks) => { - let result: TaskDTO[] = []; + const result: TaskDTO[] = []; for (let task of tasks) { - let item = TaskDTO.from(task); + const item = TaskDTO.from(task); if (item) { result.push(item); } @@ -462,12 +462,12 @@ export class MainThreadTask implements MainThreadTaskShape { public $executeTask(value: TaskHandleDTO | TaskDTO): Promise { return new Promise((resolve, reject) => { if (TaskHandleDTO.is(value)) { - let workspaceFolder = this._workspaceContextServer.getWorkspaceFolder(URI.revive(value.workspaceFolder)); + const workspaceFolder = this._workspaceContextServer.getWorkspaceFolder(URI.revive(value.workspaceFolder)); this._taskService.getTask(workspaceFolder, value.id, true).then((task: Task) => { this._taskService.run(task).then(undefined, reason => { // eat the error, it has already been surfaced to the user and we don't care about it here }); - let result: TaskExecutionDTO = { + const result: TaskExecutionDTO = { id: value.id, task: TaskDTO.from(task) }; @@ -476,11 +476,11 @@ export class MainThreadTask implements MainThreadTaskShape { reject(new Error('Task not found')); }); } else { - let task = TaskDTO.to(value, this._workspaceContextServer, true); + const task = TaskDTO.to(value, this._workspaceContextServer, true); this._taskService.run(task).then(undefined, reason => { // eat the error, it has already been surfaced to the user and we don't care about it here }); - let result: TaskExecutionDTO = { + const result: TaskExecutionDTO = { id: task._id, task: TaskDTO.from(task) }; @@ -529,7 +529,7 @@ export class MainThreadTask implements MainThreadTaskShape { }, context: this._extHostContext, resolveVariables: (workspaceFolder: IWorkspaceFolder, toResolve: ResolveSet): Promise => { - let vars: string[] = []; + const vars: string[] = []; toResolve.variables.forEach(item => vars.push(item)); return Promise.resolve(this._proxy.$resolveVariables(workspaceFolder.uri, { process: toResolve.process, variables: vars })).then(values => { const partiallyResolvedVars = new Array(); @@ -538,7 +538,7 @@ export class MainThreadTask implements MainThreadTaskShape { }); return new Promise((resolve, reject) => { this._configurationResolverService.resolveWithInteraction(workspaceFolder, partiallyResolvedVars, 'tasks').then(resolvedVars => { - let result: ResolvedVariables = { + const result: ResolvedVariables = { process: undefined, variables: new Map() }; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index c3edba1ed2a..4d2e7c01c30 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -92,7 +92,7 @@ export function createApiFactory( extHostStorage: ExtHostStorage ): IExtensionApiFactory { - let schemeTransformer: ISchemeTransformer | null = null; + const schemeTransformer: ISchemeTransformer | null = null; // Addressable instances rpcProtocol.set(ExtHostContext.ExtHostLogService, extHostLogService); @@ -188,7 +188,7 @@ export function createApiFactory( }, registerTextEditorCommand(id: string, callback: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit, ...args: any[]) => void, thisArg?: any): vscode.Disposable { return extHostCommands.registerCommand(true, id, (...args: any[]): any => { - let activeTextEditor = extHostEditors.getActiveTextEditor(); + const activeTextEditor = extHostEditors.getActiveTextEditor(); if (!activeTextEditor) { console.warn('Cannot execute ' + id + ' because there is no active text editor.'); return undefined; @@ -209,7 +209,7 @@ export function createApiFactory( }, registerDiffInformationCommand: proposedApiFunction(extension, (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => { return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise => { - let activeTextEditor = extHostEditors.getActiveTextEditor(); + const activeTextEditor = extHostEditors.getActiveTextEditor(); if (!activeTextEditor) { console.warn('Cannot execute ' + id + ' because there is no active text editor.'); return undefined; @@ -566,7 +566,7 @@ export function createApiFactory( openTextDocument(uriOrFileNameOrOptions?: vscode.Uri | string | { language?: string; content?: string; }) { let uriPromise: Thenable; - let options = uriOrFileNameOrOptions as { language?: string; content?: string; }; + const options = uriOrFileNameOrOptions as { language?: string; content?: string; }; if (typeof uriOrFileNameOrOptions === 'string') { uriPromise = Promise.resolve(URI.file(uriOrFileNameOrOptions)); } else if (uriOrFileNameOrOptions instanceof URI) { diff --git a/src/vs/workbench/api/node/extHostApiCommands.ts b/src/vs/workbench/api/node/extHostApiCommands.ts index 8a54f2e10d4..ffd3502e0b7 100644 --- a/src/vs/workbench/api/node/extHostApiCommands.ts +++ b/src/vs/workbench/api/node/extHostApiCommands.ts @@ -263,7 +263,7 @@ export class ExtHostApiCommands { // --- command impl private _register(id: string, handler: (...args: any[]) => any, description?: ICommandHandlerDescription): void { - let disposable = this._commands.registerCommand(false, id, handler, this, description); + const disposable = this._commands.registerCommand(false, id, handler, this, description); this._disposables.push(disposable); } @@ -408,7 +408,7 @@ export class ExtHostApiCommands { } private _executeSelectionRangeProvider(resource: URI, positions: types.Position[]): Promise { - let pos = positions.map(typeConverters.Position.from); + const pos = positions.map(typeConverters.Position.from); const args = { resource, position: pos[0], @@ -443,7 +443,7 @@ export class ExtHostApiCommands { } class MergedInfo extends types.SymbolInformation implements vscode.DocumentSymbol { static to(symbol: modes.DocumentSymbol): MergedInfo { - let res = new MergedInfo( + const res = new MergedInfo( symbol.name, typeConverters.SymbolKind.to(symbol.kind), symbol.containerName, diff --git a/src/vs/workbench/api/node/extHostCommands.ts b/src/vs/workbench/api/node/extHostCommands.ts index acf75cefcfb..1a6b4162422 100644 --- a/src/vs/workbench/api/node/extHostCommands.ts +++ b/src/vs/workbench/api/node/extHostCommands.ts @@ -154,7 +154,7 @@ export class ExtHostCommands implements ExtHostCommandsShape { } try { - let result = callback.apply(thisArg, args); + const result = callback.apply(thisArg, args); return Promise.resolve(result); } catch (err) { this._logService.error(err, id); diff --git a/src/vs/workbench/api/node/extHostComments.ts b/src/vs/workbench/api/node/extHostComments.ts index a5dfa6d017c..a1f3156614a 100644 --- a/src/vs/workbench/api/node/extHostComments.ts +++ b/src/vs/workbench/api/node/extHostComments.ts @@ -344,7 +344,7 @@ export class ExtHostCommentThread implements vscode.CommentThread { } getComment(commentId: string): vscode.Comment | undefined { - let comments = this._comments.filter(comment => comment.commentId === commentId); + const comments = this._comments.filter(comment => comment.commentId === commentId); if (comments && comments.length) { return comments[0]; @@ -480,7 +480,7 @@ class ExtHostCommentControl implements vscode.CommentControl { } $onActiveCommentWidgetChange(commentThread: modes.CommentThread2, comment: modes.Comment | undefined, input: string) { - let extHostCommentThread = this._threads.get(commentThread.commentThreadHandle); + const extHostCommentThread = this._threads.get(commentThread.commentThreadHandle); const extHostCommentWidget = new ExtHostCommentWidget( this._proxy, diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index c593cb4bf65..880a550dab4 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -255,7 +255,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { console.error('DebugConfigurationProvider.debugAdapterExecutable is deprecated and will be removed soon; please use DebugAdapterDescriptorFactory.createDebugAdapterDescriptor instead.'); } - let handle = this._configProviderHandleCounter++; + const handle = this._configProviderHandleCounter++; this._configProviders.push({ type, handle, provider }); this._debugServiceProxy.$registerDebugConfigurationProvider(type, @@ -286,7 +286,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { throw new Error(`a DebugAdapterDescriptorFactory can only be registered once per a type.`); } - let handle = this._adapterFactoryHandleCounter++; + const handle = this._adapterFactoryHandleCounter++; this._adapterFactories.push({ type, handle, factory }); this._debugServiceProxy.$registerDebugAdapterDescriptorFactory(type, handle); @@ -303,7 +303,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { return new Disposable(() => { }); } - let handle = this._trackerFactoryHandleCounter++; + const handle = this._trackerFactoryHandleCounter++; this._trackerFactories.push({ type, handle, factory }); this._debugServiceProxy.$registerDebugAdapterTrackerFactory(type, handle); @@ -494,9 +494,9 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { public $acceptBreakpointsDelta(delta: IBreakpointsDeltaDto): void { - let a: vscode.Breakpoint[] = []; - let r: vscode.Breakpoint[] = []; - let c: vscode.Breakpoint[] = []; + const a: vscode.Breakpoint[] = []; + const r: vscode.Breakpoint[] = []; + const c: vscode.Breakpoint[] = []; if (delta.added) { for (const bpd of delta.added) { @@ -528,7 +528,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { if (delta.changed) { for (const bpd of delta.changed) { - let bp = this._breakpoints.get(bpd.id); + const bp = this._breakpoints.get(bpd.id); if (bp) { if (bp instanceof FunctionBreakpoint && bpd.type === 'function') { const fbp = bp; @@ -554,7 +554,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { } public async $provideDebugConfigurations(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { - let provider = this.getConfigProviderByHandle(configProviderHandle); + const provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { return Promise.reject(new Error('no handler found')); } @@ -566,7 +566,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { } public async $resolveDebugConfiguration(configProviderHandle: number, folderUri: UriComponents | undefined, debugConfiguration: vscode.DebugConfiguration): Promise { - let provider = this.getConfigProviderByHandle(configProviderHandle); + const provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { return Promise.reject(new Error('no handler found')); } @@ -579,7 +579,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { // TODO@AW legacy public async $legacyDebugAdapterExecutable(configProviderHandle: number, folderUri: UriComponents | undefined): Promise { - let provider = this.getConfigProviderByHandle(configProviderHandle); + const provider = this.getConfigProviderByHandle(configProviderHandle); if (!provider) { return Promise.reject(new Error('no handler found')); } @@ -591,7 +591,7 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape { } public async $provideDebugAdapter(adapterProviderHandle: number, sessionDto: IDebugSessionDto): Promise { - let adapterProvider = this.getAdapterProviderByHandle(adapterProviderHandle); + const adapterProvider = this.getAdapterProviderByHandle(adapterProviderHandle); if (!adapterProvider) { return Promise.reject(new Error('no handler found')); } diff --git a/src/vs/workbench/api/node/extHostDiagnostics.ts b/src/vs/workbench/api/node/extHostDiagnostics.ts index fe511a50994..8a54b7e405c 100644 --- a/src/vs/workbench/api/node/extHostDiagnostics.ts +++ b/src/vs/workbench/api/node/extHostDiagnostics.ts @@ -115,7 +115,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { const entries: [URI, IMarkerData[]][] = []; for (let uri of toSync) { let marker: IMarkerData[] = []; - let diagnostics = this._data.get(uri.toString()); + const diagnostics = this._data.get(uri.toString()); if (diagnostics) { // no more than N diagnostics per file @@ -170,14 +170,14 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection { forEach(callback: (uri: URI, diagnostics: vscode.Diagnostic[], collection: DiagnosticCollection) => any, thisArg?: any): void { this._checkDisposed(); this._data.forEach((value, key) => { - let uri = URI.parse(key); + const uri = URI.parse(key); callback.apply(thisArg, [uri, this.get(uri), this]); }); } get(uri: URI): vscode.Diagnostic[] { this._checkDisposed(); - let result = this._data.get(uri.toString()); + const result = this._data.get(uri.toString()); if (Array.isArray(result)) { return Object.freeze(result.slice(0)); } @@ -224,8 +224,8 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape { } static _mapper(last: (vscode.Uri | string)[]): { uris: vscode.Uri[] } { - let uris: vscode.Uri[] = []; - let map = new Set(); + const uris: vscode.Uri[] = []; + const map = new Set(); for (const uri of last) { if (typeof uri === 'string') { if (!map.has(uri)) { @@ -285,8 +285,8 @@ export class ExtHostDiagnostics implements ExtHostDiagnosticsShape { if (resource) { return this._getDiagnostics(resource); } else { - let index = new Map(); - let res: [vscode.Uri, vscode.Diagnostic[]][] = []; + const index = new Map(); + const res: [vscode.Uri, vscode.Diagnostic[]][] = []; this._collections.forEach(collection => { collection.forEach((uri, diagnostics) => { let idx = index.get(uri.toString()); diff --git a/src/vs/workbench/api/node/extHostDocumentData.ts b/src/vs/workbench/api/node/extHostDocumentData.ts index c05dbb6855d..e875c30af2b 100644 --- a/src/vs/workbench/api/node/extHostDocumentData.ts +++ b/src/vs/workbench/api/node/extHostDocumentData.ts @@ -105,7 +105,7 @@ export class ExtHostDocumentData extends MirrorTextModel { } private _getTextInRange(_range: vscode.Range): string { - let range = this._validateRange(_range); + const range = this._validateRange(_range); if (range.isEmpty) { return ''; @@ -115,7 +115,7 @@ export class ExtHostDocumentData extends MirrorTextModel { return this._lines[range.start.line].substring(range.start.character, range.end.character); } - let lineEnding = this._eol, + const lineEnding = this._eol, startLineIndex = range.start.line, endLineIndex = range.end.line, resultLines: string[] = []; @@ -178,9 +178,9 @@ export class ExtHostDocumentData extends MirrorTextModel { offset = Math.max(0, offset); this._ensureLineStarts(); - let out = this._lineStarts!.getIndexOf(offset); + const out = this._lineStarts!.getIndexOf(offset); - let lineLength = this._lines[out.index].length; + const lineLength = this._lines[out.index].length; // Ensure we return a valid position return new Position(out.index, Math.min(out.remainder, lineLength)); @@ -193,8 +193,8 @@ export class ExtHostDocumentData extends MirrorTextModel { throw new Error('Invalid argument'); } - let start = this._validatePosition(range.start); - let end = this._validatePosition(range.end); + const start = this._validatePosition(range.start); + const end = this._validatePosition(range.end); if (start === range.start && end === range.end) { return range; @@ -221,7 +221,7 @@ export class ExtHostDocumentData extends MirrorTextModel { hasChanged = true; } else { - let maxCharacter = this._lines[line].length; + const maxCharacter = this._lines[line].length; if (character < 0) { character = 0; hasChanged = true; @@ -239,7 +239,7 @@ export class ExtHostDocumentData extends MirrorTextModel { } private _getWordRangeAtPosition(_position: vscode.Position, regexp?: RegExp): vscode.Range | undefined { - let position = this._validatePosition(_position); + const position = this._validatePosition(_position); if (!regexp) { // use default when custom-regexp isn't provided @@ -251,7 +251,7 @@ export class ExtHostDocumentData extends MirrorTextModel { regexp = getWordDefinitionFor(this._languageId); } - let wordAtText = getWordAtText( + const wordAtText = getWordAtText( position.character + 1, ensureValidWordDefinition(regexp), this._lines[position.line], diff --git a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts index d8a99d2aaee..2225d4dbc06 100644 --- a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts @@ -53,7 +53,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic const entries = this._callbacks.toArray(); let didTimeout = false; - let didTimeoutHandle = setTimeout(() => didTimeout = true, this._thresholds.timeout); + const didTimeoutHandle = setTimeout(() => didTimeout = true, this._thresholds.timeout); const promise = sequence(entries.map(listener => { return () => { diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index 40ae4c8a371..2383a6eb83a 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -77,7 +77,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { public ensureDocumentData(uri: URI): Promise { - let cached = this._documentsAndEditors.getDocument(uri); + const cached = this._documentsAndEditors.getDocument(uri); if (cached) { return Promise.resolve(cached); } diff --git a/src/vs/workbench/api/node/extHostExtensionActivator.ts b/src/vs/workbench/api/node/extHostExtensionActivator.ts index b6f50845288..a248e0e9f69 100644 --- a/src/vs/workbench/api/node/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/node/extHostExtensionActivator.ts @@ -238,14 +238,14 @@ export class ExtensionsActivator { if (this._alreadyActivatedEvents[activationEvent]) { return NO_OP_VOID_PROMISE; } - let activateExtensions = this._registry.getExtensionDescriptionsForActivationEvent(activationEvent); + const activateExtensions = this._registry.getExtensionDescriptionsForActivationEvent(activationEvent); return this._activateExtensions(activateExtensions.map(e => e.identifier), reason).then(() => { this._alreadyActivatedEvents[activationEvent] = true; }); } public activateById(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise { - let desc = this._registry.getExtensionDescription(extensionId); + const desc = this._registry.getExtensionDescription(extensionId); if (!desc) { throw new Error('Extension `' + extensionId + '` is not known'); } @@ -264,7 +264,7 @@ export class ExtensionsActivator { } const currentExtension = this._registry.getExtensionDescription(currentExtensionId)!; - let depIds = (typeof currentExtension.extensionDependencies === 'undefined' ? [] : currentExtension.extensionDependencies); + const depIds = (typeof currentExtension.extensionDependencies === 'undefined' ? [] : currentExtension.extensionDependencies); let currentExtensionGetsGreenLight = true; for (let j = 0, lenJ = depIds.length; j < lenJ; j++) { @@ -330,7 +330,7 @@ export class ExtensionsActivator { return Promise.resolve(undefined); } - let greenMap: { [id: string]: ExtensionIdentifier; } = Object.create(null), + const greenMap: { [id: string]: ExtensionIdentifier; } = Object.create(null), red: ExtensionIdentifier[] = []; for (let i = 0, len = extensionIds.length; i < len; i++) { @@ -345,7 +345,7 @@ export class ExtensionsActivator { } } - let green = Object.keys(greenMap).map(id => greenMap[id]); + const green = Object.keys(greenMap).map(id => greenMap[id]); // console.log('greenExtensions: ', green.map(p => p.id)); // console.log('redExtensions: ', red.map(p => p.id)); diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 9eae6df41cf..8114ceb234a 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -225,7 +225,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { actualActivateExtension: async (extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise => { if (hostExtensions.has(ExtensionIdentifier.toKey(extensionId))) { - let activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); + const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); await this._mainThreadExtensionsProxy.$activateExtension(extensionId, activationEvent); return new HostExtension(); } @@ -345,7 +345,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { return result; } - let extension = this._activator.getActivatedExtension(extensionId); + const extension = this._activator.getActivatedExtension(extensionId); if (!extension) { return result; } @@ -382,7 +382,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { this._mainThreadExtensionsProxy.$onWillActivateExtension(extensionDescription.identifier); return this._doActivateExtension(extensionDescription, reason).then((activatedExtension) => { const activationTimes = activatedExtension.activationTimes; - let activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); + const activationEvent = (reason instanceof ExtensionActivatedByEvent ? reason.activationEvent : null); this._mainThreadExtensionsProxy.$onDidActivateExtension(extensionDescription.identifier, activationTimes.startup, activationTimes.codeLoadingTime, activationTimes.activateCallTime, activationTimes.activateResolvedTime, activationEvent); this._logExtensionActivationTimes(extensionDescription, reason, 'success', activationTimes); return activatedExtension; @@ -394,7 +394,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } private _logExtensionActivationTimes(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason, outcome: string, activationTimes?: ExtensionActivationTimes) { - let event = getTelemetryActivationEvent(extensionDescription, reason); + const event = getTelemetryActivationEvent(extensionDescription, reason); /* __GDPR__ "extensionActivationTimes" : { "${include}": [ @@ -412,7 +412,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise { - let event = getTelemetryActivationEvent(extensionDescription, reason); + const event = getTelemetryActivationEvent(extensionDescription, reason); /* __GDPR__ "activatePlugin" : { "${include}": [ @@ -439,8 +439,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { - let globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); - let workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); + const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); + const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); this._extHostLogService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`); return Promise.all([ @@ -763,7 +763,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { } public async $test_down(size: number): Promise { - let b = Buffer.alloc(size, Math.random() % 256); + const b = Buffer.alloc(size, Math.random() % 256); return b; } @@ -799,7 +799,7 @@ function getTelemetryActivationEvent(extensionDescription: IExtensionDescription "reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ - let event = { + const event = { id: extensionDescription.identifier.value, name: extensionDescription.name, extensionVersion: extensionDescription.version, diff --git a/src/vs/workbench/api/node/extHostFileSystem.ts b/src/vs/workbench/api/node/extHostFileSystem.ts index 29cf43d41a3..8a83afc3ca4 100644 --- a/src/vs/workbench/api/node/extHostFileSystem.ts +++ b/src/vs/workbench/api/node/extHostFileSystem.ts @@ -28,7 +28,7 @@ class FsLinkProvider { } delete(scheme: string): void { - let idx = this._schemes.indexOf(scheme); + const idx = this._schemes.indexOf(scheme); if (idx >= 0) { this._schemes.splice(idx, 1); this._stateMachine = undefined; @@ -94,7 +94,7 @@ class FsLinkProvider { }, this._stateMachine); for (const link of links) { - let docLink = typeConverter.DocumentLink.to(link); + const docLink = typeConverter.DocumentLink.to(link); if (docLink.target) { result.push(docLink); } @@ -172,7 +172,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { this._proxy.$registerFileSystemProvider(handle, scheme, capabilites); const subscription = provider.onDidChangeFile(event => { - let mapped: IFileChangeDto[] = []; + const mapped: IFileChangeDto[] = []; for (const e of event) { let { uri: resource, type } = e; if (resource.scheme !== scheme) { @@ -260,12 +260,12 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $watch(handle: number, session: number, resource: UriComponents, opts: files.IWatchOptions): void { - let subscription = this.getProvider(handle).watch(URI.revive(resource), opts); + const subscription = this.getProvider(handle).watch(URI.revive(resource), opts); this._watches.set(session, subscription); } $unwatch(_handle: number, session: number): void { - let subscription = this._watches.get(session); + const subscription = this._watches.get(session); if (subscription) { subscription.dispose(); this._watches.delete(session); diff --git a/src/vs/workbench/api/node/extHostFileSystemEventService.ts b/src/vs/workbench/api/node/extHostFileSystemEventService.ts index f7f682b6281..6d709b3a107 100644 --- a/src/vs/workbench/api/node/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/node/extHostFileSystemEventService.ts @@ -49,10 +49,10 @@ class FileSystemWatcher implements vscode.FileSystemWatcher { const parsedPattern = parse(globPattern); - let subscription = dispatcher(events => { + const subscription = dispatcher(events => { if (!ignoreCreateEvents) { for (let created of events.created) { - let uri = URI.revive(created); + const uri = URI.revive(created); if (parsedPattern(uri.fsPath)) { this._onDidCreate.fire(uri); } @@ -60,7 +60,7 @@ class FileSystemWatcher implements vscode.FileSystemWatcher { } if (!ignoreChangeEvents) { for (let changed of events.changed) { - let uri = URI.revive(changed); + const uri = URI.revive(changed); if (parsedPattern(uri.fsPath)) { this._onDidChange.fire(uri); } @@ -68,7 +68,7 @@ class FileSystemWatcher implements vscode.FileSystemWatcher { } if (!ignoreDeleteEvents) { for (let deleted of events.deleted) { - let uri = URI.revive(deleted); + const uri = URI.revive(deleted); if (parsedPattern(uri.fsPath)) { this._onDidDelete.fire(uri); } @@ -169,7 +169,7 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ } // flatten all WorkspaceEdits collected via waitUntil-call // and apply them in one go. - let allEdits = new Array>(); + const allEdits = new Array>(); for (let edit of edits) { if (edit) { // sparse array let { edits } = typeConverter.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors); diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 54f34709fa2..d1cb405a281 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -65,10 +65,10 @@ class DocumentSymbolAdapter { } return res; }); - let res: modes.DocumentSymbol[] = []; - let parentStack: modes.DocumentSymbol[] = []; + const res: modes.DocumentSymbol[] = []; + const parentStack: modes.DocumentSymbol[] = []; for (const info of infos) { - let element = { + const element = { name: info.name || '!!MISSING: name!!', kind: typeConvert.SymbolKind.from(info.kind), containerName: info.containerName, @@ -83,7 +83,7 @@ class DocumentSymbolAdapter { res.push(element); break; } - let parent = parentStack[parentStack.length - 1]; + const parent = parentStack[parentStack.length - 1]; if (EditorRange.containsRange(parent.range, element.range) && !EditorRange.equalsRange(parent.range, element.range)) { parent.children.push(element); parentStack.push(element); @@ -111,7 +111,7 @@ class CodeLensAdapter { const doc = this._documents.getDocument(resource); return asPromise(() => this._provider.provideCodeLenses(doc, token)).then(lenses => { - let result: CodeLensDto[] = []; + const result: CodeLensDto[] = []; if (isNonEmptyArray(lenses)) { for (const lens of lenses) { const id = this._heapService.keep(lens); @@ -206,7 +206,7 @@ class DefinitionAdapter { provideDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideDefinition(doc, pos, token)).then(convertToLocationLinks); } } @@ -220,7 +220,7 @@ class DeclarationAdapter { provideDeclaration(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideDeclaration(doc, pos, token)).then(convertToLocationLinks); } } @@ -234,7 +234,7 @@ class ImplementationAdapter { provideImplementation(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideImplementation(doc, pos, token)).then(convertToLocationLinks); } } @@ -263,7 +263,7 @@ class HoverAdapter { public provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideHover(doc, pos, token)).then(value => { if (!value || isFalsyOrEmpty(value.contents)) { @@ -291,7 +291,7 @@ class DocumentHighlightAdapter { provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideDocumentHighlights(doc, pos, token)).then(value => { if (Array.isArray(value)) { @@ -311,7 +311,7 @@ class ReferenceAdapter { provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideReferences(doc, pos, context, token)).then(value => { if (Array.isArray(value)) { @@ -546,7 +546,7 @@ class RenameAdapter { provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.provideRenameEdits(doc, pos, newName, token)).then(value => { if (!value) { @@ -554,7 +554,7 @@ class RenameAdapter { } return typeConvert.WorkspaceEdit.from(value); }, err => { - let rejectReason = RenameAdapter._asMessage(err); + const rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { return { rejectReason, edits: undefined! }; } else { @@ -570,7 +570,7 @@ class RenameAdapter { } const doc = this._documents.getDocument(resource); - let pos = typeConvert.Position.to(position); + const pos = typeConvert.Position.to(position); return asPromise(() => this._provider.prepareRename!(doc, pos, token)).then(rangeOrLocation => { @@ -594,7 +594,7 @@ class RenameAdapter { } return { range: typeConvert.Range.from(range), text }; }, err => { - let rejectReason = RenameAdapter._asMessage(err); + const rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { return { rejectReason, range: undefined!, text: undefined! }; } else { @@ -832,8 +832,8 @@ class LinkProviderAdapter { } const result: LinkDto[] = []; for (const link of links) { - let data = typeConvert.DocumentLink.from(link); - let id = this._heapService.keep(link); + const data = typeConvert.DocumentLink.from(link); + const id = this._heapService.keep(link); result.push(ObjectIdentifier.mixin(data, id)); } return result; @@ -936,7 +936,7 @@ class SelectionRangeAdapter { return []; } - let allResults: modes.SelectionRange[][] = []; + const allResults: modes.SelectionRange[][] = []; for (let i = 0; i < positions.length; i++) { const oneResult: modes.SelectionRange[] = []; allResults.push(oneResult); @@ -1065,7 +1065,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { t1 = Date.now(); this._logService.trace(`[${data.extension.identifier.value}] INVOKE provider '${(ctor as any).name}'`); } - let p = callback(data.adapter, data.extension); + const p = callback(data.adapter, data.extension); const extension = data.extension; if (extension) { Promise.resolve(p).then( diff --git a/src/vs/workbench/api/node/extHostMessageService.ts b/src/vs/workbench/api/node/extHostMessageService.ts index ea85d1d6d99..635f076610d 100644 --- a/src/vs/workbench/api/node/extHostMessageService.ts +++ b/src/vs/workbench/api/node/extHostMessageService.ts @@ -24,7 +24,7 @@ export class ExtHostMessageService { showMessage(extension: IExtensionDescription, severity: Severity, message: string, optionsOrFirstItem: vscode.MessageOptions | vscode.MessageItem, rest: vscode.MessageItem[]): Promise; showMessage(extension: IExtensionDescription, severity: Severity, message: string, optionsOrFirstItem: vscode.MessageOptions | string | vscode.MessageItem, rest: (string | vscode.MessageItem)[]): Promise { - let options: MainThreadMessageOptions = { extension }; + const options: MainThreadMessageOptions = { extension }; let items: (string | vscode.MessageItem)[]; if (typeof optionsOrFirstItem === 'string' || isMessageItem(optionsOrFirstItem)) { @@ -37,7 +37,7 @@ export class ExtHostMessageService { const commands: { title: string; isCloseAffordance: boolean; handle: number; }[] = []; for (let handle = 0; handle < items.length; handle++) { - let command = items[handle]; + const command = items[handle]; if (typeof command === 'string') { commands.push({ title: command, handle, isCloseAffordance: false }); } else if (typeof command === 'object') { diff --git a/src/vs/workbench/api/node/extHostQuickOpen.ts b/src/vs/workbench/api/node/extHostQuickOpen.ts index 1a8fbce1a76..9aedb8e14e6 100644 --- a/src/vs/workbench/api/node/extHostQuickOpen.ts +++ b/src/vs/workbench/api/node/extHostQuickOpen.ts @@ -68,10 +68,10 @@ export class ExtHostQuickOpen implements ExtHostQuickOpenShape { return itemsPromise.then(items => { - let pickItems: TransferQuickPickItems[] = []; + const pickItems: TransferQuickPickItems[] = []; for (let handle = 0; handle < items.length; handle++) { - let item = items[handle]; + const item = items[handle]; let label: string; let description: string | undefined; let detail: string | undefined; diff --git a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts index 57ccbf500e8..9ca147e4cfe 100644 --- a/src/vs/workbench/api/node/extHostSearch.fileIndex.ts +++ b/src/vs/workbench/api/node/extHostSearch.fileIndex.ts @@ -116,7 +116,7 @@ export class FileIndexSearchEngine { } private searchInFolder(fq: IFolderQuery, onResult: (match: IInternalFileMatch) => void): Promise { - let cancellation = new CancellationTokenSource(); + const cancellation = new CancellationTokenSource(); return new Promise((resolve, reject) => { const options = this.getSearchOptionsForFolder(fq); const tree = this.initDirectoryTree(); @@ -511,10 +511,10 @@ export class FileIndexSearchManager { } // Pattern match on results - let results: IInternalFileMatch[] = []; + const results: IInternalFileMatch[] = []; const normalizedSearchValueLowercase = strings.stripWildcards(searchValue).toLowerCase(); for (let i = 0; i < complete.results.length; i++) { - let entry = complete.results[i]; + const entry = complete.results[i]; // Check if this entry is a match for the search value if (!strings.fuzzyContains(entry.relativePath!, normalizedSearchValueLowercase)) { diff --git a/src/vs/workbench/api/node/extHostStatusBar.ts b/src/vs/workbench/api/node/extHostStatusBar.ts index e5ff768408b..cd6c2066146 100644 --- a/src/vs/workbench/api/node/extHostStatusBar.ts +++ b/src/vs/workbench/api/node/extHostStatusBar.ts @@ -139,7 +139,7 @@ class StatusBarMessage { this._update(); return new Disposable(() => { - let idx = this._messages.indexOf(data); + const idx = this._messages.indexOf(data); if (idx >= 0) { this._messages.splice(idx, 1); this._update(); @@ -173,7 +173,7 @@ export class ExtHostStatusBar { setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable): Disposable { - let d = this._statusMessage.setMessage(text); + const d = this._statusMessage.setMessage(text); let handle: any; if (typeof timeoutOrThenable === 'number') { diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index eeed4f06b6e..8d2fc278b45 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -75,14 +75,14 @@ namespace ProcessExecutionOptionsDTO { namespace ProcessExecutionDTO { export function is(value: ShellExecutionDTO | ProcessExecutionDTO): value is ProcessExecutionDTO { - let candidate = value as ProcessExecutionDTO; + const candidate = value as ProcessExecutionDTO; return candidate && !!candidate.process; } export function from(value: vscode.ProcessExecution): ProcessExecutionDTO { if (value === undefined || value === null) { return undefined; } - let result: ProcessExecutionDTO = { + const result: ProcessExecutionDTO = { process: value.process, args: value.args }; @@ -116,14 +116,14 @@ namespace ShellExecutionOptionsDTO { namespace ShellExecutionDTO { export function is(value: ShellExecutionDTO | ProcessExecutionDTO): value is ShellExecutionDTO { - let candidate = value as ShellExecutionDTO; + const candidate = value as ShellExecutionDTO; return candidate && (!!candidate.commandLine || !!candidate.command); } export function from(value: vscode.ShellExecution): ShellExecutionDTO { if (value === undefined || value === null) { return undefined; } - let result: ShellExecutionDTO = { + const result: ShellExecutionDTO = { }; if (value.commandLine !== undefined) { result.commandLine = value.commandLine; @@ -167,9 +167,9 @@ namespace TaskDTO { if (tasks === undefined || tasks === null) { return []; } - let result: TaskDTO[] = []; + const result: TaskDTO[] = []; for (let task of tasks) { - let converted = from(task, extension); + const converted = from(task, extension); if (converted) { result.push(converted); } @@ -187,7 +187,7 @@ namespace TaskDTO { } else if (value.execution instanceof types.ShellExecution) { execution = ShellExecutionDTO.from(value.execution); } - let definition: TaskDefinitionDTO = TaskDefinitionDTO.from(value.definition); + const definition: TaskDefinitionDTO = TaskDefinitionDTO.from(value.definition); let scope: number | UriComponents; if (value.scope) { if (typeof value.scope === 'number') { @@ -202,8 +202,8 @@ namespace TaskDTO { if (!definition || !scope) { return undefined; } - let group = (value.group as types.TaskGroup) ? (value.group as types.TaskGroup).id : undefined; - let result: TaskDTO = { + const group = (value.group as types.TaskGroup) ? (value.group as types.TaskGroup).id : undefined; + const result: TaskDTO = { _id: (value as types.Task)._id, definition, name: value.name, @@ -232,7 +232,7 @@ namespace TaskDTO { } else if (ShellExecutionDTO.is(value.execution)) { execution = ShellExecutionDTO.to(value.execution); } - let definition: vscode.TaskDefinition = TaskDefinitionDTO.to(value.definition); + const definition: vscode.TaskDefinition = TaskDefinitionDTO.to(value.definition); let scope: vscode.TaskScope.Global | vscode.TaskScope.Workspace | vscode.WorkspaceFolder | undefined; if (value.source) { if (value.source.scope !== undefined) { @@ -248,7 +248,7 @@ namespace TaskDTO { if (!definition || !scope) { return undefined; } - let result = new types.Task(definition, scope, value.name, value.source.label, execution, value.problemMatchers); + const result = new types.Task(definition, scope, value.name, value.source.label, execution, value.problemMatchers); if (value.isBackground !== undefined) { result.isBackground = value.isBackground; } @@ -345,7 +345,7 @@ export class ExtHostTask implements ExtHostTaskShape { if (!provider) { return new types.Disposable(() => { }); } - let handle = this.nextHandle(); + const handle = this.nextHandle(); this._handlers.set(handle, { provider, extension }); this._proxy.$registerTaskProvider(handle); return new types.Disposable(() => { @@ -360,9 +360,9 @@ export class ExtHostTask implements ExtHostTaskShape { public fetchTasks(filter?: vscode.TaskFilter): Promise { return this._proxy.$fetchTasks(TaskFilterDTO.from(filter)).then(async (values) => { - let result: vscode.Task[] = []; + const result: vscode.Task[] = []; for (let value of values) { - let task = await TaskDTO.to(value, this._workspaceProvider); + const task = await TaskDTO.to(value, this._workspaceProvider); if (task) { result.push(task); } @@ -372,12 +372,12 @@ export class ExtHostTask implements ExtHostTaskShape { } public async executeTask(extension: IExtensionDescription, task: vscode.Task): Promise { - let tTask = (task as types.Task); + const tTask = (task as types.Task); // We have a preserved ID. So the task didn't change. if (tTask._id !== undefined) { return this._proxy.$executeTask(TaskHandleDTO.from(tTask)).then(value => this.getTaskExecution(value, task)); } else { - let dto = TaskDTO.from(task, extension); + const dto = TaskDTO.from(task, extension); if (dto === undefined) { return Promise.reject(new Error('Task is not valid')); } @@ -386,7 +386,7 @@ export class ExtHostTask implements ExtHostTaskShape { } public get taskExecutions(): vscode.TaskExecution[] { - let result: vscode.TaskExecution[] = []; + const result: vscode.TaskExecution[] = []; this._taskExecutions.forEach(value => result.push(value)); return result; } @@ -449,12 +449,12 @@ export class ExtHostTask implements ExtHostTaskShape { } public $provideTasks(handle: number, validTypes: { [key: string]: boolean; }): Thenable { - let handler = this._handlers.get(handle); + const handler = this._handlers.get(handle); if (!handler) { return Promise.reject(new Error('no handler found')); } return asPromise(() => handler.provider.provideTasks(CancellationToken.None)).then(value => { - let sanitized: vscode.Task[] = []; + const sanitized: vscode.Task[] = []; for (let task of value) { if (task.definition && validTypes[task.definition.type] === true) { sanitized.push(task); @@ -472,15 +472,15 @@ export class ExtHostTask implements ExtHostTaskShape { public async $resolveVariables(uriComponents: UriComponents, toResolve: { process?: { name: string; cwd?: string; path?: string }, variables: string[] }): Promise<{ process?: string, variables: { [key: string]: string; } }> { const configProvider = await this._configurationService.getConfigProvider(); - let uri: URI = URI.revive(uriComponents); - let result = { + const uri: URI = URI.revive(uriComponents); + const result = { process: undefined as string, variables: Object.create(null) }; - let workspaceFolder = await this._workspaceProvider.resolveWorkspaceFolder(uri); + const workspaceFolder = await this._workspaceProvider.resolveWorkspaceFolder(uri); const workspaceFolders = await this._workspaceProvider.getWorkspaceFolders2(); - let resolver = new ExtHostVariableResolverService(workspaceFolders, this._editorService, configProvider); - let ws: IWorkspaceFolder = { + const resolver = new ExtHostVariableResolverService(workspaceFolders, this._editorService, configProvider); + const ws: IWorkspaceFolder = { uri: workspaceFolder.uri, name: workspaceFolder.name, index: workspaceFolder.index, diff --git a/src/vs/workbench/api/node/extHostTextEditor.ts b/src/vs/workbench/api/node/extHostTextEditor.ts index ae9ea2f67cf..d3080e367b6 100644 --- a/src/vs/workbench/api/node/extHostTextEditor.ts +++ b/src/vs/workbench/api/node/extHostTextEditor.ts @@ -106,7 +106,7 @@ export class TextEditorEdit { } private _pushEdit(range: Range, text: string | null, forceMoveMarkers: boolean): void { - let validRange = this._document.validateRange(range); + const validRange = this._document.validateRange(range); this._collectedEdits.push({ range: validRange, text: text, @@ -170,11 +170,11 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { return 'auto'; } if (typeof value === 'number') { - let r = Math.floor(value); + const r = Math.floor(value); return (r > 0 ? r : null); } if (typeof value === 'string') { - let r = parseInt(value, 10); + const r = parseInt(value, 10); if (isNaN(r)) { return null; } @@ -184,7 +184,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { } public set tabSize(value: number | string) { - let tabSize = this._validateTabSize(value); + const tabSize = this._validateTabSize(value); if (tabSize === null) { // ignore invalid call return; @@ -211,11 +211,11 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { return 'tabSize'; } if (typeof value === 'number') { - let r = Math.floor(value); + const r = Math.floor(value); return (r > 0 ? r : null); } if (typeof value === 'string') { - let r = parseInt(value, 10); + const r = parseInt(value, 10); if (isNaN(r)) { return null; } @@ -225,7 +225,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { } public set indentSize(value: number | string) { - let indentSize = this._validateIndentSize(value); + const indentSize = this._validateIndentSize(value); if (indentSize === null) { // ignore invalid call return; @@ -255,7 +255,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { } public set insertSpaces(value: boolean | string) { - let insertSpaces = this._validateInsertSpaces(value); + const insertSpaces = this._validateInsertSpaces(value); if (typeof insertSpaces === 'boolean') { if (this._insertSpaces === insertSpaces) { // nothing to do @@ -300,11 +300,11 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { } public assign(newOptions: vscode.TextEditorOptions) { - let bulkConfigurationUpdate: ITextEditorConfigurationUpdate = {}; + const bulkConfigurationUpdate: ITextEditorConfigurationUpdate = {}; let hasUpdate = false; if (typeof newOptions.tabSize !== 'undefined') { - let tabSize = this._validateTabSize(newOptions.tabSize); + const tabSize = this._validateTabSize(newOptions.tabSize); if (tabSize === 'auto') { hasUpdate = true; bulkConfigurationUpdate.tabSize = tabSize; @@ -317,7 +317,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { } // if (typeof newOptions.indentSize !== 'undefined') { - // let indentSize = this._validateIndentSize(newOptions.indentSize); + // const indentSize = this._validateIndentSize(newOptions.indentSize); // if (indentSize === 'tabSize') { // hasUpdate = true; // bulkConfigurationUpdate.indentSize = indentSize; @@ -330,7 +330,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions { // } if (typeof newOptions.insertSpaces !== 'undefined') { - let insertSpaces = this._validateInsertSpaces(newOptions.insertSpaces); + const insertSpaces = this._validateInsertSpaces(newOptions.insertSpaces); if (insertSpaces === 'auto') { hasUpdate = true; bulkConfigurationUpdate.insertSpaces = insertSpaces; @@ -510,7 +510,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { TypeConverters.fromRangeOrRangeWithMessage(ranges) ); } else { - let _ranges: number[] = new Array(4 * ranges.length); + const _ranges: number[] = new Array(4 * ranges.length); for (let i = 0, len = ranges.length; i < len; i++) { const range = ranges[i]; _ranges[4 * i] = range.start.line + 1; @@ -539,7 +539,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { } private _trySetSelection(): Promise { - let selection = this._selections.map(TypeConverters.Selection.from); + const selection = this._selections.map(TypeConverters.Selection.from); return this._runOnProxy(() => this._proxy.$trySetSelections(this._id, selection)); } @@ -554,13 +554,13 @@ export class ExtHostTextEditor implements vscode.TextEditor { if (this._disposed) { return Promise.reject(new Error('TextEditor#edit not possible on closed editors')); } - let edit = new TextEditorEdit(this._documentData.document, options); + const edit = new TextEditorEdit(this._documentData.document, options); callback(edit); return this._applyEdit(edit); } private _applyEdit(editBuilder: TextEditorEdit): Promise { - let editData = editBuilder.finalize(); + const editData = editBuilder.finalize(); // return when there is nothing to do if (editData.edits.length === 0 && !editData.setEndOfLine) { @@ -568,7 +568,7 @@ export class ExtHostTextEditor implements vscode.TextEditor { } // check that the edits are not overlapping (i.e. illegal) - let editRanges = editData.edits.map(edit => edit.range); + const editRanges = editData.edits.map(edit => edit.range); // sort ascending (by end and then by start) editRanges.sort((a, b) => { diff --git a/src/vs/workbench/api/node/extHostTextEditors.ts b/src/vs/workbench/api/node/extHostTextEditors.ts index 5e6e2dfb5a1..a42ec9c245f 100644 --- a/src/vs/workbench/api/node/extHostTextEditors.ts +++ b/src/vs/workbench/api/node/extHostTextEditors.ts @@ -75,7 +75,7 @@ export class ExtHostEditors implements ExtHostEditorsShape { } return this._proxy.$tryShowTextDocument(document.uri, options).then(id => { - let editor = this._extHostDocumentsAndEditors.getEditor(id); + const editor = this._extHostDocumentsAndEditors.getEditor(id); if (editor) { return editor; } else { diff --git a/src/vs/workbench/api/node/extHostTreeViews.ts b/src/vs/workbench/api/node/extHostTreeViews.ts index f5e8ea7aba9..b135cd62d8d 100644 --- a/src/vs/workbench/api/node/extHostTreeViews.ts +++ b/src/vs/workbench/api/node/extHostTreeViews.ts @@ -366,7 +366,7 @@ class ExtHostTreeView extends Disposable { private getHandlesToRefresh(elements: T[]): TreeItemHandle[] { const elementsToUpdate = new Set(); for (const element of elements) { - let elementNode = this.nodes.get(element); + const elementNode = this.nodes.get(element); if (elementNode && !elementsToUpdate.has(elementNode.item.handle)) { // check if an ancestor of extElement is already in the elements to update list let currentNode = elementNode; @@ -384,7 +384,7 @@ class ExtHostTreeView extends Disposable { // Take only top level elements elementsToUpdate.forEach((handle) => { const element = this.elements.get(handle); - let node = this.nodes.get(element); + const node = this.nodes.get(element); if (node && (!node.parent || !elementsToUpdate.has(node.parent.item.handle))) { handlesToUpdate.push(handle); } @@ -553,7 +553,7 @@ class ExtHostTreeView extends Disposable { private clearChildren(parentElement?: T): void { if (parentElement) { - let node = this.nodes.get(parentElement); + const node = this.nodes.get(parentElement); if (node.children) { for (const child of node.children) { const childEleement = this.elements.get(child.item.handle); @@ -569,7 +569,7 @@ class ExtHostTreeView extends Disposable { } private clear(element: T): void { - let node = this.nodes.get(element); + const node = this.nodes.get(element); if (node.children) { for (const child of node.children) { const childEleement = this.elements.get(child.item.handle); diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 54006bf3829..b87947ae0b8 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -236,7 +236,7 @@ export namespace MarkdownString { const resUris: { [href: string]: UriComponents } = Object.create(null); res.uris = resUris; - let renderer = new marked.Renderer(); + const renderer = new marked.Renderer(); renderer.image = renderer.link = (href: string): string => { try { let uri = URI.parse(href, true); @@ -267,7 +267,7 @@ export namespace MarkdownString { } data = cloneAndChange(data, value => { if (value instanceof URI) { - let key = `__uri_${Math.random().toString(16).slice(2, 8)}`; + const key = `__uri_${Math.random().toString(16).slice(2, 8)}`; bucket[key] = value; return key; } else { diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index 71dc9a8b3a7..535dadfb0c8 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -66,7 +66,7 @@ export class Position { } let result = positions[0]; for (let i = 1; i < positions.length; i++) { - let p = positions[i]; + const p = positions[i]; if (p.isBefore(result!)) { result = p; } @@ -80,7 +80,7 @@ export class Position { } let result = positions[0]; for (let i = 1; i < positions.length; i++) { - let p = positions[i]; + const p = positions[i]; if (p.isAfter(result!)) { result = p; } @@ -303,8 +303,8 @@ export class Range { } intersection(other: Range): Range | undefined { - let start = Position.Max(other.start, this._start); - let end = Position.Min(other.end, this._end); + const start = Position.Max(other.start, this._start); + const end = Position.Min(other.end, this._end); if (start.isAfter(end)) { // this happens when there is no overlap: // |-----| @@ -320,8 +320,8 @@ export class Range { } else if (other.contains(this)) { return other; } - let start = Position.Min(other.start, this._start); - let end = Position.Max(other.end, this.end); + const start = Position.Min(other.start, this._start); + const end = Position.Max(other.end, this.end); return new Range(start, end); } @@ -480,7 +480,7 @@ export class TextEdit { } static setEndOfLine(eol: EndOfLine): TextEdit { - let ret = new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), ''); + const ret = new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), ''); ret.newEol = eol; return ret; } @@ -616,7 +616,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { } get(uri: URI): TextEdit[] { - let res: TextEdit[] = []; + const res: TextEdit[] = []; for (let candidate of this._edits) { if (candidate._type === 2 && candidate.uri.toString() === uri.toString()) { res.push(candidate.edit); @@ -626,7 +626,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { } entries(): [URI, TextEdit[]][] { - let textEdits = new Map(); + const textEdits = new Map(); for (let candidate of this._edits) { if (candidate._type === 2) { let textEdit = textEdits.get(candidate.uri.toString()); @@ -641,7 +641,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit { } _allEntries(): ([URI, TextEdit[]] | [URI?, URI?, IFileOperationOptions?])[] { - let res: ([URI, TextEdit[]] | [URI?, URI?, IFileOperationOptions?])[] = []; + const res: ([URI, TextEdit[]] | [URI?, URI?, IFileOperationOptions?])[] = []; for (let edit of this._edits) { if (edit._type === 1) { res.push([edit.from, edit.to, edit.options]); @@ -1846,7 +1846,7 @@ export class Task implements vscode.Task { } this.clear(); this._execution = value; - let type = this._definition.type; + const type = this._definition.type; if (Task.EmptyType === type || Task.ProcessType === type || Task.ShellType === type) { this.computeDefinitionBasedOnExecution(); } diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index edcbfaee62e..785ad829cba 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -459,7 +459,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac excludePattern: options.exclude ? globPatternToString(options.exclude) : undefined }; - let isCanceled = false; + const isCanceled = false; this._activeSearchCallbacks[requestId] = p => { if (isCanceled) { From 3f93ea65210fd28eb9507795738bb741cf0a1a7a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 16:48:35 -0800 Subject: [PATCH 266/290] Auto convert let -> const in base/common --- src/vs/base/common/arrays.ts | 12 +++--- src/vs/base/common/async.ts | 8 ++-- src/vs/base/common/cancellation.ts | 2 +- src/vs/base/common/color.ts | 2 +- src/vs/base/common/comparers.ts | 18 ++++---- src/vs/base/common/errors.ts | 4 +- src/vs/base/common/event.ts | 14 +++---- src/vs/base/common/extpath.ts | 6 +-- src/vs/base/common/filters.ts | 42 +++++++++---------- src/vs/base/common/glob.ts | 8 ++-- src/vs/base/common/history.ts | 2 +- src/vs/base/common/json.ts | 58 +++++++++++++------------- src/vs/base/common/jsonEdit.ts | 42 +++++++++---------- src/vs/base/common/jsonFormatter.ts | 20 ++++----- src/vs/base/common/keyCodes.ts | 10 ++--- src/vs/base/common/keybindingLabels.ts | 4 +- src/vs/base/common/keybindingParser.ts | 4 +- src/vs/base/common/linkedList.ts | 4 +- src/vs/base/common/map.ts | 48 ++++++++++----------- src/vs/base/common/objects.ts | 4 +- src/vs/base/common/parsers.ts | 4 +- src/vs/base/common/path.ts | 42 +++++++++---------- src/vs/base/common/platform.ts | 8 ++-- src/vs/base/common/process.ts | 2 +- src/vs/base/common/resources.ts | 2 +- src/vs/base/common/scrollable.ts | 12 +++--- src/vs/base/common/strings.ts | 36 ++++++++-------- src/vs/base/common/types.ts | 2 +- src/vs/base/common/uri.ts | 14 +++---- 29 files changed, 217 insertions(+), 217 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index ce2f41cf633..4b6e32dc042 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -51,8 +51,8 @@ export function binarySearch(array: ReadonlyArray, key: T, comparator: (op high = array.length - 1; while (low <= high) { - let mid = ((low + high) / 2) | 0; - let comp = comparator(array[mid], key); + const mid = ((low + high) / 2) | 0; + const comp = comparator(array[mid], key); if (comp < 0) { low = mid + 1; } else if (comp > 0) { @@ -75,7 +75,7 @@ export function findFirstInSorted(array: ReadonlyArray, p: (x: T) => boole return 0; // no children } while (low < high) { - let mid = Math.floor((low + high) / 2); + const mid = Math.floor((low + high) / 2); if (p(array[mid])) { high = mid; } else { @@ -122,7 +122,7 @@ function _sort(a: T[], compare: Compare, lo: number, hi: number, aux: T[]) if (hi <= lo) { return; } - let mid = lo + ((hi - lo) / 2) | 0; + const mid = lo + ((hi - lo) / 2) | 0; _sort(a, compare, lo, mid, aux); _sort(a, compare, mid + 1, hi, aux); if (compare(a[mid], a[mid + 1]) <= 0) { @@ -502,8 +502,8 @@ export function shuffle(array: T[], _seed?: number): void { } for (let i = array.length - 1; i > 0; i -= 1) { - let j = Math.floor(rand() * (i + 1)); - let temp = array[i]; + const j = Math.floor(rand() * (i + 1)); + const temp = array[i]; array[i] = array[j]; array[j] = temp; } diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index 080a2c7a273..8cc8a36ffcd 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -52,7 +52,7 @@ export function createCancelablePromise(callback: (token: CancellationToken) export function asPromise(callback: () => T | Thenable): Promise { return new Promise((resolve, reject) => { - let item = callback(); + const item = callback(); if (isThenable(item)) { item.then(resolve, reject); } else { @@ -688,12 +688,12 @@ declare function cancelIdleCallback(handle: number): void; (function () { if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') { - let dummyIdle: IdleDeadline = Object.freeze({ + const dummyIdle: IdleDeadline = Object.freeze({ didTimeout: true, timeRemaining() { return 15; } }); runWhenIdle = (runner) => { - let handle = setTimeout(() => runner(dummyIdle)); + const handle = setTimeout(() => runner(dummyIdle)); let disposed = false; return { dispose() { @@ -707,7 +707,7 @@ declare function cancelIdleCallback(handle: number): void; }; } else { runWhenIdle = (runner, timeout?) => { - let handle: number = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); + const handle: number = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined); let disposed = false; return { dispose() { diff --git a/src/vs/base/common/cancellation.ts b/src/vs/base/common/cancellation.ts index 39f672c9751..8f6b0b96f74 100644 --- a/src/vs/base/common/cancellation.ts +++ b/src/vs/base/common/cancellation.ts @@ -16,7 +16,7 @@ export interface CancellationToken { } const shortcutEvent = Object.freeze(function (callback, context?): IDisposable { - let handle = setTimeout(callback.bind(context), 0); + const handle = setTimeout(callback.bind(context), 0); return { dispose() { clearTimeout(handle); } }; } as Event); diff --git a/src/vs/base/common/color.ts b/src/vs/base/common/color.ts index f63e7aa86f1..3be7a1128a6 100644 --- a/src/vs/base/common/color.ts +++ b/src/vs/base/common/color.ts @@ -387,7 +387,7 @@ export class Color { const thisA = this.rgba.a; const colorA = rgba.a; - let a = thisA + colorA * (1 - thisA); + const a = thisA + colorA * (1 - thisA); if (a < 1e-6) { return Color.transparent; } diff --git a/src/vs/base/common/comparers.ts b/src/vs/base/common/comparers.ts index f5b9b26edd6..adf5859c794 100644 --- a/src/vs/base/common/comparers.ts +++ b/src/vs/base/common/comparers.ts @@ -144,8 +144,8 @@ export function comparePaths(one: string, other: string, caseSensitive = false): } export function compareAnything(one: string, other: string, lookFor: string): number { - let elementAName = one.toLowerCase(); - let elementBName = other.toLowerCase(); + const elementAName = one.toLowerCase(); + const elementBName = other.toLowerCase(); // Sort prefix matches over non prefix matches const prefixCompare = compareByPrefix(one, other, lookFor); @@ -154,14 +154,14 @@ export function compareAnything(one: string, other: string, lookFor: string): nu } // Sort suffix matches over non suffix matches - let elementASuffixMatch = strings.endsWith(elementAName, lookFor); - let elementBSuffixMatch = strings.endsWith(elementBName, lookFor); + const elementASuffixMatch = strings.endsWith(elementAName, lookFor); + const elementBSuffixMatch = strings.endsWith(elementBName, lookFor); if (elementASuffixMatch !== elementBSuffixMatch) { return elementASuffixMatch ? -1 : 1; } // Understand file names - let r = compareFileNames(elementAName, elementBName); + const r = compareFileNames(elementAName, elementBName); if (r !== 0) { return r; } @@ -171,12 +171,12 @@ export function compareAnything(one: string, other: string, lookFor: string): nu } export function compareByPrefix(one: string, other: string, lookFor: string): number { - let elementAName = one.toLowerCase(); - let elementBName = other.toLowerCase(); + const elementAName = one.toLowerCase(); + const elementBName = other.toLowerCase(); // Sort prefix matches over non prefix matches - let elementAPrefixMatch = strings.startsWith(elementAName, lookFor); - let elementBPrefixMatch = strings.startsWith(elementBName, lookFor); + const elementAPrefixMatch = strings.startsWith(elementAName, lookFor); + const elementBPrefixMatch = strings.startsWith(elementBName, lookFor); if (elementAPrefixMatch !== elementBPrefixMatch) { return elementAPrefixMatch ? -1 : 1; } diff --git a/src/vs/base/common/errors.ts b/src/vs/base/common/errors.ts index 15e2eb22b8b..da6f814332f 100644 --- a/src/vs/base/common/errors.ts +++ b/src/vs/base/common/errors.ts @@ -102,7 +102,7 @@ export function transformErrorForSerialization(error: any): any; export function transformErrorForSerialization(error: any): any { if (error instanceof Error) { let { name, message } = error; - let stack: string = (error).stacktrace || (error).stack; + const stack: string = (error).stacktrace || (error).stack; return { $isError: true, name, @@ -146,7 +146,7 @@ export function isPromiseCanceledError(error: any): boolean { * Returns an error that signals cancellation. */ export function canceled(): Error { - let error = new Error(canceledName); + const error = new Error(canceledName); error.name = error.message; return error; } diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 1a5596aa6b7..159c6e708d9 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -152,7 +152,7 @@ export namespace Event { clearTimeout(handle); handle = setTimeout(() => { - let _output = output; + const _output = output; output = undefined; handle = undefined; if (!leading || numDebouncedCalls > 1) { @@ -190,7 +190,7 @@ export namespace Event { let cache: T; return filter(event, value => { - let shouldEmit = firstCall || value !== cache; + const shouldEmit = firstCall || value !== cache; firstCall = false; cache = value; return shouldEmit; @@ -389,7 +389,7 @@ export interface EmitterOptions { let _globalLeakWarningThreshold = -1; export function setGlobalLeakWarningThreshold(n: number): IDisposable { - let oldValue = _globalLeakWarningThreshold; + const oldValue = _globalLeakWarningThreshold; _globalLeakWarningThreshold = n; return { dispose() { @@ -428,8 +428,8 @@ class LeakageMonitor { if (!this._stacks) { this._stacks = new Map(); } - let stack = new Error().stack!.split('\n').slice(3).join('\n'); - let count = (this._stacks.get(stack) || 0); + const stack = new Error().stack!.split('\n').slice(3).join('\n'); + const count = (this._stacks.get(stack) || 0); this._stacks.set(stack, count + 1); this._warnCountdown -= 1; @@ -453,7 +453,7 @@ class LeakageMonitor { } return () => { - let count = (this._stacks!.get(stack) || 0); + const count = (this._stacks!.get(stack) || 0); this._stacks!.set(stack, count - 1); }; } @@ -627,7 +627,7 @@ export class AsyncEmitter extends Emitter { } for (let iter = this._listeners.iterator(), e = iter.next(); !e.done; e = iter.next()) { - let thenables: Promise[] = []; + const thenables: Promise[] = []; this._asyncDeliveryQueue.push([e.value, eventFn(thenables, typeof e.value === 'function' ? e.value : e.value[0]), thenables]); } diff --git a/src/vs/base/common/extpath.ts b/src/vs/base/common/extpath.ts index ab554f756bf..984a1c8afd1 100644 --- a/src/vs/base/common/extpath.ts +++ b/src/vs/base/common/extpath.ts @@ -32,7 +32,7 @@ export function getRoot(path: string, sep: string = posix.sep): string { return ''; } - let len = path.length; + const len = path.length; const firstLetter = path.charCodeAt(0); if (isPathSeparator(firstLetter)) { if (isPathSeparator(path.charCodeAt(1))) { @@ -40,7 +40,7 @@ export function getRoot(path: string, sep: string = posix.sep): string { // ^^^^^^^^^^^^^^^^^^^ if (!isPathSeparator(path.charCodeAt(2))) { let pos = 3; - let start = pos; + const start = pos; for (; pos < len; pos++) { if (isPathSeparator(path.charCodeAt(pos))) { break; @@ -121,7 +121,7 @@ export function isUNC(path: string): boolean { return false; } let pos = 2; - let start = pos; + const start = pos; for (; pos < path.length; pos++) { code = path.charCodeAt(pos); if (code === CharCode.Backslash) { diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index e7674b93648..ef1df908741 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -28,7 +28,7 @@ export interface IMatch { export function or(...filter: IFilter[]): IFilter { return function (word: string, wordToMatchAgainst: string): IMatch[] | null { for (let i = 0, len = filter.length; i < len; i++) { - let match = filter[i](word, wordToMatchAgainst); + const match = filter[i](word, wordToMatchAgainst); if (match) { return match; } @@ -64,7 +64,7 @@ function _matchesPrefix(ignoreCase: boolean, word: string, wordToMatchAgainst: s // Contiguous Substring export function matchesContiguousSubString(word: string, wordToMatchAgainst: string): IMatch[] | null { - let index = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); + const index = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); if (index === -1) { return null; } @@ -136,7 +136,7 @@ function join(head: IMatch, tail: IMatch[]): IMatch[] { function nextAnchor(camelCaseWord: string, start: number): number { for (let i = start; i < camelCaseWord.length; i++) { - let c = camelCaseWord.charCodeAt(i); + const c = camelCaseWord.charCodeAt(i); if (isUpper(c) || isNumber(c) || (i > 0 && !isAlphanumeric(camelCaseWord.charCodeAt(i - 1)))) { return i; } @@ -184,10 +184,10 @@ function analyzeCamelCaseWord(word: string): ICamelCaseAnalysis { if (isNumber(code)) { numeric++; } } - let upperPercent = upper / word.length; - let lowerPercent = lower / word.length; - let alphaPercent = alpha / word.length; - let numericPercent = numeric / word.length; + const upperPercent = upper / word.length; + const lowerPercent = lower / word.length; + const alphaPercent = alpha / word.length; + const numericPercent = numeric / word.length; return { upperPercent, lowerPercent, alphaPercent, numericPercent }; } @@ -307,7 +307,7 @@ function _matchesWords(word: string, target: string, i: number, j: number, conti function nextWord(word: string, start: number): number { for (let i = start; i < word.length; i++) { - let c = word.charCodeAt(i); + const c = word.charCodeAt(i); if (isWhitespace(c) || (i > 0 && isWhitespace(word.charCodeAt(i - 1)))) { return i; } @@ -334,7 +334,7 @@ export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSep } // RegExp Filter - let match = regexp.exec(wordToMatchAgainst); + const match = regexp.exec(wordToMatchAgainst); if (match) { return [{ start: match.index, end: match.index + match[0].length }]; } @@ -348,7 +348,7 @@ export function matchesFuzzy(word: string, wordToMatchAgainst: string, enableSep * powerfull than `matchesFuzzy` */ export function matchesFuzzy2(pattern: string, word: string): IMatch[] | null { - let score = fuzzyScore(pattern, pattern.toLowerCase(), 0, word, word.toLowerCase(), 0, true); + const score = fuzzyScore(pattern, pattern.toLowerCase(), 0, word, word.toLowerCase(), 0, true); return score ? createMatches(score) : null; } @@ -404,7 +404,7 @@ function initTable() { row.push(-i); } for (let i = 0; i <= _maxLen; i++) { - let thisRow = row.slice(0); + const thisRow = row.slice(0); thisRow[0] = -i; table.push(thisRow); } @@ -566,9 +566,9 @@ export function fuzzyScore(pattern: string, patternLow: string, patternPos: numb _scores[patternPos][wordPos] = score; - let diag = _table[patternPos - 1][wordPos - 1] + (score > 1 ? 1 : score); - let top = _table[patternPos - 1][wordPos] + -1; - let left = _table[patternPos][wordPos - 1] + -1; + const diag = _table[patternPos - 1][wordPos - 1] + (score > 1 ? 1 : score); + const top = _table[patternPos - 1][wordPos] + -1; + const left = _table[patternPos][wordPos - 1] + -1; if (left >= top) { // left or diag @@ -635,8 +635,8 @@ function _findAllMatches2(patternPos: number, wordPos: number, total: number, ma while (patternPos > _patternStartPos && wordPos > 0) { - let score = _scores[patternPos][wordPos]; - let arrow = _arrows[patternPos][wordPos]; + const score = _scores[patternPos][wordPos]; + const arrow = _arrows[patternPos][wordPos]; if (arrow === Arrow.Left) { // left -> no match, skip a word character @@ -733,11 +733,11 @@ function fuzzyScoreWithPermutations(pattern: string, lowPattern: string, pattern // permutations of the pattern to find a better match. The // permutations only swap neighbouring characters, e.g // `cnoso` becomes `conso`, `cnsoo`, `cnoos`. - let tries = Math.min(7, pattern.length - 1); + const tries = Math.min(7, pattern.length - 1); for (let movingPatternPos = patternPos + 1; movingPatternPos < tries; movingPatternPos++) { - let newPattern = nextTypoPermutation(pattern, movingPatternPos); + const newPattern = nextTypoPermutation(pattern, movingPatternPos); if (newPattern) { - let candidate = fuzzyScore(newPattern, newPattern.toLowerCase(), patternPos, word, lowWord, wordPos, firstMatchCanBeWeak); + const candidate = fuzzyScore(newPattern, newPattern.toLowerCase(), patternPos, word, lowWord, wordPos, firstMatchCanBeWeak); if (candidate) { candidate[0] -= 3; // permutation penalty if (!top || candidate[0] > top[0]) { @@ -757,8 +757,8 @@ function nextTypoPermutation(pattern: string, patternPos: number): string | unde return undefined; } - let swap1 = pattern[patternPos]; - let swap2 = pattern[patternPos + 1]; + const swap1 = pattern[patternPos]; + const swap2 = pattern[patternPos + 1]; if (swap1 === swap2) { return undefined; diff --git a/src/vs/base/common/glob.ts b/src/vs/base/common/glob.ts index a7569150a48..0cecf47d7d4 100644 --- a/src/vs/base/common/glob.ts +++ b/src/vs/base/common/glob.ts @@ -53,7 +53,7 @@ export function splitGlobAware(pattern: string, splitChar: string): string[] { return []; } - let segments: string[] = []; + const segments: string[] = []; let inBraces = false; let inBrackets = false; @@ -102,7 +102,7 @@ function parseRegExp(pattern: string): string { let regEx = ''; // Split up into segments for each slash found - let segments = splitGlobAware(pattern, GLOB_SPLIT); + const segments = splitGlobAware(pattern, GLOB_SPLIT); // Special case where we only have globstars if (segments.every(s => s === GLOBSTAR)) { @@ -179,10 +179,10 @@ function parseRegExp(pattern: string): string { continue; case '}': - let choices = splitGlobAware(braceVal, ','); + const choices = splitGlobAware(braceVal, ','); // Converts {foo,bar} => [foo|bar] - let braceRegExp = `(?:${choices.map(c => parseRegExp(c)).join('|')})`; + const braceRegExp = `(?:${choices.map(c => parseRegExp(c)).join('|')})`; regEx += braceRegExp; diff --git a/src/vs/base/common/history.ts b/src/vs/base/common/history.ts index 95551eb1a7a..19dada92a3e 100644 --- a/src/vs/base/common/history.ts +++ b/src/vs/base/common/history.ts @@ -66,7 +66,7 @@ export class HistoryNavigator implements INavigator { } private _reduceToLimit() { - let data = this._elements; + const data = this._elements; if (data.length > this._limit) { this._initialize(data.slice(data.length - this._limit)); } diff --git a/src/vs/base/common/json.ts b/src/vs/base/common/json.ts index e0cf131ad89..b3a62ede9ff 100644 --- a/src/vs/base/common/json.ts +++ b/src/vs/base/common/json.ts @@ -209,7 +209,7 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON let digits = 0; let value = 0; while (digits < count) { - let ch = text.charCodeAt(pos); + const ch = text.charCodeAt(pos); if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) { value = value * 16 + ch - CharacterCodes._0; } @@ -240,7 +240,7 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON } function scanNumber(): string { - let start = pos; + const start = pos; if (text.charCodeAt(pos) === CharacterCodes._0) { pos++; } else { @@ -331,7 +331,7 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON result += '\t'; break; case CharacterCodes.u: - let ch = scanHexDigits(4); + const ch = scanHexDigits(4); if (ch >= 0) { result += String.fromCharCode(ch); } else { @@ -424,7 +424,7 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON // comments case CharacterCodes.slash: - let start = pos - 1; + const start = pos - 1; // Single-line comment if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { pos += 2; @@ -444,10 +444,10 @@ export function createScanner(text: string, ignoreTrivia: boolean = false): JSON if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { pos += 2; - let safeLength = len - 1; // For lookahead. + const safeLength = len - 1; // For lookahead. let commentClosed = false; while (pos < safeLength) { - let ch = text.charCodeAt(pos); + const ch = text.charCodeAt(pos); if (ch === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { pos += 2; @@ -720,8 +720,8 @@ interface NodeImpl extends Node { * For a given offset, evaluate the location in the JSON document. Each segment in the location path is either a property name or an array index. */ export function getLocation(text: string, position: number): Location { - let segments: Segment[] = []; // strings or numbers - let earlyReturnException = new Object(); + const segments: Segment[] = []; // strings or numbers + const earlyReturnException = new Object(); let previousNode: NodeImpl | undefined = undefined; const previousNodeInst: NodeImpl = { value: {}, @@ -800,7 +800,7 @@ export function getLocation(text: string, position: number): Location { isAtPropertyKey = false; previousNode = undefined; } else if (sep === ',') { - let last = segments[segments.length - 1]; + const last = segments[segments.length - 1]; if (typeof last === 'number') { segments[segments.length - 1] = last + 1; } else { @@ -843,7 +843,7 @@ export function getLocation(text: string, position: number): Location { export function parse(text: string, errors: ParseError[] = [], options: ParseOptions = ParseOptions.DEFAULT): any { let currentProperty: string | null = null; let currentParent: any = []; - let previousParents: any[] = []; + const previousParents: any[] = []; function onValue(value: any) { if (Array.isArray(currentParent)) { @@ -853,9 +853,9 @@ export function parse(text: string, errors: ParseError[] = [], options: ParseOpt } } - let visitor: JSONVisitor = { + const visitor: JSONVisitor = { onObjectBegin: () => { - let object = {}; + const object = {}; onValue(object); previousParents.push(currentParent); currentParent = object; @@ -868,7 +868,7 @@ export function parse(text: string, errors: ParseError[] = [], options: ParseOpt currentParent = previousParents.pop(); }, onArrayBegin: () => { - let array: any[] = []; + const array: any[] = []; onValue(array); previousParents.push(currentParent); currentParent = array; @@ -905,7 +905,7 @@ export function parseTree(text: string, errors: ParseError[] = [], options: Pars return valueNode; } - let visitor: JSONVisitor = { + const visitor: JSONVisitor = { onObjectBegin: (offset: number) => { currentParent = onValue({ type: 'object', offset, length: -1, parent: currentParent, children: [] }); }, @@ -945,7 +945,7 @@ export function parseTree(text: string, errors: ParseError[] = [], options: Pars }; visit(text, visitor, options); - let result = currentParent.children![0]; + const result = currentParent.children![0]; if (result) { delete result.parent; } @@ -977,7 +977,7 @@ export function findNodeAtLocation(root: Node, path: JSONPath): Node | undefined return undefined; } } else { - let index = segment; + const index = segment; if (node.type !== 'array' || index < 0 || !Array.isArray(node.children) || index >= node.children.length) { return undefined; } @@ -994,12 +994,12 @@ export function getNodePath(node: Node): JSONPath { if (!node.parent || !node.parent.children) { return []; } - let path = getNodePath(node.parent); + const path = getNodePath(node.parent); if (node.parent.type === 'property') { - let key = node.parent.children[0].value; + const key = node.parent.children[0].value; path.push(key); } else if (node.parent.type === 'array') { - let index = node.parent.children.indexOf(node); + const index = node.parent.children.indexOf(node); if (index !== -1) { path.push(index); } @@ -1015,9 +1015,9 @@ export function getNodeValue(node: Node): any { case 'array': return node.children!.map(getNodeValue); case 'object': - let obj = Object.create(null); + const obj = Object.create(null); for (let prop of node.children!) { - let valueNode = prop.children![1]; + const valueNode = prop.children![1]; if (valueNode) { obj[prop.children![0].value] = getNodeValue(valueNode); } @@ -1043,10 +1043,10 @@ export function contains(node: Node, offset: number, includeRightBound = false): */ export function findNodeAtOffset(node: Node, offset: number, includeRightBound = false): Node | undefined { if (contains(node, offset, includeRightBound)) { - let children = node.children; + const children = node.children; if (Array.isArray(children)) { for (let i = 0; i < children.length && children[i].offset <= offset; i++) { - let item = findNodeAtOffset(children[i], offset, includeRightBound); + const item = findNodeAtOffset(children[i], offset, includeRightBound); if (item) { return item; } @@ -1064,7 +1064,7 @@ export function findNodeAtOffset(node: Node, offset: number, includeRightBound = */ export function visit(text: string, visitor: JSONVisitor, options: ParseOptions = ParseOptions.DEFAULT): any { - let _scanner = createScanner(text, false); + const _scanner = createScanner(text, false); function toNoArgVisit(visitFunction?: (offset: number, length: number) => void): () => void { return visitFunction ? () => visitFunction(_scanner.getTokenOffset(), _scanner.getTokenLength()) : () => true; @@ -1073,7 +1073,7 @@ export function visit(text: string, visitor: JSONVisitor, options: ParseOptions return visitFunction ? (arg: T) => visitFunction(arg, _scanner.getTokenOffset(), _scanner.getTokenLength()) : () => true; } - let onObjectBegin = toNoArgVisit(visitor.onObjectBegin), + const onObjectBegin = toNoArgVisit(visitor.onObjectBegin), onObjectProperty = toOneArgVisit(visitor.onObjectProperty), onObjectEnd = toNoArgVisit(visitor.onObjectEnd), onArrayBegin = toNoArgVisit(visitor.onArrayBegin), @@ -1083,11 +1083,11 @@ export function visit(text: string, visitor: JSONVisitor, options: ParseOptions onComment = toNoArgVisit(visitor.onComment), onError = toOneArgVisit(visitor.onError); - let disallowComments = options && options.disallowComments; - let allowTrailingComma = options && options.allowTrailingComma; + const disallowComments = options && options.disallowComments; + const allowTrailingComma = options && options.allowTrailingComma; function scanNext(): SyntaxKind { while (true) { - let token = _scanner.scan(); + const token = _scanner.scan(); switch (_scanner.getTokenError()) { case ScanError.InvalidUnicode: handleError(ParseErrorCode.InvalidUnicode); @@ -1148,7 +1148,7 @@ export function visit(text: string, visitor: JSONVisitor, options: ParseOptions } function parseString(isValue: boolean): boolean { - let value = _scanner.getTokenValue(); + const value = _scanner.getTokenValue(); if (isValue) { onLiteralValue(value); } else { diff --git a/src/vs/base/common/jsonEdit.ts b/src/vs/base/common/jsonEdit.ts index 7675ea16049..4a99bee9acd 100644 --- a/src/vs/base/common/jsonEdit.ts +++ b/src/vs/base/common/jsonEdit.ts @@ -12,9 +12,9 @@ export function removeProperty(text: string, path: JSONPath, formattingOptions: } export function setProperty(text: string, originalPath: JSONPath, value: any, formattingOptions: FormattingOptions, getInsertionIndex?: (properties: string[]) => number): Edit[] { - let path = originalPath.slice(); - let errors: ParseError[] = []; - let root = parseTree(text, errors); + const path = originalPath.slice(); + const errors: ParseError[] = []; + const root = parseTree(text, errors); let parent: Node | undefined = undefined; let lastSegment: Segment | undefined = undefined; @@ -39,24 +39,24 @@ export function setProperty(text: string, originalPath: JSONPath, value: any, fo } return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions); } else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) { - let existing = findNodeAtLocation(parent, [lastSegment]); + const existing = findNodeAtLocation(parent, [lastSegment]); if (existing !== undefined) { if (value === undefined) { // delete if (!existing.parent) { throw new Error('Malformed AST'); } - let propertyIndex = parent.children.indexOf(existing.parent); + const propertyIndex = parent.children.indexOf(existing.parent); let removeBegin: number; let removeEnd = existing.parent.offset + existing.parent.length; if (propertyIndex > 0) { // remove the comma of the previous node - let previous = parent.children[propertyIndex - 1]; + const previous = parent.children[propertyIndex - 1]; removeBegin = previous.offset + previous.length; } else { removeBegin = parent.offset + 1; if (parent.children.length > 1) { // remove the comma of the next node - let next = parent.children[1]; + const next = parent.children[1]; removeEnd = next.offset; } } @@ -69,11 +69,11 @@ export function setProperty(text: string, originalPath: JSONPath, value: any, fo if (value === undefined) { // delete return []; // property does not exist, nothing to do } - let newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`; - let index = getInsertionIndex ? getInsertionIndex(parent.children.map(p => p.children![0].value)) : parent.children.length; + const newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`; + const index = getInsertionIndex ? getInsertionIndex(parent.children.map(p => p.children![0].value)) : parent.children.length; let edit: Edit; if (index > 0) { - let previous = parent.children[index - 1]; + const previous = parent.children[index - 1]; edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty }; } else if (parent.children.length === 0) { edit = { offset: parent.offset + 1, length: 0, content: newProperty }; @@ -83,32 +83,32 @@ export function setProperty(text: string, originalPath: JSONPath, value: any, fo return withFormatting(text, edit, formattingOptions); } } else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) { - let insertIndex = lastSegment; + const insertIndex = lastSegment; if (insertIndex === -1) { // Insert - let newProperty = `${JSON.stringify(value)}`; + const newProperty = `${JSON.stringify(value)}`; let edit: Edit; if (parent.children.length === 0) { edit = { offset: parent.offset + 1, length: 0, content: newProperty }; } else { - let previous = parent.children[parent.children.length - 1]; + const previous = parent.children[parent.children.length - 1]; edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty }; } return withFormatting(text, edit, formattingOptions); } else { if (value === undefined && parent.children.length >= 0) { //Removal - let removalIndex = lastSegment; - let toRemove = parent.children[removalIndex]; + const removalIndex = lastSegment; + const toRemove = parent.children[removalIndex]; let edit: Edit; if (parent.children.length === 1) { // only item edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' }; } else if (parent.children.length - 1 === removalIndex) { // last item - let previous = parent.children[removalIndex - 1]; - let offset = previous.offset + previous.length; - let parentEndOffset = parent.offset + parent.length; + const previous = parent.children[removalIndex - 1]; + const offset = previous.offset + previous.length; + const parentEndOffset = parent.offset + parent.length; edit = { offset, length: parentEndOffset - 2 - offset, content: '' }; } else { edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' }; @@ -139,18 +139,18 @@ function withFormatting(text: string, edit: Edit, formattingOptions: FormattingO } } - let edits = format(newText, { offset: begin, length: end - begin }, formattingOptions); + const edits = format(newText, { offset: begin, length: end - begin }, formattingOptions); // apply the formatting edits and track the begin and end offsets of the changes for (let i = edits.length - 1; i >= 0; i--) { - let edit = edits[i]; + const edit = edits[i]; newText = applyEdit(newText, edit); begin = Math.min(begin, edit.offset); end = Math.max(end, edit.offset + edit.length); end += edit.content.length - edit.length; } // create a single edit with all changes - let editLength = text.length - (newText.length - end) - begin; + const editLength = text.length - (newText.length - end) - begin; return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }]; } diff --git a/src/vs/base/common/jsonFormatter.ts b/src/vs/base/common/jsonFormatter.ts index df2a97ee5cd..a25c493c05d 100644 --- a/src/vs/base/common/jsonFormatter.ts +++ b/src/vs/base/common/jsonFormatter.ts @@ -80,7 +80,7 @@ export function format(documentText: string, range: Range | undefined, options: rangeStart = 0; rangeEnd = documentText.length; } - let eol = getEOL(options, documentText); + const eol = getEOL(options, documentText); let lineBreak = false; let indentLevel = 0; @@ -91,7 +91,7 @@ export function format(documentText: string, range: Range | undefined, options: indentValue = '\t'; } - let scanner = createScanner(formatText, false); + const scanner = createScanner(formatText, false); let hasError = false; function newLineAndIndent(): string { @@ -107,7 +107,7 @@ export function format(documentText: string, range: Range | undefined, options: hasError = token === SyntaxKind.Unknown || scanner.getTokenError() !== ScanError.None; return token; } - let editOperations: Edit[] = []; + const editOperations: Edit[] = []; function addEdit(text: string, startOffset: number, endOffset: number) { if (!hasError && startOffset < rangeEnd && endOffset > rangeStart && documentText.substring(startOffset, endOffset) !== text) { editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text }); @@ -117,8 +117,8 @@ export function format(documentText: string, range: Range | undefined, options: let firstToken = scanNext(); if (firstToken !== SyntaxKind.EOF) { - let firstTokenStart = scanner.getTokenOffset() + formatTextStart; - let initialIndent = repeat(indentValue, initialIndentLevel); + const firstTokenStart = scanner.getTokenOffset() + formatTextStart; + const initialIndent = repeat(indentValue, initialIndentLevel); addEdit(initialIndent, formatTextStart, firstTokenStart); } @@ -129,7 +129,7 @@ export function format(documentText: string, range: Range | undefined, options: let replaceContent = ''; while (!lineBreak && (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia)) { // comments on the same line: keep them on the same line, but ignore them otherwise - let commentTokenStart = scanner.getTokenOffset() + formatTextStart; + const commentTokenStart = scanner.getTokenOffset() + formatTextStart; addEdit(' ', firstTokenEnd, commentTokenStart); firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart; replaceContent = secondToken === SyntaxKind.LineCommentTrivia ? newLineAndIndent() : ''; @@ -195,7 +195,7 @@ export function format(documentText: string, range: Range | undefined, options: } } - let secondTokenStart = scanner.getTokenOffset() + formatTextStart; + const secondTokenStart = scanner.getTokenOffset() + formatTextStart; addEdit(replaceContent, firstTokenEnd, secondTokenStart); firstToken = secondToken; } @@ -213,9 +213,9 @@ function repeat(s: string, count: number): string { function computeIndentLevel(content: string, options: FormattingOptions): number { let i = 0; let nChars = 0; - let tabSize = options.tabSize || 4; + const tabSize = options.tabSize || 4; while (i < content.length) { - let ch = content.charAt(i); + const ch = content.charAt(i); if (ch === ' ') { nChars++; } else if (ch === '\t') { @@ -230,7 +230,7 @@ function computeIndentLevel(content: string, options: FormattingOptions): number function getEOL(options: FormattingOptions, text: string): string { for (let i = 0; i < text.length; i++) { - let ch = text.charAt(i); + const ch = text.charAt(i); if (ch === '\r') { if (i + 1 < text.length && text.charAt(i + 1) === '\n') { return '\r\n'; diff --git a/src/vs/base/common/keyCodes.ts b/src/vs/base/common/keyCodes.ts index b2d75920a4c..ec08bea7e91 100644 --- a/src/vs/base/common/keyCodes.ts +++ b/src/vs/base/common/keyCodes.ts @@ -407,7 +407,7 @@ export const enum KeyMod { } export function KeyChord(firstPart: number, secondPart: number): number { - let chordPart = ((secondPart & 0x0000FFFF) << 16) >>> 0; + const chordPart = ((secondPart & 0x0000FFFF) << 16) >>> 0; return (firstPart | chordPart) >>> 0; } @@ -466,10 +466,10 @@ export class SimpleKeybinding { } public getHashCode(): string { - let ctrl = this.ctrlKey ? '1' : '0'; - let shift = this.shiftKey ? '1' : '0'; - let alt = this.altKey ? '1' : '0'; - let meta = this.metaKey ? '1' : '0'; + const ctrl = this.ctrlKey ? '1' : '0'; + const shift = this.shiftKey ? '1' : '0'; + const alt = this.altKey ? '1' : '0'; + const meta = this.metaKey ? '1' : '0'; return `${ctrl}${shift}${alt}${meta}${this.keyCode}`; } diff --git a/src/vs/base/common/keybindingLabels.ts b/src/vs/base/common/keybindingLabels.ts index a1df76ab4fb..671816830bd 100644 --- a/src/vs/base/common/keybindingLabels.ts +++ b/src/vs/base/common/keybindingLabels.ts @@ -41,7 +41,7 @@ export class ModifierLabelProvider { return null; } - let result: string[] = []; + const result: string[] = []; for (let i = 0, len = parts.length; i < len; i++) { const part = parts[i]; const keyLabel = keyLabelProvider(part); @@ -162,7 +162,7 @@ function _simpleAsString(modifiers: Modifiers, key: string, labels: ModifierLabe return ''; } - let result: string[] = []; + const result: string[] = []; // translate modifier keys: Ctrl-Shift-Alt-Meta if (modifiers.ctrlKey) { diff --git a/src/vs/base/common/keybindingParser.ts b/src/vs/base/common/keybindingParser.ts index 68025d9131b..f7e120acc53 100644 --- a/src/vs/base/common/keybindingParser.ts +++ b/src/vs/base/common/keybindingParser.ts @@ -85,7 +85,7 @@ export class KeybindingParser { return null; } - let parts: SimpleKeybinding[] = []; + const parts: SimpleKeybinding[] = []; let part: SimpleKeybinding; do { @@ -112,7 +112,7 @@ export class KeybindingParser { return []; } - let parts: (SimpleKeybinding | ScanCodeBinding)[] = []; + const parts: (SimpleKeybinding | ScanCodeBinding)[] = []; let part: SimpleKeybinding | ScanCodeBinding; while (input.length > 0) { diff --git a/src/vs/base/common/linkedList.ts b/src/vs/base/common/linkedList.ts index 5673ae64808..0eb16c2faa3 100644 --- a/src/vs/base/common/linkedList.ts +++ b/src/vs/base/common/linkedList.ts @@ -97,7 +97,7 @@ export class LinkedList { } if (candidate.prev && candidate.next) { // middle - let anchor = candidate.prev; + const anchor = candidate.prev; anchor.next = candidate.next; candidate.next.prev = anchor; @@ -144,7 +144,7 @@ export class LinkedList { } toArray(): E[] { - let result: E[] = []; + const result: E[] = []; for (let node = this._first; node instanceof Node; node = node.next) { result.push(node.element); } diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index c1ed1d4aa4a..5320086b024 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -100,8 +100,8 @@ export class StringIterator implements IKeyIterator { } cmp(a: string): number { - let aCode = a.charCodeAt(0); - let thisCode = this._value.charCodeAt(this._pos); + const aCode = a.charCodeAt(0); + const thisCode = this._value.charCodeAt(this._pos); return aCode - thisCode; } @@ -149,11 +149,11 @@ export class PathIterator implements IKeyIterator { cmp(a: string): number { let aPos = 0; - let aLen = a.length; + const aLen = a.length; let thisPos = this._from; while (aPos < aLen && thisPos < this._to) { - let cmp = a.charCodeAt(aPos) - this._value.charCodeAt(thisPos); + const cmp = a.charCodeAt(aPos) - this._value.charCodeAt(thisPos); if (cmp !== 0) { return cmp; } @@ -210,7 +210,7 @@ export class TernarySearchTree { } set(key: string, element: E): E | undefined { - let iter = this._iter.reset(key); + const iter = this._iter.reset(key); let node: TernarySearchTreeNode; if (!this._root) { @@ -220,7 +220,7 @@ export class TernarySearchTree { node = this._root; while (true) { - let val = iter.cmp(node.segment); + const val = iter.cmp(node.segment); if (val > 0) { // left if (!node.left) { @@ -256,10 +256,10 @@ export class TernarySearchTree { } get(key: string): E | undefined { - let iter = this._iter.reset(key); + const iter = this._iter.reset(key); let node = this._root; while (node) { - let val = iter.cmp(node.segment); + const val = iter.cmp(node.segment); if (val > 0) { // left node = node.left; @@ -279,13 +279,13 @@ export class TernarySearchTree { delete(key: string): void { - let iter = this._iter.reset(key); - let stack: [-1 | 0 | 1, TernarySearchTreeNode][] = []; + const iter = this._iter.reset(key); + const stack: [-1 | 0 | 1, TernarySearchTreeNode][] = []; let node = this._root; // find and unset node while (node) { - let val = iter.cmp(node.segment); + const val = iter.cmp(node.segment); if (val > 0) { // left stack.push([1, node]); @@ -319,11 +319,11 @@ export class TernarySearchTree { } findSubstr(key: string): E | undefined { - let iter = this._iter.reset(key); + const iter = this._iter.reset(key); let node = this._root; let candidate: E | undefined = undefined; while (node) { - let val = iter.cmp(node.segment); + const val = iter.cmp(node.segment); if (val > 0) { // left node = node.left; @@ -343,10 +343,10 @@ export class TernarySearchTree { } findSuperstr(key: string): Iterator | undefined { - let iter = this._iter.reset(key); + const iter = this._iter.reset(key); let node = this._root; while (node) { - let val = iter.cmp(node.segment); + const val = iter.cmp(node.segment); if (val > 0) { // left node = node.left; @@ -373,7 +373,7 @@ export class TernarySearchTree { let res: { done: false; value: E; }; let idx: number; let data: E[]; - let next = (): IteratorResult => { + const next = (): IteratorResult => { if (!data) { // lazy till first invocation data = []; @@ -610,7 +610,7 @@ export class LinkedMap { } values(): V[] { - let result: V[] = []; + const result: V[] = []; let current = this._head; while (current) { result.push(current.value); @@ -620,7 +620,7 @@ export class LinkedMap { } keys(): K[] { - let result: K[] = []; + const result: K[] = []; let current = this._head; while (current) { result.push(current.key); @@ -631,14 +631,14 @@ export class LinkedMap { /* VS Code / Monaco editor runs on es5 which has no Symbol.iterator keys(): IterableIterator { - let current = this._head; - let iterator: IterableIterator = { + const current = this._head; + const iterator: IterableIterator = { [Symbol.iterator]() { return iterator; }, next():IteratorResult { if (current) { - let result = { value: current.key, done: false }; + const result = { value: current.key, done: false }; current = current.next; return result; } else { @@ -650,14 +650,14 @@ export class LinkedMap { } values(): IterableIterator { - let current = this._head; - let iterator: IterableIterator = { + const current = this._head; + const iterator: IterableIterator = { [Symbol.iterator]() { return iterator; }, next():IteratorResult { if (current) { - let result = { value: current.value, done: false }; + const result = { value: current.value, done: false }; current = current.next; return result; } else { diff --git a/src/vs/base/common/objects.ts b/src/vs/base/common/objects.ts index ef5e8b59de4..34e9a7862c9 100644 --- a/src/vs/base/common/objects.ts +++ b/src/vs/base/common/objects.ts @@ -30,11 +30,11 @@ export function deepFreeze(obj: T): T { } const stack: any[] = [obj]; while (stack.length > 0) { - let obj = stack.shift(); + const obj = stack.shift(); Object.freeze(obj); for (const key in obj) { if (_hasOwnProperty.call(obj, key)) { - let prop = obj[key]; + const prop = obj[key]; if (typeof prop === 'object' && !Object.isFrozen(prop)) { stack.push(prop); } diff --git a/src/vs/base/common/parsers.ts b/src/vs/base/common/parsers.ts index da9010662fa..4ea4e95373d 100644 --- a/src/vs/base/common/parsers.ts +++ b/src/vs/base/common/parsers.ts @@ -81,8 +81,8 @@ export abstract class Parser { protected static merge(destination: T, source: T, overwrite: boolean): void { Object.keys(source).forEach((key: string) => { - let destValue = destination[key]; - let sourceValue = source[key]; + const destValue = destination[key]; + const sourceValue = source[key]; if (Types.isUndefined(sourceValue)) { return; } diff --git a/src/vs/base/common/path.ts b/src/vs/base/common/path.ts index 844cdd246a9..640c033ae01 100644 --- a/src/vs/base/common/path.ts +++ b/src/vs/base/common/path.ts @@ -231,7 +231,7 @@ export const win32: IPath = { continue; } - let len = path.length; + const len = path.length; let rootEnd = 0; let device = ''; let isAbsolute = false; @@ -503,7 +503,7 @@ export const win32: IPath = { let joined; let firstPart; for (let i = 0; i < paths.length; ++i) { - let arg = paths[i]; + const arg = paths[i]; validateString(arg, 'path'); if (arg.length > 0) { if (joined === undefined) { @@ -582,8 +582,8 @@ export const win32: IPath = { return ''; } - let fromOrig = win32.resolve(from); - let toOrig = win32.resolve(to); + const fromOrig = win32.resolve(from); + const toOrig = win32.resolve(to); if (fromOrig === toOrig) { return ''; @@ -610,7 +610,7 @@ export const win32: IPath = { break; } } - let fromLen = (fromEnd - fromStart); + const fromLen = (fromEnd - fromStart); // Trim any leading backslashes let toStart = 0; @@ -626,10 +626,10 @@ export const win32: IPath = { break; } } - let toLen = (toEnd - toStart); + const toLen = (toEnd - toStart); // Compare paths to find the longest common path from root - let length = (fromLen < toLen ? fromLen : toLen); + const length = (fromLen < toLen ? fromLen : toLen); let lastCommonSep = -1; let i = 0; for (; i <= length; ++i) { @@ -658,8 +658,8 @@ export const win32: IPath = { } break; } - let fromCode = from.charCodeAt(fromStart + i); - let toCode = to.charCodeAt(toStart + i); + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) { break; } @@ -1015,12 +1015,12 @@ export const win32: IPath = { parse(path) { validateString(path, 'path'); - let ret = { root: '', dir: '', base: '', ext: '', name: '' }; + const ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) { return ret; } - let len = path.length; + const len = path.length; let rootEnd = 0; let code = path.charCodeAt(0); @@ -1268,7 +1268,7 @@ export const posix: IPath = { } let joined; for (let i = 0; i < paths.length; ++i) { - let arg = arguments[i]; + const arg = arguments[i]; validateString(arg, 'path'); if (arg.length > 0) { if (joined === undefined) { @@ -1307,8 +1307,8 @@ export const posix: IPath = { break; } } - let fromEnd = from.length; - let fromLen = (fromEnd - fromStart); + const fromEnd = from.length; + const fromLen = (fromEnd - fromStart); // Trim any leading backslashes let toStart = 1; @@ -1317,11 +1317,11 @@ export const posix: IPath = { break; } } - let toEnd = to.length; - let toLen = (toEnd - toStart); + const toEnd = to.length; + const toLen = (toEnd - toStart); // Compare paths to find the longest common path from root - let length = (fromLen < toLen ? fromLen : toLen); + const length = (fromLen < toLen ? fromLen : toLen); let lastCommonSep = -1; let i = 0; for (; i <= length; ++i) { @@ -1349,8 +1349,8 @@ export const posix: IPath = { } break; } - let fromCode = from.charCodeAt(fromStart + i); - let toCode = to.charCodeAt(toStart + i); + const fromCode = from.charCodeAt(fromStart + i); + const toCode = to.charCodeAt(toStart + i); if (fromCode !== toCode) { break; } @@ -1568,11 +1568,11 @@ export const posix: IPath = { parse(path: string): ParsedPath { validateString(path, 'path'); - let ret = { root: '', dir: '', base: '', ext: '', name: '' }; + const ret = { root: '', dir: '', base: '', ext: '', name: '' }; if (path.length === 0) { return ret; } - let isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; + const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; let start; if (isAbsolute) { ret.root = '/'; diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index 6755ebaa983..66178dacef8 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -34,15 +34,15 @@ interface INodeProcess { }; type?: string; } -declare let process: INodeProcess; -declare let global: any; +declare const process: INodeProcess; +declare const global: any; interface INavigator { userAgent: string; language: string; } -declare let navigator: INavigator; -declare let self: any; +declare const navigator: INavigator; +declare const self: any; const isElectronRenderer = (typeof process !== 'undefined' && typeof process.versions !== 'undefined' && typeof process.versions.electron !== 'undefined' && process.type === 'renderer'); diff --git a/src/vs/base/common/process.ts b/src/vs/base/common/process.ts index 386ad29df56..a8447d58eea 100644 --- a/src/vs/base/common/process.ts +++ b/src/vs/base/common/process.ts @@ -13,7 +13,7 @@ interface IProcess { nextTick(callback: (...args: any[]) => void): number; } -declare let process: IProcess; +declare const process: IProcess; const safeProcess: IProcess = (typeof process === 'undefined') ? { cwd(): string { return '/'; }, env: Object.create(null), diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index 54f46ad9468..60a58363f18 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -181,7 +181,7 @@ export function hasTrailingPathSeparator(resource: URI): boolean { const fsp = originalFSPath(resource); return fsp.length > extpath.getRoot(fsp).length && fsp[fsp.length - 1] === paths.sep; } else { - let p = resource.path; + const p = resource.path; return p.length > 1 && p.charCodeAt(p.length - 1) === CharCode.Slash; // ignore the slash at offset 0 } } diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index f33897a9f3b..1ecdd316ba8 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -117,13 +117,13 @@ export class ScrollState implements IScrollDimensions, IScrollPosition { } public createScrollEvent(previous: ScrollState): ScrollEvent { - let widthChanged = (this.width !== previous.width); - let scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth); - let scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft); + const widthChanged = (this.width !== previous.width); + const scrollWidthChanged = (this.scrollWidth !== previous.scrollWidth); + const scrollLeftChanged = (this.scrollLeft !== previous.scrollLeft); - let heightChanged = (this.height !== previous.height); - let scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight); - let scrollTopChanged = (this.scrollTop !== previous.scrollTop); + const heightChanged = (this.height !== previous.height); + const scrollHeightChanged = (this.scrollHeight !== previous.scrollHeight); + const scrollTopChanged = (this.scrollTop !== previous.scrollTop); return { width: this.width, diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index 72a0c0785b5..37c57c26f1c 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -21,8 +21,8 @@ export function isFalsyOrWhitespace(str: string | undefined): boolean { * @returns the provided number with the given number of preceding zeros. */ export function pad(n: number, l: number, char: string = '0'): string { - let str = '' + n; - let r = [str]; + const str = '' + n; + const r = [str]; for (let i = str.length; i < l; i++) { r.push(char); @@ -44,7 +44,7 @@ export function format(value: string, ...args: any[]): string { return value; } return value.replace(_formatRegexp, function (match, group) { - let idx = parseInt(group, 10); + const idx = parseInt(group, 10); return isNaN(idx) || idx < 0 || idx >= args.length ? match : args[idx]; @@ -79,7 +79,7 @@ export function escapeRegExpCharacters(value: string): string { * @param needle the thing to trim (default is a blank) */ export function trim(haystack: string, needle: string = ' '): string { - let trimmed = ltrim(haystack, needle); + const trimmed = ltrim(haystack, needle); return rtrim(trimmed, needle); } @@ -93,7 +93,7 @@ export function ltrim(haystack: string, needle: string): string { return haystack; } - let needleLen = needle.length; + const needleLen = needle.length; if (needleLen === 0 || haystack.length === 0) { return haystack; } @@ -116,7 +116,7 @@ export function rtrim(haystack: string, needle: string): string { return haystack; } - let needleLen = needle.length, + const needleLen = needle.length, haystackLen = haystack.length; if (needleLen === 0 || haystackLen === 0) { @@ -173,7 +173,7 @@ export function startsWith(haystack: string, needle: string): boolean { * Determines if haystack ends with needle. */ export function endsWith(haystack: string, needle: string): boolean { - let diff = haystack.length - needle.length; + const diff = haystack.length - needle.length; if (diff > 0) { return haystack.indexOf(needle, diff) === diff; } else if (diff === 0) { @@ -232,7 +232,7 @@ export function regExpLeadsToEndlessLoop(regexp: RegExp): boolean { // We check against an empty string. If the regular expression doesn't advance // (e.g. ends in an endless loop) it will match an empty string. - let match = regexp.exec(''); + const match = regexp.exec(''); return !!(match && regexp.lastIndex === 0); } @@ -253,7 +253,7 @@ export function regExpFlags(regexp: RegExp): string { */ export function firstNonWhitespaceIndex(str: string): number { for (let i = 0, len = str.length; i < len; i++) { - let chCode = str.charCodeAt(i); + const chCode = str.charCodeAt(i); if (chCode !== CharCode.Space && chCode !== CharCode.Tab) { return i; } @@ -267,7 +267,7 @@ export function firstNonWhitespaceIndex(str: string): number { */ export function getLeadingWhitespace(str: string, start: number = 0, end: number = str.length): string { for (let i = start; i < end; i++) { - let chCode = str.charCodeAt(i); + const chCode = str.charCodeAt(i); if (chCode !== CharCode.Space && chCode !== CharCode.Tab) { return str.substring(start, i); } @@ -281,7 +281,7 @@ export function getLeadingWhitespace(str: string, start: number = 0, end: number */ export function lastNonWhitespaceIndex(str: string, startIndex: number = str.length - 1): number { for (let i = startIndex; i >= 0; i--) { - let chCode = str.charCodeAt(i); + const chCode = str.charCodeAt(i); if (chCode !== CharCode.Space && chCode !== CharCode.Tab) { return i; } @@ -380,7 +380,7 @@ function doEqualsIgnoreCase(a: string, b: string, stopAt = a.length): boolean { // a-z A-Z if (isAsciiLetter(codeA) && isAsciiLetter(codeB)) { - let diff = Math.abs(codeA - codeB); + const diff = Math.abs(codeA - codeB); if (diff !== 0 && diff !== 32) { return false; } @@ -431,8 +431,8 @@ export function commonSuffixLength(a: string, b: string): number { let i: number, len = Math.min(a.length, b.length); - let aLastIndex = a.length - 1; - let bLastIndex = b.length - 1; + const aLastIndex = a.length - 1; + const bLastIndex = b.length - 1; for (i = 0; i < len; i++) { if (a.charCodeAt(aLastIndex - i) !== b.charCodeAt(bLastIndex - i)) { @@ -459,7 +459,7 @@ function substrEquals(a: string, aStart: number, aEnd: number, b: string, bStart * For instance `overlap("foobar", "arr, I'm a pirate") === 2`. */ export function overlap(a: string, b: string): number { - let aEnd = a.length; + const aEnd = a.length; let bEnd = b.length; let aStart = aEnd - bEnd; @@ -486,9 +486,9 @@ export function overlap(a: string, b: string): number { // Code points U+0000 to U+D7FF and U+E000 to U+FFFF are represented on a single character // Code points U+10000 to U+10FFFF are represented on two consecutive characters //export function getUnicodePoint(str:string, index:number, len:number):number { -// let chrCode = str.charCodeAt(index); +// const chrCode = str.charCodeAt(index); // if (0xD800 <= chrCode && chrCode <= 0xDBFF && index + 1 < len) { -// let nextChrCode = str.charCodeAt(index + 1); +// const nextChrCode = str.charCodeAt(index + 1); // if (0xDC00 <= nextChrCode && nextChrCode <= 0xDFFF) { // return (chrCode - 0xD800) << 10 + (nextChrCode - 0xDC00) + 0x10000; // } @@ -685,7 +685,7 @@ export function fuzzyContains(target: string, query: string): boolean { let index = 0; let lastIndexOf = -1; while (index < queryLen) { - let indexOf = targetLower.indexOf(query[index], lastIndexOf + 1); + const indexOf = targetLower.indexOf(query[index], lastIndexOf + 1); if (indexOf < 0) { return false; } diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index 9dbae8ce1e2..d2a261fb029 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -168,7 +168,7 @@ export function create(ctor: Function, ...args: any[]): any { if (isNativeClass(ctor)) { return new (ctor as any)(...args); } else { - let obj = Object.create(ctor.prototype); + const obj = Object.create(ctor.prototype); ctor.apply(obj, args); return obj; } diff --git a/src/vs/base/common/uri.ts b/src/vs/base/common/uri.ts index 8fbecabfd80..79560531ae8 100644 --- a/src/vs/base/common/uri.ts +++ b/src/vs/base/common/uri.ts @@ -329,7 +329,7 @@ export class URI implements UriComponents { // check for authority as used in UNC shares // or use the path as given if (path[0] === _slash && path[1] === _slash) { - let idx = path.indexOf(_slash, 2); + const idx = path.indexOf(_slash, 2); if (idx === -1) { authority = path.substring(2); path = _slash; @@ -379,7 +379,7 @@ export class URI implements UriComponents { } else if (data instanceof URI) { return data; } else { - let result = new _URI(data); + const result = new _URI(data); result._fsPath = (data).fsPath; result._formatted = (data).external; return result; @@ -488,7 +488,7 @@ function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): stri let nativeEncodePos = -1; for (let pos = 0; pos < uriComponent.length; pos++) { - let code = uriComponent.charCodeAt(pos); + const code = uriComponent.charCodeAt(pos); // unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3 if ( @@ -518,7 +518,7 @@ function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): stri } // check with default table first - let escaped = encodeTable[code]; + const escaped = encodeTable[code]; if (escaped !== undefined) { // check if we are delaying native encode @@ -547,7 +547,7 @@ function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): stri function encodeURIComponentMinimal(path: string): string { let res: string | undefined = undefined; for (let pos = 0; pos < path.length; pos++) { - let code = path.charCodeAt(pos); + const code = path.charCodeAt(pos); if (code === CharCode.Hash || code === CharCode.QuestionMark) { if (res === undefined) { res = path.substr(0, pos); @@ -637,12 +637,12 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string { if (path) { // lower-case windows drive letters in /C:/fff or C:/fff if (path.length >= 3 && path.charCodeAt(0) === CharCode.Slash && path.charCodeAt(2) === CharCode.Colon) { - let code = path.charCodeAt(1); + const code = path.charCodeAt(1); if (code >= CharCode.A && code <= CharCode.Z) { path = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // "/c:".length === 3 } } else if (path.length >= 2 && path.charCodeAt(1) === CharCode.Colon) { - let code = path.charCodeAt(0); + const code = path.charCodeAt(0); if (code >= CharCode.A && code <= CharCode.Z) { path = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // "/c:".length === 3 } From 608fc2cee2f1a4c832d8c23b9d4e28805ddf6041 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 16:53:02 -0800 Subject: [PATCH 267/290] Auto convert let -> const in base/node --- src/vs/base/node/decoder.ts | 6 ++--- src/vs/base/node/flow.ts | 12 +++++----- src/vs/base/node/ports.ts | 4 ++-- src/vs/base/node/processes.ts | 44 +++++++++++++++++------------------ src/vs/base/node/ps.ts | 4 ++-- src/vs/base/node/request.ts | 2 +- src/vs/base/node/stats.ts | 22 +++++++++--------- src/vs/base/node/stream.ts | 2 +- src/vs/base/node/zip.ts | 2 +- 9 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/vs/base/node/decoder.ts b/src/vs/base/node/decoder.ts index 5ef4abf19f7..76741a370e4 100644 --- a/src/vs/base/node/decoder.ts +++ b/src/vs/base/node/decoder.ts @@ -24,8 +24,8 @@ export class LineDecoder { } public write(buffer: Buffer): string[] { - let result: string[] = []; - let value = this.remaining + const result: string[] = []; + const value = this.remaining ? this.remaining + this.stringDecoder.write(buffer) : this.stringDecoder.write(buffer); @@ -41,7 +41,7 @@ export class LineDecoder { result.push(value.substring(start, idx)); idx++; if (idx < value.length) { - let lastChar = ch; + const lastChar = ch; ch = value.charCodeAt(idx); if ((lastChar === CharCode.CarriageReturn && ch === CharCode.LineFeed) || (lastChar === CharCode.LineFeed && ch === CharCode.CarriageReturn)) { idx++; diff --git a/src/vs/base/node/flow.ts b/src/vs/base/node/flow.ts index c1232c2993b..a97727ae88d 100644 --- a/src/vs/base/node/flow.ts +++ b/src/vs/base/node/flow.ts @@ -10,8 +10,8 @@ import * as assert from 'assert'; * array to the callback (callback). The resulting errors and results are evaluated by calling the provided callback function. */ export function parallel(list: T[], fn: (item: T, callback: (err: Error | null, result: E | null) => void) => void, callback: (err: Array | null, result: E[]) => void): void { - let results = new Array(list.length); - let errors = new Array(list.length); + const results = new Array(list.length); + const errors = new Array(list.length); let didErrorOccur = false; let doneCount = 0; @@ -68,9 +68,9 @@ export function loop(param: any, fn: (item: any, callback: (error: Error | nu // Expect the param to be an array and loop over it else { - let results: E[] = []; + const results: E[] = []; - let looper: (i: number) => void = function (i: number): void { + const looper: (i: number) => void = function (i: number): void { // Still work to do if (i < param.length) { @@ -126,11 +126,11 @@ function Sequence(sequences: { (...param: any[]): void; }[]): void { }); // Execute in Loop - let errorHandler = sequences.splice(0, 1)[0]; //Remove error handler + const errorHandler = sequences.splice(0, 1)[0]; //Remove error handler let sequenceResult: any = null; loop(sequences, (sequence, clb) => { - let sequenceFunction = function (error: any, result: any): void { + const sequenceFunction = function (error: any, result: any): void { // A method might only send a boolean value as return value (e.g. fs.exists), support this case gracefully if (error === true || error === false) { diff --git a/src/vs/base/node/ports.ts b/src/vs/base/node/ports.ts index a077f020fa9..d0334628e47 100644 --- a/src/vs/base/node/ports.ts +++ b/src/vs/base/node/ports.ts @@ -9,8 +9,8 @@ import * as net from 'net'; * @returns Returns a random port between 1025 and 65535. */ export function randomPort(): number { - let min = 1025; - let max = 65535; + const min = 1025; + const max = 65535; return min + Math.floor((max - min) * Math.random()); } diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index 9836e6ccfbb..df8690d0011 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -42,7 +42,7 @@ function getWindowsCode(status: number): TerminateResponseCode { export function terminateProcess(process: cp.ChildProcess, cwd?: string): TerminateResponse { if (Platform.isWindows) { try { - let options: any = { + const options: any = { stdio: ['pipe', 'pipe', 'ignore'] }; if (cwd) { @@ -54,8 +54,8 @@ export function terminateProcess(process: cp.ChildProcess, cwd?: string): Termin } } else if (Platform.isLinux || Platform.isMacintosh) { try { - let cmd = getPathFromAmdModule(require, 'vs/base/node/terminateProcess.sh'); - let result = cp.spawnSync(cmd, [process.pid.toString()]); + const cmd = getPathFromAmdModule(require, 'vs/base/node/terminateProcess.sh'); + const result = cp.spawnSync(cmd, [process.pid.toString()]); if (result.error) { return { success: false, error: result.error }; } @@ -113,7 +113,7 @@ export abstract class AbstractProcess { this.shell = arg3; this.options = arg4; } else { - let executable = arg1; + const executable = arg1; this.cmd = executable.command; this.shell = executable.isShellCommand; this.args = executable.args.slice(0); @@ -124,7 +124,7 @@ export abstract class AbstractProcess { this.terminateRequested = false; if (this.options.env) { - let newEnv: IStringDictionary = Object.create(null); + const newEnv: IStringDictionary = Object.create(null); Object.keys(process.env).forEach((key) => { newEnv[key] = process.env[key]!; }); @@ -137,7 +137,7 @@ export abstract class AbstractProcess { public getSanitizedCommand(): string { let result = this.cmd.toLowerCase(); - let index = result.lastIndexOf(path.sep); + const index = result.lastIndexOf(path.sep); if (index !== -1) { result = result.substring(index + 1); } @@ -154,7 +154,7 @@ export abstract class AbstractProcess { return this.useExec().then((useExec) => { let cc: ValueCallback; let ee: ErrorCallback; - let result = new Promise((c, e) => { + const result = new Promise((c, e) => { cc = c; ee = e; }); @@ -166,7 +166,7 @@ export abstract class AbstractProcess { } this.childProcess = cp.exec(cmd, this.options, (error, stdout, stderr) => { this.childProcess = null; - let err: any = error; + const err: any = error; // This is tricky since executing a command shell reports error back in case the executed command return an // error or the command didn't exist at all. So we can't blindly treat an error as a failed command. So we // always parse the output and report success unless the job got killed. @@ -178,11 +178,11 @@ export abstract class AbstractProcess { }); } else { let childProcess: cp.ChildProcess | null = null; - let closeHandler = (data: any) => { + const closeHandler = (data: any) => { this.childProcess = null; this.childProcessPromise = null; this.handleClose(data, cc, pp, ee); - let result: SuccessData = { + const result: SuccessData = { terminated: this.terminateRequested }; if (Types.isNumber(data)) { @@ -191,12 +191,12 @@ export abstract class AbstractProcess { cc(result); }; if (this.shell && Platform.isWindows) { - let options: any = Objects.deepClone(this.options); + const options: any = Objects.deepClone(this.options); options.windowsVerbatimArguments = true; options.detached = false; let quotedCommand: boolean = false; let quotedArg: boolean = false; - let commandLine: string[] = []; + const commandLine: string[] = []; let quoted = this.ensureQuotes(this.cmd); commandLine.push(quoted.value); quotedCommand = quoted.quoted; @@ -207,7 +207,7 @@ export abstract class AbstractProcess { quotedArg = quotedArg && quoted.quoted; }); } - let args: string[] = [ + const args: string[] = [ '/s', '/c', ]; @@ -287,7 +287,7 @@ export abstract class AbstractProcess { } return this.childProcessPromise.then((childProcess) => { this.terminateRequested = true; - let result = terminateProcess(childProcess, this.options.cwd); + const result = terminateProcess(childProcess, this.options.cwd); if (result.success) { this.childProcess = null; } @@ -302,7 +302,7 @@ export abstract class AbstractProcess { if (!this.shell || !Platform.isWindows) { return c(false); } - let cmdShell = cp.spawn(getWindowsShell(), ['/s', '/c']); + const cmdShell = cp.spawn(getWindowsShell(), ['/s', '/c']); cmdShell.on('error', (error: Error) => { return c(true); }); @@ -326,12 +326,12 @@ export class LineProcess extends AbstractProcess { protected handleExec(cc: ValueCallback, pp: ProgressCallback, error: Error, stdout: Buffer, stderr: Buffer) { [stdout, stderr].forEach((buffer: Buffer, index: number) => { - let lineDecoder = new LineDecoder(); - let lines = lineDecoder.write(buffer); + const lineDecoder = new LineDecoder(); + const lines = lineDecoder.write(buffer); lines.forEach((line) => { pp({ line: line, source: index === 0 ? Source.stdout : Source.stderr }); }); - let line = lineDecoder.end(); + const line = lineDecoder.end(); if (line) { pp({ line: line, source: index === 0 ? Source.stdout : Source.stderr }); } @@ -343,11 +343,11 @@ export class LineProcess extends AbstractProcess { this.stdoutLineDecoder = new LineDecoder(); this.stderrLineDecoder = new LineDecoder(); childProcess.stdout.on('data', (data: Buffer) => { - let lines = this.stdoutLineDecoder.write(data); + const lines = this.stdoutLineDecoder.write(data); lines.forEach(line => pp({ line: line, source: Source.stdout })); }); childProcess.stderr.on('data', (data: Buffer) => { - let lines = this.stderrLineDecoder.write(data); + const lines = this.stderrLineDecoder.write(data); lines.forEach(line => pp({ line: line, source: Source.stderr })); }); } @@ -380,7 +380,7 @@ export function createQueuedSender(childProcess: cp.ChildProcess): IQueuedSender return; } - let result = childProcess.send(msg, (error: Error) => { + const result = childProcess.send(msg, (error: Error) => { if (error) { console.error(error); // unlikely to happen, best we can do is log this error } @@ -412,7 +412,7 @@ export namespace win32 { if (cwd === undefined) { cwd = process.cwd(); } - let dir = path.dirname(command); + const dir = path.dirname(command); if (dir !== '.') { // We have a directory and the directory is relative (see above). Make the path absolute // to the current working directory. diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index e42e9420809..8a0b2845c4f 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -151,7 +151,7 @@ export function listProcesses(rootPid: number): Promise { rootItem = processItems.get(rootPid); if (rootItem) { processItems.forEach(item => { - let parent = processItems.get(item.ppid); + const parent = processItems.get(item.ppid); if (parent) { if (!parent.children) { parent.children = []; @@ -186,7 +186,7 @@ export function listProcesses(rootPid: number): Promise { const lines = stdout.toString().split('\n'); for (const line of lines) { - let matches = PID_CMD.exec(line.trim()); + const matches = PID_CMD.exec(line.trim()); if (matches && matches.length === 6) { addToTree(parseInt(matches[1]), parseInt(matches[2]), matches[5], parseFloat(matches[3]), parseFloat(matches[4])); } diff --git a/src/vs/base/node/request.ts b/src/vs/base/node/request.ts index 0d8d7434f66..ea24cdb7589 100644 --- a/src/vs/base/node/request.ts +++ b/src/vs/base/node/request.ts @@ -152,7 +152,7 @@ export function asText(context: IRequestContext): Promise { return c(null); } - let buffer: string[] = []; + const buffer: string[] = []; context.stream.on('data', (d: string) => buffer.push(d)); context.stream.on('end', () => c(buffer.join(''))); context.stream.on('error', e); diff --git a/src/vs/base/node/stats.ts b/src/vs/base/node/stats.ts index 4b89e868fe1..1c3598a5d30 100644 --- a/src/vs/base/node/stats.ts +++ b/src/vs/base/node/stats.ts @@ -21,15 +21,15 @@ export interface WorkspaceStats { } function asSortedItems(map: Map): WorkspaceStatItem[] { - let a: WorkspaceStatItem[] = []; + const a: WorkspaceStatItem[] = []; map.forEach((value, index) => a.push({ name: index, count: value })); return a.sort((a, b) => b.count - a.count); } export function collectLaunchConfigs(folder: string): Promise { - let launchConfigs = new Map(); + const launchConfigs = new Map(); - let launchConfig = join(folder, '.vscode', 'launch.json'); + const launchConfig = join(folder, '.vscode', 'launch.json'); return new Promise((resolve, reject) => { exists(launchConfig, (doesExist) => { if (doesExist) { @@ -87,8 +87,8 @@ export async function collectWorkspaceStats(folder: string, filter: string[]): P { 'tag': 'cmake', 'pattern': /^.+\.cmake$/i } ]; - let fileTypes = new Map(); - let configFiles = new Map(); + const fileTypes = new Map(); + const configFiles = new Map(); const MAX_FILES = 20000; @@ -149,7 +149,7 @@ export async function collectWorkspaceStats(folder: string, filter: string[]): P }); } - let addFileType = (fileType: string) => { + const addFileType = (fileType: string) => { if (fileTypes.has(fileType)) { fileTypes.set(fileType, fileTypes.get(fileType)! + 1); } @@ -158,7 +158,7 @@ export async function collectWorkspaceStats(folder: string, filter: string[]): P } }; - let addConfigFiles = (fileName: string) => { + const addConfigFiles = (fileName: string) => { for (const each of configFilePatterns) { if (each.pattern.test(fileName)) { if (configFiles.has(each.tag)) { @@ -170,9 +170,9 @@ export async function collectWorkspaceStats(folder: string, filter: string[]): P } }; - let acceptFile = (name: string) => { + const acceptFile = (name: string) => { if (name.lastIndexOf('.') >= 0) { - let suffix: string | undefined = name.split('.').pop(); + const suffix: string | undefined = name.split('.').pop(); if (suffix) { addFileType(suffix); } @@ -180,13 +180,13 @@ export async function collectWorkspaceStats(folder: string, filter: string[]): P addConfigFiles(name); }; - let token: { count: number, maxReached: boolean } = { count: 0, maxReached: false }; + const token: { count: number, maxReached: boolean } = { count: 0, maxReached: false }; return new Promise((resolve, reject) => { walk(folder, filter, token, async (files) => { files.forEach(acceptFile); - let launchConfigs = await collectLaunchConfigs(folder); + const launchConfigs = await collectLaunchConfigs(folder); resolve({ configFiles: asSortedItems(configFiles), diff --git a/src/vs/base/node/stream.ts b/src/vs/base/node/stream.ts index 845afdab8e9..1c8d7e73ede 100644 --- a/src/vs/base/node/stream.ts +++ b/src/vs/base/node/stream.ts @@ -92,7 +92,7 @@ export function readToMatchingString(file: string, matchingString: string, chunk }); } - let buffer = Buffer.allocUnsafe(maximumBytesToRead); + const buffer = Buffer.allocUnsafe(maximumBytesToRead); let offset = 0; function readChunk(): void { diff --git a/src/vs/base/node/zip.ts b/src/vs/base/node/zip.ts index cb9fbfbf25e..e2221f1b243 100644 --- a/src/vs/base/node/zip.ts +++ b/src/vs/base/node/zip.ts @@ -49,7 +49,7 @@ export class ExtractError extends Error { } function modeFromEntry(entry: Entry) { - let attr = entry.externalFileAttributes >> 16 || 33188; + const attr = entry.externalFileAttributes >> 16 || 33188; return [448 /* S_IRWXU */, 56 /* S_IRWXG */, 7 /* S_IRWXO */] .map(mask => attr & mask) From 38c3f4bedefce282a51f669c2468d781f5b8529b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 5 Mar 2019 17:07:14 -0800 Subject: [PATCH 268/290] Use config file diagnostics provided by TS Server Fixes #69880 --- .../src/typeScriptServiceClientHost.ts | 45 +++---------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts index 890a30fcc06..68e3dd484ab 100644 --- a/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts +++ b/extensions/typescript-language-features/src/typeScriptServiceClientHost.ts @@ -217,47 +217,16 @@ export default class TypeScriptServiceClientHost extends Disposable { return; } - (this.findLanguage(this.client.toResource(body.configFile))).then(language => { + this.findLanguage(this.client.toResource(body.configFile)).then(language => { if (!language) { return; } - if (body.diagnostics.length === 0) { - language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), []); - } else if (body.diagnostics.length >= 1) { - 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: vscode.Diagnostic; - for (let index = 0; index < document.lineCount; index++) { - const line = document.lineAt(index); - const text = line.text; - const firstNonWhitespaceCharacterIndex = line.firstNonWhitespaceCharacterIndex; - if (firstNonWhitespaceCharacterIndex < text.length) { - if (text.charAt(firstNonWhitespaceCharacterIndex) === '{') { - curly = [index, firstNonWhitespaceCharacterIndex, firstNonWhitespaceCharacterIndex + 1]; - break; - } else { - const matches = /\s*([^\s]*)(?:\s*|$)/.exec(text.substr(firstNonWhitespaceCharacterIndex)); - if (matches && matches.length >= 1) { - nonCurly = [index, firstNonWhitespaceCharacterIndex, firstNonWhitespaceCharacterIndex + matches[1].length]; - } - } - } - } - const match = curly || nonCurly; - if (match) { - diagnostic = new vscode.Diagnostic(new vscode.Range(match[0], match[1], match[0], match[2]), body.diagnostics[0].text); - } else { - 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 vscode.Diagnostic(new vscode.Range(0, 0, 0, 0), body.diagnostics[0].text)]); - }); - } + + language.configFileDiagnosticsReceived(this.client.toResource(body.configFile), body.diagnostics.map(tsDiag => { + const diagnostic = new vscode.Diagnostic(typeConverters.Range.fromTextSpan(tsDiag), body.diagnostics[0].text); + diagnostic.source = language.diagnosticSource; + return diagnostic; + })); }); } From 1adb3256ea092a0d47d1d02439f3fa0678025039 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Tue, 5 Mar 2019 17:26:43 -0800 Subject: [PATCH 269/290] Show a quickpick for changing display language (#69570) --- .../browser/localizationsActions.ts | 91 +++++++++++++------ 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts b/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts index 3ee31d1c836..bbd759cb98d 100644 --- a/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts +++ b/src/vs/workbench/contrib/localizations/browser/localizationsActions.ts @@ -5,50 +5,83 @@ import { localize } from 'vs/nls'; import { Action } from 'vs/base/common/actions'; -import { IFileService } from 'vs/platform/files/common/files'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IEditor } from 'vs/workbench/common/editor'; import { join } from 'vs/base/common/path'; import { URI } from 'vs/base/common/uri'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { ILocalizationsService, LanguageType } from 'vs/platform/localizations/common/localizations'; +import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; +import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing'; +import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { INotificationService } from 'vs/platform/notification/common/notification'; import { language } from 'vs/base/common/platform'; -import { ILabelService } from 'vs/platform/label/common/label'; +import { firstIndex } from 'vs/base/common/arrays'; +import { IExtensionsViewlet, VIEWLET_ID as EXTENSIONS_VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; export class ConfigureLocaleAction extends Action { public static readonly ID = 'workbench.action.configureLocale'; public static readonly LABEL = localize('configureLocale', "Configure Display Language"); - private static DEFAULT_CONTENT: string = [ - '{', - `\t// ${localize('displayLanguage', 'Defines VS Code\'s display language.')}`, - `\t// ${localize('doc', 'See {0} for a list of supported languages.', 'https://go.microsoft.com/fwlink/?LinkId=761051')}`, - `\t`, - `\t"locale":"${language}" // ${localize('restart', 'Changes will not take effect until VS Code has been restarted.')}`, - '}' - ].join('\n'); - constructor(id: string, label: string, - @IFileService private readonly fileService: IFileService, @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IEditorService private readonly editorService: IEditorService, - @ILabelService private readonly labelService: ILabelService + @ILocalizationsService private readonly localizationService: ILocalizationsService, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, + @IWindowsService private readonly windowsService: IWindowsService, + @INotificationService private readonly notificationService: INotificationService, + @IViewletService private readonly viewletService: IViewletService, + @IDialogService private readonly dialogService: IDialogService ) { super(id, label); } - public run(event?: any): Promise { - const file = URI.file(join(this.environmentService.appSettingsHome, 'locale.json')); - return this.fileService.resolveFile(file).then(undefined, (error) => { - return this.fileService.createFile(file, ConfigureLocaleAction.DEFAULT_CONTENT); - }).then((stat): Promise | null => { - if (!stat) { - return null; + private async getLanguageOptions(): Promise { + // Contributed languages are those installed via extension packs, so does not include English + const availableLanguages = ['en', ...await this.localizationService.getLanguageIds(LanguageType.Contributed)]; + availableLanguages.sort(); + + return availableLanguages + .map(language => { return { label: language }; }) + .concat({ label: localize('installAdditionalLanguages', "Install additional languages...") }); + } + + public async run(event?: any): Promise { + const languageOptions = await this.getLanguageOptions(); + const currentLanguageIndex = firstIndex(languageOptions, l => l.label === language); + + try { + const selectedLanguage = await this.quickInputService.pick(languageOptions, + { + canPickMany: false, + placeHolder: localize('chooseDisplayLanguage', "Select Display Language"), + activeItem: languageOptions[currentLanguageIndex] + }); + + if (selectedLanguage === languageOptions[languageOptions.length - 1]) { + return this.viewletService.openViewlet(EXTENSIONS_VIEWLET_ID, true) + .then((viewlet: IExtensionsViewlet) => { + viewlet.search('@category:"language packs"'); + viewlet.focus(); + }); } - return this.editorService.openEditor({ - resource: stat.resource - }); - }, (error) => { - throw new Error(localize('fail.createSettings', "Unable to create '{0}' ({1}).", this.labelService.getUriLabel(file, { relative: true }), error)); - }); + + if (selectedLanguage) { + const file = URI.file(join(this.environmentService.appSettingsHome, 'locale.json')); + await this.jsonEditingService.write(file, { key: 'locale', value: selectedLanguage.label }, true); + const restart = await this.dialogService.confirm({ + type: 'info', + message: localize('relaunchDisplayLanguageMessage', "A restart is required for the change in display language to take effect."), + detail: localize('relaunchDisplayLanguageDetail', "Press the restart button to restart {0} and change the display language.", this.environmentService.appNameLong), + primaryButton: localize('restart', "&&Restart") + }); + + if (restart.confirmed) { + this.windowsService.relaunch({}); + } + } + } catch (e) { + this.notificationService.error(e); + } } } From 0710a009f8cf56a5f8ee6403f61c158a1df493bc Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 16:11:40 -0800 Subject: [PATCH 270/290] Fix #69875 --- src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts | 2 +- src/vs/workbench/api/node/extHost.protocol.ts | 2 +- src/vs/workbench/api/node/extHostWorkspace.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts index fe39eeef61a..c2b3d540575 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadWorkspace.ts @@ -119,7 +119,7 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape { // --- search --- - $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise { + $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false | undefined, maxResults: number, token: CancellationToken): Promise { const includeFolder = URI.revive(_includeFolder); const workspace = this._contextService.getWorkspace(); if (!workspace.folders.length) { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index e7cb2b72c07..53df36fbf27 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -527,7 +527,7 @@ export interface ExtHostUrlsShape { } export interface MainThreadWorkspaceShape extends IDisposable { - $startFileSearch(includePattern: string | undefined, includeFolder: URI | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise; + $startFileSearch(includePattern: string | undefined, includeFolder: URI | undefined, excludePatternOrDisregardExcludes: string | false | undefined, maxResults: number, token: CancellationToken): Promise; $startTextSearch(query: IPatternInfo, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise; $checkExists(includes: string[], token: CancellationToken): Promise; $saveAll(includeUntitled?: boolean): Promise; diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 785ad829cba..bcd01710615 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -405,7 +405,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac } } - let excludePatternOrDisregardExcludes: string | false = false; + let excludePatternOrDisregardExcludes: string | false | undefined = undefined; if (exclude === null) { excludePatternOrDisregardExcludes = false; } else if (exclude) { From 92629f3f5f4c662a26cc193b5208c3ff3a335243 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 5 Mar 2019 19:17:21 -0800 Subject: [PATCH 271/290] findFiles tests --- .../src/singlefolder-tests/workspace.test.ts | 7 + .../services/search/common/search.ts | 3 - .../api/extHostWorkspace.test.ts | 123 ++++++++++++++++-- .../api/mainThreadWorkspace.test.ts | 101 ++++++++++++++ 4 files changed, 223 insertions(+), 11 deletions(-) create mode 100644 src/vs/workbench/test/electron-browser/api/mainThreadWorkspace.test.ts 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 2f46c461b3f..a1e85fc4daf 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -494,6 +494,13 @@ suite('workspace-namespace', () => { }); }); + test('findFiles - exclude', () => { + return vscode.workspace.findFiles('**/*.png').then((res) => { + assert.equal(res.length, 2); + assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); + }); + }); + test('findFiles, exclude', () => { return vscode.workspace.findFiles('**/*.png', '**/sub/**').then((res) => { assert.equal(res.length, 1); diff --git a/src/vs/workbench/services/search/common/search.ts b/src/vs/workbench/services/search/common/search.ts index 16f1f7af4d9..a109834cc1a 100644 --- a/src/vs/workbench/services/search/common/search.ts +++ b/src/vs/workbench/services/search/common/search.ts @@ -71,9 +71,6 @@ export interface IFileQueryProps extends ICommonQueryPr type: QueryType.File; filePattern?: string; - // TODO: Remove this! - disregardExcludeSettings?: boolean; - /** * If true no results will be returned. Instead `limitHit` will indicate if at least one result exists or not. * Currently does not work with queries including a 'siblings clause'. 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 40de7dbe2b3..5974b4713f5 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -4,16 +4,20 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { URI } from 'vs/base/common/uri'; -import { basename } from 'vs/base/common/path'; -import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; -import { TestRPCProtocol } from './testRPCProtocol'; -import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; -import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { NullLogService, ILogService } from 'vs/platform/log/common/log'; -import { IMainContext, IWorkspaceData } from 'vs/workbench/api/node/extHost.protocol'; +import { CancellationToken } from 'vs/base/common/cancellation'; import { Counter } from 'vs/base/common/numbers'; +import { basename } from 'vs/base/common/path'; +import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { ILogService, NullLogService } from 'vs/platform/log/common/log'; +import { IWorkspaceFolderData } from 'vs/platform/workspace/common/workspace'; +import { MainThreadWorkspace } from 'vs/workbench/api/electron-browser/mainThreadWorkspace'; +import { IMainContext, IWorkspaceData, MainContext } from 'vs/workbench/api/node/extHost.protocol'; +import { RelativePattern } from 'vs/workbench/api/node/extHostTypes'; +import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; +import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; +import { mock } from 'vs/workbench/test/electron-browser/api/mock'; +import { TestRPCProtocol } from './testRPCProtocol'; function createExtHostWorkspace(mainContext: IMainContext, data: IWorkspaceData, logService: ILogService, requestIdProvider: Counter): ExtHostWorkspace { const result = new ExtHostWorkspace(mainContext, logService, requestIdProvider); @@ -563,4 +567,107 @@ suite('ExtHostWorkspace', function () { function asUpdateWorkspaceFolderData(uri: URI, name?: string): { uri: URI, name?: string } { return { uri, name }; } + + test('findFiles - string include', () => { + const root = '/project/foo'; + const rpcProtocol = new TestRPCProtocol(); + + let mainThreadCalled = false; + rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock() { + $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise { + mainThreadCalled = true; + assert.equal(includePattern, 'foo'); + assert.equal(_includeFolder, undefined); + assert.equal(excludePatternOrDisregardExcludes, undefined); + assert.equal(maxResults, 10); + return Promise.resolve(undefined); + } + }); + + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + return ws.findFiles('foo', undefined!, 10, new ExtensionIdentifier('test')).then(() => { + assert(mainThreadCalled, 'mainThreadCalled'); + }); + }); + + test('findFiles - RelativePattern include', () => { + const root = '/project/foo'; + const rpcProtocol = new TestRPCProtocol(); + + let mainThreadCalled = false; + rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock() { + $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise { + mainThreadCalled = true; + assert.equal(includePattern, 'glob/**'); + assert.deepEqual(_includeFolder, URI.file('/other/folder').toJSON()); + assert.equal(excludePatternOrDisregardExcludes, undefined); + return Promise.resolve(undefined); + } + }); + + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), undefined!, 10, new ExtensionIdentifier('test')).then(() => { + assert(mainThreadCalled, 'mainThreadCalled'); + }); + }); + + test('findFiles - no excludes', () => { + const root = '/project/foo'; + const rpcProtocol = new TestRPCProtocol(); + + let mainThreadCalled = false; + rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock() { + $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise { + mainThreadCalled = true; + assert.equal(includePattern, 'glob/**'); + assert.deepEqual(_includeFolder, URI.file('/other/folder').toJSON()); + assert.equal(excludePatternOrDisregardExcludes, false); + return Promise.resolve(undefined); + } + }); + + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), null!, 10, new ExtensionIdentifier('test')).then(() => { + assert(mainThreadCalled, 'mainThreadCalled'); + }); + }); + + test('findFiles - with cancelled token', () => { + const root = '/project/foo'; + const rpcProtocol = new TestRPCProtocol(); + + let mainThreadCalled = false; + rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock() { + $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise { + mainThreadCalled = true; + return Promise.resolve(undefined); + } + }); + + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + + const token = CancellationToken.Cancelled; + return ws.findFiles(new RelativePattern('/other/folder', 'glob/**'), null!, 10, new ExtensionIdentifier('test'), token).then(() => { + assert(!mainThreadCalled, '!mainThreadCalled'); + }); + }); + + test('findFiles - RelativePattern exclude', () => { + const root = '/project/foo'; + const rpcProtocol = new TestRPCProtocol(); + + let mainThreadCalled = false; + rpcProtocol.set(MainContext.MainThreadWorkspace, new class extends mock() { + $startFileSearch(includePattern: string, _includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false, maxResults: number, token: CancellationToken): Promise { + mainThreadCalled = true; + assert(excludePatternOrDisregardExcludes, 'glob/**'); // Note that the base portion is ignored, see #52651 + return Promise.resolve(undefined); + } + }); + + const ws = createExtHostWorkspace(rpcProtocol, { id: 'foo', folders: [aWorkspaceFolderData(URI.file(root), 0)], name: 'Test' }, new NullLogService(), new Counter()); + return ws.findFiles('', new RelativePattern(root, 'glob/**'), 10, new ExtensionIdentifier('test')).then(() => { + assert(mainThreadCalled, 'mainThreadCalled'); + }); + }); }); diff --git a/src/vs/workbench/test/electron-browser/api/mainThreadWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/mainThreadWorkspace.test.ts new file mode 100644 index 00000000000..fc2e5cd50b5 --- /dev/null +++ b/src/vs/workbench/test/electron-browser/api/mainThreadWorkspace.test.ts @@ -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. + *--------------------------------------------------------------------------------------------*/ + +import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { ISearchService, IFileQuery } from 'vs/workbench/services/search/common/search'; +import { MainThreadWorkspace } from 'vs/workbench/api/electron-browser/mainThreadWorkspace'; +import * as assert from 'assert'; +import { SingleProxyRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; + +suite('MainThreadWorkspace', () => { + + let configService: TestConfigurationService; + let instantiationService: TestInstantiationService; + + setup(() => { + instantiationService = workbenchInstantiationService() as TestInstantiationService; + + configService = instantiationService.get(IConfigurationService) as TestConfigurationService; + configService.setUserConfiguration('search', {}); + }); + + test('simple', () => { + instantiationService.stub(ISearchService, { + fileSearch(query: IFileQuery) { + assert.equal(query.folderQueries.length, 1); + assert.equal(query.folderQueries[0].disregardIgnoreFiles, true); + + assert.deepEqual(query.includePattern, { 'foo': true }); + assert.equal(query.maxResults, 10); + + return Promise.resolve({ results: [] }); + } + }); + + const mtw: MainThreadWorkspace = instantiationService.createInstance(MainThreadWorkspace, SingleProxyRPCProtocol({ $initializeWorkspace: () => { } })); + return mtw.$startFileSearch('foo', undefined, undefined, 10, new CancellationTokenSource().token); + }); + + test('exclude defaults', () => { + configService.setUserConfiguration('search', { + 'exclude': { 'searchExclude': true } + }); + configService.setUserConfiguration('files', { + 'exclude': { 'filesExclude': true } + }); + + instantiationService.stub(ISearchService, { + fileSearch(query: IFileQuery) { + assert.equal(query.folderQueries.length, 1); + assert.equal(query.folderQueries[0].disregardIgnoreFiles, true); + assert.deepEqual(query.folderQueries[0].excludePattern, { 'filesExclude': true }); + + return Promise.resolve({ results: [] }); + } + }); + + const mtw: MainThreadWorkspace = instantiationService.createInstance(MainThreadWorkspace, SingleProxyRPCProtocol({ $initializeWorkspace: () => { } })); + return mtw.$startFileSearch('', undefined, undefined, 10, new CancellationTokenSource().token); + }); + + test('disregard excludes', () => { + configService.setUserConfiguration('search', { + 'exclude': { 'searchExclude': true } + }); + configService.setUserConfiguration('files', { + 'exclude': { 'filesExclude': true } + }); + + instantiationService.stub(ISearchService, { + fileSearch(query: IFileQuery) { + assert.equal(query.folderQueries[0].excludePattern, undefined); + assert.deepEqual(query.excludePattern, undefined); + + return Promise.resolve({ results: [] }); + } + }); + + const mtw: MainThreadWorkspace = instantiationService.createInstance(MainThreadWorkspace, SingleProxyRPCProtocol({ $initializeWorkspace: () => { } })); + return mtw.$startFileSearch('', undefined, false, 10, new CancellationTokenSource().token); + }); + + test('exclude string', () => { + instantiationService.stub(ISearchService, { + fileSearch(query: IFileQuery) { + assert.equal(query.folderQueries[0].excludePattern, undefined); + assert.deepEqual(query.excludePattern, { 'exclude/**': true }); + + return Promise.resolve({ results: [] }); + } + }); + + const mtw: MainThreadWorkspace = instantiationService.createInstance(MainThreadWorkspace, SingleProxyRPCProtocol({ $initializeWorkspace: () => { } })); + return mtw.$startFileSearch('', undefined, 'exclude/**', 10, new CancellationTokenSource().token); + }); +}); From 556bfbeee6ec5126e4a7d84581ef4f14afb043b0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Mar 2019 09:48:15 +0100 Subject: [PATCH 272/290] fix #43270 --- .../contrib/snippet/snippetController2.ts | 21 +++++++++-- .../editor/contrib/snippet/snippetSession.ts | 10 +++--- .../snippet/test/snippetController2.test.ts | 36 ++++++++++++++----- .../snippet/test/snippetSession.test.ts | 2 +- 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/vs/editor/contrib/snippet/snippetController2.ts b/src/vs/editor/contrib/snippet/snippetController2.ts index 3f87729b6ab..eadc88a2545 100644 --- a/src/vs/editor/contrib/snippet/snippetController2.ts +++ b/src/vs/editor/contrib/snippet/snippetController2.ts @@ -19,6 +19,7 @@ import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from ' import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { ILogService } from 'vs/platform/log/common/log'; import { SnippetSession } from './snippetSession'; +import { EditorState, CodeEditorStateFlag } from 'vs/editor/browser/core/editorState'; export class SnippetController2 implements IEditorContribution { @@ -113,10 +114,26 @@ export class SnippetController2 implements IEditorContribution { this._updateState(); + // we listen on model and selection changes. usually + // both events come in together and this is to prevent + // that we don't call _updateState twice. + let state: EditorState; + let dedupedUpdateState = () => { + if (!state || !state.validate(this._editor)) { + this._updateState(); + state = new EditorState(this._editor, CodeEditorStateFlag.Selection | CodeEditorStateFlag.Value); + } + }; this._snippetListener = [ - this._editor.onDidChangeModelContent(e => e.isFlush && this.cancel()), + this._editor.onDidChangeModelContent(e => { + if (e.isFlush) { + this.cancel(); + } else { + setTimeout(dedupedUpdateState, 0); + } + }), + this._editor.onDidChangeCursorSelection(dedupedUpdateState), this._editor.onDidChangeModel(() => this.cancel()), - this._editor.onDidChangeCursorSelection(() => this._updateState()) ]; } diff --git a/src/vs/editor/contrib/snippet/snippetSession.ts b/src/vs/editor/contrib/snippet/snippetSession.ts index 53cb0ed3c15..31cfa72a41c 100644 --- a/src/vs/editor/contrib/snippet/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/snippetSession.ts @@ -197,10 +197,6 @@ export class OneSnippet { let ranges: Range[] | undefined; for (const placeholder of placeholdersWithEqualIndex) { - if (placeholder.isFinalTabstop) { - // ignore those - break; - } if (!ranges) { ranges = []; @@ -574,6 +570,12 @@ export class SnippetSession { return false; } + if (allPossibleSelections.has(0)) { + // selection overlaps with a final tab stop which means + // we done + return false; + } + // add selections from 'this' snippet so that we know all // selections for this placeholder allPossibleSelections.forEach((array, index) => { diff --git a/src/vs/editor/contrib/snippet/test/snippetController2.test.ts b/src/vs/editor/contrib/snippet/test/snippetController2.test.ts index 95395786fd0..bfb0cf61727 100644 --- a/src/vs/editor/contrib/snippet/test/snippetController2.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetController2.test.ts @@ -11,6 +11,7 @@ import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKe import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { NullLogService } from 'vs/platform/log/common/log'; import { Handler } from 'vs/editor/common/editorCommon'; +import { timeout } from 'vs/base/common/async'; suite('SnippetController2', function () { @@ -133,11 +134,11 @@ suite('SnippetController2', function () { assertSelections(editor, new Selection(1, 1, 1, 7), new Selection(2, 5, 2, 11)); editor.trigger('test', 'cut', {}); - assertContextKeys(contextKeys, true, false, true); + assertContextKeys(contextKeys, false, false, false); assertSelections(editor, new Selection(1, 1, 1, 1), new Selection(2, 5, 2, 5)); editor.trigger('test', 'type', { text: 'abc' }); - assertContextKeys(contextKeys, true, false, true); + assertContextKeys(contextKeys, false, false, false); ctrl.next(); assertContextKeys(contextKeys, false, false, false); @@ -159,9 +160,9 @@ suite('SnippetController2', function () { assertSelections(editor, new Selection(1, 4, 1, 4), new Selection(2, 8, 2, 8)); assertContextKeys(contextKeys, true, false, true); - ctrl.next(); - assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11)); - assertContextKeys(contextKeys, true, true, true); + // ctrl.next(); + // assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11)); + // assertContextKeys(contextKeys, true, true, true); ctrl.next(); assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11)); @@ -176,10 +177,10 @@ suite('SnippetController2', function () { ctrl.insert('farboo'); assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11)); - assertContextKeys(contextKeys, true, false, true); + // assertContextKeys(contextKeys, true, false, true); - ctrl.next(); - assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11)); + // ctrl.next(); + // assertSelections(editor, new Selection(1, 7, 1, 7), new Selection(2, 11, 2, 11)); assertContextKeys(contextKeys, false, false, false); }); @@ -401,4 +402,23 @@ suite('SnippetController2', function () { assertContextKeys(contextKeys, false, false, false); assertSelections(editor, new Selection(1, 22, 1, 22)); }); + + test('A little confusing visual effect of highlighting for snippet tabstop #43270', async function () { + const ctrl = new SnippetController2(editor, logService, contextKeys); + model.setValue(''); + editor.setSelection(new Selection(1, 1, 1, 1)); + + ctrl.insert('background-color: ${1:fff};$0'); + assertSelections(editor, new Selection(1, 19, 1, 22)); + + editor.setSelection(new Selection(1, 22, 1, 22)); + assertContextKeys(contextKeys, true, false, true); + editor.trigger('', 'deleteRight', null); + + assert.equal(model.getValue(), 'background-color: fff'); + + await timeout(0); // this depends on re-scheduling of events... + + assertContextKeys(contextKeys, false, false, false); + }); }); diff --git a/src/vs/editor/contrib/snippet/test/snippetSession.test.ts b/src/vs/editor/contrib/snippet/test/snippetSession.test.ts index 0d2ec457b50..924f9a6d230 100644 --- a/src/vs/editor/contrib/snippet/test/snippetSession.test.ts +++ b/src/vs/editor/contrib/snippet/test/snippetSession.test.ts @@ -331,7 +331,7 @@ suite('SnippetSession', function () { // reset selection to placeholder session.next(); - assert.equal(session.isSelectionWithinPlaceholders(), true); + assert.equal(session.isSelectionWithinPlaceholders(), false); assert.equal(session.isAtLastPlaceholder, true); assertSelections(editor, new Selection(1, 13, 1, 13), new Selection(2, 17, 2, 17)); }); From 0b9e2a1c8a6e041aabf813e73a3876a2c667ac48 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 6 Mar 2019 09:57:44 +0100 Subject: [PATCH 273/290] If the code editor is readonly still alow bulk edits to be applied --- src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts index 5137f89c2c5..f532d978e35 100644 --- a/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/services/bulkEdit/browser/bulkEditService.ts @@ -410,6 +410,10 @@ export class BulkEditService implements IBulkEditService { } } + if (codeEditor && codeEditor.getConfiguration().readOnly) { + // If the code editor is readonly still allow bulk edits to be applied #68549 + codeEditor = undefined; + } const bulkEdit = new BulkEdit(codeEditor, options.progress, this._logService, this._textModelService, this._fileService, this._textFileService, this._labelService, this._configurationService); bulkEdit.add(edits); From ec878903e941e09af53936262470ce9de6370826 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Mar 2019 10:18:15 +0100 Subject: [PATCH 274/290] Fix #69849 --- .../editor/contrib/hover/modesContentHover.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index bf6bab44890..671da624c7b 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -24,7 +24,7 @@ import { ContentHoverWidget } from 'vs/editor/contrib/hover/hoverWidgets'; import { MarkdownRenderer } from 'vs/editor/contrib/markdown/markdownRenderer'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays'; -import { IMarker, IMarkerData } from 'vs/platform/markers/common/markers'; +import { IMarker, IMarkerData, MarkerSeverity } from 'vs/platform/markers/common/markers'; import { basename } from 'vs/base/common/resources'; import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; import { onUnexpectedError } from 'vs/base/common/errors'; @@ -474,7 +474,8 @@ export class ModesContentHoverWidget extends ContentHoverWidget { if (markerMessages.length) { markerMessages.forEach(msg => fragment.appendChild(this.renderMarkerHover(msg))); - fragment.appendChild(this.renderMarkerStatusbar(markerMessages[0])); + const markerHoverForStatusbar = markerMessages.length === 1 ? markerMessages[0] : markerMessages.sort((a, b) => MarkerSeverity.compare(a.marker.severity, b.marker.severity))[0]; + fragment.appendChild(this.renderMarkerStatusbar(markerHoverForStatusbar)); } // show @@ -550,15 +551,17 @@ export class ModesContentHoverWidget extends ContentHoverWidget { }); } })); - disposables.push(this.renderAction(actionsElement, { - label: nls.localize('peek problem', "Peek Problem"), - commandId: NextMarkerAction.ID, - run: () => { - this.hide(); - MarkerController.get(this._editor).show(markerHover.marker); - this._editor.focus(); - } - })); + if (markerHover.marker.severity === MarkerSeverity.Error || markerHover.marker.severity === MarkerSeverity.Warning || markerHover.marker.severity === MarkerSeverity.Info) { + disposables.push(this.renderAction(actionsElement, { + label: nls.localize('peek problem', "Peek Problem"), + commandId: NextMarkerAction.ID, + run: () => { + this.hide(); + MarkerController.get(this._editor).show(markerHover.marker); + this._editor.focus(); + } + })); + } this.renderDisposable = combinedDisposable(disposables); return hoverElement; } From c4bed467841821c894f5b6da1fdac7e33ef7989c Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 6 Mar 2019 10:14:38 +0100 Subject: [PATCH 275/290] Add a download util that uses a separate process --- build/download/download.js | 91 ++++++++++++++++++++++++++++++ build/download/download.ts | 111 +++++++++++++++++++++++++++++++++++++ build/gulpfile.hygiene.js | 2 +- build/lib/util.js | 37 +++++++++++++ build/lib/util.ts | 38 +++++++++++++ 5 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 build/download/download.js create mode 100644 build/download/download.ts diff --git a/build/download/download.js b/build/download/download.js new file mode 100644 index 00000000000..c70bae336a6 --- /dev/null +++ b/build/download/download.js @@ -0,0 +1,91 @@ +"use strict"; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +Object.defineProperty(exports, "__esModule", { value: true }); +const https = require("https"); +const fs = require("fs"); +const path = require("path"); +const cp = require("child_process"); +function ensureDir(filepath) { + if (!fs.existsSync(filepath)) { + ensureDir(path.dirname(filepath)); + fs.mkdirSync(filepath); + } +} +function download(options, destination) { + ensureDir(path.dirname(destination)); + return new Promise((c, e) => { + const fd = fs.openSync(destination, 'w'); + const req = https.get(options, (res) => { + res.on('data', (chunk) => { + fs.writeSync(fd, chunk); + }); + res.on('end', () => { + fs.closeSync(fd); + c(); + }); + }); + req.on('error', (reqErr) => { + console.error(`request to ${options.host}${options.path} failed.`); + console.error(reqErr); + e(reqErr); + }); + }); +} +const MARKER_ARGUMENT = `_download_fork_`; +function base64encode(str) { + return Buffer.from(str, 'utf8').toString('base64'); +} +function base64decode(str) { + return Buffer.from(str, 'base64').toString('utf8'); +} +function downloadInExternalProcess(options) { + const url = `https://${options.requestOptions.host}${options.requestOptions.path}`; + console.log(`Downloading ${url}...`); + return new Promise((c, e) => { + const child = cp.fork(__filename, [MARKER_ARGUMENT, base64encode(JSON.stringify(options))], { + stdio: ['pipe', 'pipe', 'pipe', 'ipc'] + }); + let stderr = []; + child.stderr.on('data', (chunk) => { + stderr.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); + }); + child.on('exit', (code) => { + if (code === 0) { + // normal termination + console.log(`Finished downloading ${url}.`); + c(); + } + else { + // abnormal termination + console.error(Buffer.concat(stderr).toString()); + e(new Error(`Download of ${url} failed.`)); + } + }); + }); +} +exports.downloadInExternalProcess = downloadInExternalProcess; +function _downloadInExternalProcess() { + let options; + try { + options = JSON.parse(base64decode(process.argv[3])); + } + catch (err) { + console.error(`Cannot read arguments`); + console.error(err); + process.exit(-1); + return; + } + download(options.requestOptions, options.destinationPath).then(() => { + process.exit(0); + }, (err) => { + console.error(err); + process.exit(-2); + }); +} +if (process.argv.length >= 4 && process.argv[2] === MARKER_ARGUMENT) { + // running as forked download script + _downloadInExternalProcess(); +} diff --git a/build/download/download.ts b/build/download/download.ts new file mode 100644 index 00000000000..01ac8864d0b --- /dev/null +++ b/build/download/download.ts @@ -0,0 +1,111 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as https from 'https'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as cp from 'child_process'; + +function ensureDir(filepath: string) { + if (!fs.existsSync(filepath)) { + ensureDir(path.dirname(filepath)); + fs.mkdirSync(filepath); + } +} + +function download(options: https.RequestOptions, destination: string): Promise { + ensureDir(path.dirname(destination)); + + return new Promise((c, e) => { + const fd = fs.openSync(destination, 'w'); + const req = https.get(options, (res) => { + res.on('data', (chunk) => { + fs.writeSync(fd, chunk); + }); + res.on('end', () => { + fs.closeSync(fd); + c(); + }); + }); + req.on('error', (reqErr) => { + console.error(`request to ${options.host}${options.path} failed.`); + console.error(reqErr); + e(reqErr); + }); + }); +} + +const MARKER_ARGUMENT = `_download_fork_`; + +function base64encode(str: string): string { + return Buffer.from(str, 'utf8').toString('base64'); +} + +function base64decode(str: string): string { + return Buffer.from(str, 'base64').toString('utf8'); +} + +export interface IDownloadRequestOptions { + host: string; + path: string; +} + +export interface IDownloadOptions { + requestOptions: IDownloadRequestOptions; + destinationPath: string; +} + +export function downloadInExternalProcess(options: IDownloadOptions): Promise { + const url = `https://${options.requestOptions.host}${options.requestOptions.path}`; + console.log(`Downloading ${url}...`); + return new Promise((c, e) => { + const child = cp.fork( + __filename, + [MARKER_ARGUMENT, base64encode(JSON.stringify(options))], + { + stdio: ['pipe', 'pipe', 'pipe', 'ipc'] + } + ); + let stderr: Buffer[] = []; + child.stderr.on('data', (chunk) => { + stderr.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); + }); + child.on('exit', (code) => { + if (code === 0) { + // normal termination + console.log(`Finished downloading ${url}.`); + c(); + } else { + // abnormal termination + console.error(Buffer.concat(stderr).toString()); + e(new Error(`Download of ${url} failed.`)); + } + }); + }); +} + +function _downloadInExternalProcess() { + let options: IDownloadOptions; + try { + options = JSON.parse(base64decode(process.argv[3])); + } catch (err) { + console.error(`Cannot read arguments`); + console.error(err); + process.exit(-1); + return; + } + + download(options.requestOptions, options.destinationPath).then(() => { + process.exit(0); + }, (err) => { + console.error(err); + process.exit(-2); + }); +} + +if (process.argv.length >= 4 && process.argv[2] === MARKER_ARGUMENT) { + // running as forked download script + _downloadInExternalProcess(); +} diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 187968a95bc..2525e625e43 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -81,7 +81,7 @@ const indentationFilter = [ '!src/typings/**/*.d.ts', '!extensions/**/*.d.ts', '!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe,ico,icns}', - '!build/{lib,tslintRules}/**/*.js', + '!build/{lib,tslintRules,download}/**/*.js', '!build/**/*.sh', '!build/azure-pipelines/**/*.js', '!build/azure-pipelines/**/*.config', diff --git a/build/lib/util.js b/build/lib/util.js index 17edc75f65f..34ee13695fd 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -14,6 +14,8 @@ const fs = require("fs"); const _rimraf = require("rimraf"); const git = require("./git"); const VinylFile = require("vinyl"); +const download_1 = require("../download/download"); +const REPO_ROOT = path.join(__dirname, '../../'); const NoCancellationToken = { isCancellationRequested: () => false }; function incremental(streamProvider, initial, supportsCancellation) { const input = es.through(); @@ -221,3 +223,38 @@ function versionStringToNumber(versionStr) { return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); } exports.versionStringToNumber = versionStringToNumber; +function download(requestOptions) { + const result = es.through(); + const filename = path.join(REPO_ROOT, `.build/tmp-${Date.now()}-${path.posix.basename(requestOptions.path)}`); + const opts = { + requestOptions: requestOptions, + destinationPath: filename + }; + download_1.downloadInExternalProcess(opts).then(() => { + fs.stat(filename, (err, stat) => { + if (err) { + result.emit('error', err); + return; + } + fs.readFile(filename, (err, data) => { + if (err) { + result.emit('error', err); + return; + } + fs.unlink(filename, () => { + result.emit('data', new VinylFile({ + path: path.normalize(requestOptions.path), + stat: stat, + base: path.normalize(requestOptions.path), + contents: data + })); + result.emit('end'); + }); + }); + }); + }, (err) => { + result.emit('error', err); + }); + return result; +} +exports.download = download; diff --git a/build/lib/util.ts b/build/lib/util.ts index a773b2449da..44ac9d0dc74 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -17,6 +17,9 @@ import * as git from './git'; import * as VinylFile from 'vinyl'; import { ThroughStream } from 'through'; import * as sm from 'source-map'; +import { IDownloadOptions, downloadInExternalProcess, IDownloadRequestOptions } from '../download/download'; + +const REPO_ROOT = path.join(__dirname, '../../'); export interface ICancellationToken { isCancellationRequested(): boolean; @@ -280,3 +283,38 @@ export function versionStringToNumber(versionStr: string) { return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10); } + +export function download(requestOptions: IDownloadRequestOptions): NodeJS.ReadWriteStream { + const result = es.through(); + const filename = path.join(REPO_ROOT, `.build/tmp-${Date.now()}-${path.posix.basename(requestOptions.path)}`); + const opts: IDownloadOptions = { + requestOptions: requestOptions, + destinationPath: filename + }; + downloadInExternalProcess(opts).then(() => { + fs.stat(filename, (err, stat) => { + if (err) { + result.emit('error', err); + return; + } + fs.readFile(filename, (err, data) => { + if (err) { + result.emit('error', err); + return; + } + fs.unlink(filename, () => { + result.emit('data', new VinylFile({ + path: path.normalize(requestOptions.path), + stat: stat, + base: path.normalize(requestOptions.path), + contents: data + })); + result.emit('end'); + }); + }); + }); + }, (err) => { + result.emit('error', err); + }); + return result; +} From caa10c9d053fd883d7b8d8fefd840dcf09d656ef Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 6 Mar 2019 10:16:55 +0100 Subject: [PATCH 276/290] Simplify the Protocol implementation --- src/vs/base/parts/ipc/node/ipc.net.ts | 135 +++++++++++------- .../base/parts/ipc/test/node/ipc.net.test.ts | 35 ----- 2 files changed, 86 insertions(+), 84 deletions(-) diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index 08f2def654f..9cc68b10be5 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -10,7 +10,6 @@ import { join } from 'vs/base/common/path'; import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { TimeoutTimer } from 'vs/base/common/async'; export function generateRandomPipeName(): string { const randomSuffix = generateUuid(); @@ -22,6 +21,80 @@ export function generateRandomPipeName(): string { } } +class ChunkStream { + + private _chunks: Buffer[]; + private _totalLength: number; + + public get byteLength() { + return this._totalLength; + } + + constructor() { + this._chunks = []; + this._totalLength = 0; + } + + public acceptChunk(buff: Buffer) { + this._chunks.push(buff); + this._totalLength += buff.byteLength; + } + + public readUInt32BE(): number { + let tmp = this.read(4); + return tmp.readUInt32BE(0); + } + + public read(byteCount: number): Buffer { + if (byteCount === 0) { + return Buffer.allocUnsafe(0); + } + + if (byteCount > this._totalLength) { + throw new Error(`Cannot read so many bytes!`); + } + + if (this._chunks[0].byteLength === byteCount) { + // super fast path, precisely first chunk must be returned + const result = this._chunks.shift()!; + this._totalLength -= byteCount; + return result; + } + + if (this._chunks[0].byteLength > byteCount) { + // fast path, the reading is entirely within the first chunk + const result = this._chunks[0].slice(0, byteCount); + this._chunks[0] = this._chunks[0].slice(byteCount); + this._totalLength -= byteCount; + return result; + } + + let result = Buffer.allocUnsafe(byteCount); + let resultOffset = 0; + while (byteCount > 0) { + const chunk = this._chunks[0]; + if (chunk.byteLength > byteCount) { + // this chunk will survive + this._chunks[0] = chunk.slice(byteCount); + + chunk.copy(result, resultOffset, 0, byteCount); + resultOffset += byteCount; + this._totalLength -= byteCount; + byteCount -= byteCount; + } else { + // this chunk will be entirely read + this._chunks.shift(); + + chunk.copy(result, resultOffset, 0, chunk.byteLength); + resultOffset += chunk.byteLength; + this._totalLength -= chunk.byteLength; + byteCount -= chunk.byteLength; + } + } + return result; + } +} + /** * A message has the following format: * @@ -35,9 +108,8 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { private static readonly _headerLen = 4; private _isDisposed: boolean; - private _chunks: Buffer[]; + private _incomingData: ChunkStream; - private _firstChunkTimer: TimeoutTimer; private _socketDataListener: (data: Buffer) => void; private _socketEndListener: () => void; private _socketCloseListener: () => void; @@ -48,11 +120,9 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { private _onClose = new Emitter(); readonly onClose: Event = this._onClose.event; - constructor(private _socket: Socket, firstDataChunk?: Buffer) { + constructor(private _socket: Socket) { this._isDisposed = false; - this._chunks = []; - - let totalLength = 0; + this._incomingData = new ChunkStream(); const state = { readHead: true, @@ -61,24 +131,15 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { const acceptChunk = (data: Buffer) => { - this._chunks.push(data); - totalLength += data.length; + this._incomingData.acceptChunk(data); - while (totalLength > 0) { + while (this._incomingData.byteLength > 0) { if (state.readHead) { - // expecting header -> read 5bytes for header - // information: `bodyIsJson` and `bodyLen` - if (totalLength >= Protocol._headerLen) { - const all = Buffer.concat(this._chunks); - - state.bodyLen = all.readUInt32BE(0); + // expecting header -> read header + if (this._incomingData.byteLength >= Protocol._headerLen) { + state.bodyLen = this._incomingData.readUInt32BE(); state.readHead = false; - - const rest = all.slice(Protocol._headerLen); - totalLength = rest.length; - this._chunks = [rest]; - } else { break; } @@ -87,15 +148,8 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { if (!state.readHead) { // expecting body -> read bodyLen-bytes for // the actual message or wait for more data - if (totalLength >= state.bodyLen) { - - const all = Buffer.concat(this._chunks); - const buffer = all.slice(0, state.bodyLen); - - // 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]; + if (this._incomingData.byteLength >= state.bodyLen) { + const buffer = this._incomingData.read(state.bodyLen); state.bodyLen = -1; state.readHead = true; @@ -113,28 +167,12 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { } }; - const acceptFirstDataChunk = () => { - if (firstDataChunk && firstDataChunk.length > 0) { - let tmp = firstDataChunk; - firstDataChunk = undefined; - acceptChunk(tmp); - } - }; - - // Make sure to always handle the firstDataChunk if no more `data` event comes in - this._firstChunkTimer = new TimeoutTimer(); - this._firstChunkTimer.setIfNotSet(() => { - acceptFirstDataChunk(); - }, 0); - this._socketDataListener = (data: Buffer) => { - acceptFirstDataChunk(); acceptChunk(data); }; _socket.on('data', this._socketDataListener); this._socketEndListener = () => { - acceptFirstDataChunk(); }; _socket.on('end', this._socketEndListener); @@ -146,7 +184,6 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { dispose(): void { this._isDisposed = true; - this._firstChunkTimer.dispose(); this._socket.removeListener('data', this._socketDataListener); this._socket.removeListener('end', this._socketEndListener); this._socket.removeListener('close', this._socketCloseListener); @@ -156,8 +193,8 @@ export class Protocol implements IDisposable, IMessagePassingProtocol { this._socket.end(); } - getBuffer(): Buffer { - return Buffer.concat(this._chunks); + readEntireBuffer(): Buffer { + return this._incomingData.read(this._incomingData.byteLength); } send(buffer: Buffer): void { 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 439dce11f52..5288308dc37 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 @@ -85,39 +85,4 @@ suite('IPC, Socket Protocol', () => { }); }); }); - - test('can devolve to a socket and evolve again without losing data', () => { - let resolve: (v: void) => void; - let result = new Promise((_resolve, _reject) => { - resolve = _resolve; - }); - const sender = new Protocol(stream); - const receiver1 = new Protocol(stream); - - assert.equal(stream.listenerCount('data'), 2); - assert.equal(stream.listenerCount('end'), 2); - - receiver1.onMessage((msg) => { - assert.equal(JSON.parse(msg.toString()).value, 1); - - let buffer = receiver1.getBuffer(); - receiver1.dispose(); - - assert.equal(stream.listenerCount('data'), 1); - assert.equal(stream.listenerCount('end'), 1); - - const receiver2 = new Protocol(stream, buffer); - receiver2.onMessage((msg) => { - assert.equal(JSON.parse(msg.toString()).value, 2); - resolve(undefined); - }); - }); - - const msg1 = { value: 1 }; - const msg2 = { value: 2 }; - sender.send(Buffer.from(JSON.stringify(msg1))); - sender.send(Buffer.from(JSON.stringify(msg2))); - - return result; - }); }); From dfb934c319e1392c1db1101a4774e3e6172efaea Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 6 Mar 2019 10:17:07 +0100 Subject: [PATCH 277/290] Add a context key expression mapper --- .../platform/contextkey/common/contextkey.ts | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/contextkey/common/contextkey.ts b/src/vs/platform/contextkey/common/contextkey.ts index 6617af20f86..11d8132fe05 100644 --- a/src/vs/platform/contextkey/common/contextkey.ts +++ b/src/vs/platform/contextkey/common/contextkey.ts @@ -16,6 +16,14 @@ export const enum ContextKeyExprType { Regex = 6 } +export interface IContextKeyExprMapper { + mapDefined(key: string): ContextKeyDefinedExpr; + mapNot(key: string): ContextKeyNotExpr; + mapEquals(key: string, value: any): ContextKeyEqualsExpr; + mapNotEquals(key: string, value: any): ContextKeyNotEqualsExpr; + mapRegex(key: string, regexp: RegExp | null): ContextKeyRegexExpr; +} + export abstract class ContextKeyExpr { public static has(key: string): ContextKeyExpr { @@ -138,6 +146,7 @@ export abstract class ContextKeyExpr { public abstract normalize(): ContextKeyExpr | null; public abstract serialize(): string; public abstract keys(): string[]; + public abstract map(mapFnc: IContextKeyExprMapper): ContextKeyExpr; } function cmp(a: ContextKeyExpr, b: ContextKeyExpr): number { @@ -202,10 +211,14 @@ export class ContextKeyDefinedExpr implements ContextKeyExpr { public keys(): string[] { return [this.key]; } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr { + return mapFnc.mapDefined(this.key); + } } export class ContextKeyEqualsExpr implements ContextKeyExpr { - constructor(private key: string, private value: any) { + constructor(private readonly key: string, private readonly value: any) { } public getType(): ContextKeyExprType { @@ -263,6 +276,10 @@ export class ContextKeyEqualsExpr implements ContextKeyExpr { public keys(): string[] { return [this.key]; } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr { + return mapFnc.mapEquals(this.key, this.value); + } } export class ContextKeyNotEqualsExpr implements ContextKeyExpr { @@ -324,6 +341,10 @@ export class ContextKeyNotEqualsExpr implements ContextKeyExpr { public keys(): string[] { return [this.key]; } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr { + return mapFnc.mapNotEquals(this.key, this.value); + } } export class ContextKeyNotExpr implements ContextKeyExpr { @@ -366,6 +387,10 @@ export class ContextKeyNotExpr implements ContextKeyExpr { public keys(): string[] { return [this.key]; } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr { + return mapFnc.mapNot(this.key); + } } export class ContextKeyRegexExpr implements ContextKeyExpr { @@ -424,6 +449,10 @@ export class ContextKeyRegexExpr implements ContextKeyExpr { public keys(): string[] { return [this.key]; } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr { + return mapFnc.mapRegex(this.key, this.regexp); + } } export class ContextKeyAndExpr implements ContextKeyExpr { @@ -523,6 +552,10 @@ export class ContextKeyAndExpr implements ContextKeyExpr { } return result; } + + public map(mapFnc: IContextKeyExprMapper): ContextKeyExpr { + return new ContextKeyAndExpr(this.expr.map(expr => expr.map(mapFnc))); + } } export class RawContextKey extends ContextKeyDefinedExpr { From 1d345f07379fc958f6f9da8d63489030353c2a1d Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 6 Mar 2019 10:18:56 +0100 Subject: [PATCH 278/290] URI always needs to be revived after crossing ipc boundaries --- .../electron-browser/mainThreadTerminalService.ts | 5 +++-- src/vs/workbench/api/node/extHost.protocol.ts | 8 ++++---- src/vs/workbench/api/node/extHostTerminalService.ts | 12 ++++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts b/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts index 3f30d465934..8a1fc7d216d 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTerminalService.ts @@ -7,6 +7,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal'; import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto } from 'vs/workbench/api/node/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; +import { UriComponents, URI } from 'vs/base/common/uri'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -58,12 +59,12 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // when the extension host process goes down ? } - public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }> { + public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string | UriComponents, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }> { const shellLaunchConfig: IShellLaunchConfig = { name, executable: shellPath, args: shellArgs, - cwd, + cwd: typeof cwd === 'string' ? cwd : URI.revive(cwd), waitOnExit, ignoreConfigurationCwd: true, env, diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 53df36fbf27..8d094cf262a 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -368,7 +368,7 @@ export interface MainThreadProgressShape extends IDisposable { } export interface MainThreadTerminalServiceShape extends IDisposable { - $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string | URI, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }>; + $createTerminal(name?: string, shellPath?: string, shellArgs?: string[], cwd?: string | UriComponents, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean): Promise<{ id: number, name: string }>; $createTerminalRenderer(name: string): Promise; $dispose(terminalId: number): void; $hide(terminalId: number): void; @@ -527,7 +527,7 @@ export interface ExtHostUrlsShape { } export interface MainThreadWorkspaceShape extends IDisposable { - $startFileSearch(includePattern: string | undefined, includeFolder: URI | undefined, excludePatternOrDisregardExcludes: string | false | undefined, maxResults: number, token: CancellationToken): Promise; + $startFileSearch(includePattern: string | undefined, includeFolder: UriComponents | undefined, excludePatternOrDisregardExcludes: string | false | undefined, maxResults: number, token: CancellationToken): Promise; $startTextSearch(query: IPatternInfo, options: ITextQueryBuilderOptions, requestId: number, token: CancellationToken): Promise; $checkExists(includes: string[], token: CancellationToken): Promise; $saveAll(includeUntitled?: boolean): Promise; @@ -965,7 +965,7 @@ export interface ShellLaunchConfigDto { name?: string; executable?: string; args?: string[] | string; - cwd?: string | URI; + cwd?: string | UriComponents; env?: { [key: string]: string | null }; } @@ -978,7 +978,7 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalRendererInput(id: number, data: string): void; $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; - $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: URI, cols: number, rows: number): void; + $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number): void; $acceptProcessInput(id: number, data: string): void; $acceptProcessResize(id: number, cols: number, rows: number): void; $acceptProcessShutdown(id: number, immediate: boolean): void; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 070d8874c22..45d953bb808 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -13,7 +13,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/node/extHost.protocol'; import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; -import { EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal'; +import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { timeout } from 'vs/base/common/async'; import { sanitizeProcessEnvironment } from 'vs/base/common/processes'; @@ -411,7 +411,15 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } } - public async $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number): Promise { + public async $createProcess(id: number, shellLaunchConfigDto: ShellLaunchConfigDto, activeWorkspaceRootUriComponents: UriComponents, cols: number, rows: number): Promise { + const shellLaunchConfig: IShellLaunchConfig = { + name: shellLaunchConfigDto.name, + executable: shellLaunchConfigDto.executable, + args: shellLaunchConfigDto.args, + cwd: typeof shellLaunchConfigDto.cwd === 'string' ? shellLaunchConfigDto.cwd : URI.revive(shellLaunchConfigDto.cwd), + env: shellLaunchConfigDto.env + }; + // TODO: This function duplicates a lot of TerminalProcessManager.createProcess, ideally // they would be merged into a single implementation. const configProvider = await this._extHostConfiguration.getConfigProvider(); From 764d2e94873c299feb03a20dc1a8f584b1edc9ab Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 6 Mar 2019 10:28:54 +0100 Subject: [PATCH 279/290] fixes #67722 --- src/vs/base/browser/ui/tree/asyncDataTree.ts | 167 ++++++++---------- .../browser/ui/tree/asyncDataTree.test.ts | 137 ++++++++++++++ 2 files changed, 210 insertions(+), 94 deletions(-) diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 20e0bdf0bd4..21b5b7fdef7 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -17,24 +17,35 @@ import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView'; import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors'; import { toggleClass } from 'vs/base/browser/dom'; -const enum AsyncDataTreeNodeState { - Uninitialized = 'uninitialized', - Loaded = 'loaded', - Loading = 'loading' -} - interface IAsyncDataTreeNode { element: TInput | T; readonly parent: IAsyncDataTreeNode | null; readonly children: IAsyncDataTreeNode[]; readonly id?: string | null; - state: AsyncDataTreeNodeState; + loading: boolean; hasChildren: boolean; - needsRefresh: boolean; + stale: boolean; slow: boolean; disposed: boolean; } +interface IAsyncDataTreeNodeRequiredProps extends Partial> { + readonly element: TInput | T; + readonly parent: IAsyncDataTreeNode | null; + readonly hasChildren: boolean; +} + +function createAsyncDataTreeNode(props: IAsyncDataTreeNodeRequiredProps): IAsyncDataTreeNode { + return { + ...props, + children: [], + loading: false, + stale: true, + disposed: false, + slow: false + }; +} + function isAncestor(ancestor: IAsyncDataTreeNode, descendant: IAsyncDataTreeNode): boolean { if (!descendant.parent) { return false; @@ -236,7 +247,7 @@ function asTreeElement(node: IAsyncDataTreeNode, viewState return { element: node, - children: Iterator.map(Iterator.fromArray(node.children), child => asTreeElement(child, viewStateContext)), + children: node.hasChildren ? Iterator.map(Iterator.fromArray(node.children), child => asTreeElement(child, viewStateContext)) : [], collapsible: node.hasChildren, collapsed }; @@ -318,16 +329,11 @@ export class AsyncDataTree implements IDisposable this.tree = new ObjectTree(container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions); - this.root = { + this.root = createAsyncDataTreeNode({ element: undefined!, parent: null, - children: [], - state: AsyncDataTreeNodeState.Uninitialized, - hasChildren: true, - needsRefresh: false, - disposed: false, - slow: false - }; + hasChildren: true + }); if (this.identityProvider) { this.root = { @@ -426,7 +432,7 @@ export class AsyncDataTree implements IDisposable throw new Error('Tree input not set'); } - if (this.root.state === AsyncDataTreeNodeState.Loading) { + if (this.root.loading) { await this.subTreeRefreshPromises.get(this.root)!; await Event.toPromise(this._onDidRender.event); } @@ -477,20 +483,20 @@ export class AsyncDataTree implements IDisposable throw new Error('Tree input not set'); } - if (this.root.state === AsyncDataTreeNodeState.Loading) { + if (this.root.loading) { await this.subTreeRefreshPromises.get(this.root)!; await Event.toPromise(this._onDidRender.event); } const node = this.getDataNode(element); - if (node !== this.root && node.state !== AsyncDataTreeNodeState.Loading && !this.tree.isCollapsed(node)) { + if (node !== this.root && !node.loading && !this.tree.isCollapsed(node)) { return false; } const result = this.tree.expand(node === this.root ? null : node, recursive); - if (node.state === AsyncDataTreeNodeState.Loading) { + if (node.loading) { await this.subTreeRefreshPromises.get(node)!; await Event.toPromise(this._onDidRender.event); } @@ -651,39 +657,19 @@ export class AsyncDataTree implements IDisposable } private async doRefreshSubTree(node: IAsyncDataTreeNode, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext): Promise { - node.state = AsyncDataTreeNodeState.Loading; + node.loading = true; try { - await this.doRefreshNode(node, recursive, viewStateContext); + const childrenToRefresh = await this.doRefreshNode(node, recursive, viewStateContext); + node.stale = false; - if (recursive) { - const childrenToRefresh = node.children - .filter(child => { - if (child.needsRefresh) { - child.needsRefresh = false; - return true; - } - - // TODO@joao: is this still needed? - if (child.hasChildren && child.state === AsyncDataTreeNodeState.Loaded) { - return true; - } - - if (!viewStateContext || !viewStateContext.viewState.expanded || !child.id) { - return false; - } - - return viewStateContext.viewState.expanded.indexOf(child.id) > -1; - }); - - await Promise.all(childrenToRefresh.map(child => this.doRefreshSubTree(child, recursive, viewStateContext))); - } + await Promise.all(childrenToRefresh.map(child => this.doRefreshSubTree(child, recursive, viewStateContext))); } finally { - node.state = AsyncDataTreeNodeState.Loaded; + node.loading = false; } } - private async doRefreshNode(node: IAsyncDataTreeNode, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext): Promise { + private async doRefreshNode(node: IAsyncDataTreeNode, recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext): Promise[]> { node.hasChildren = !!this.dataSource.hasChildren(node.element!); let childrenPromise: Promise; @@ -704,16 +690,14 @@ export class AsyncDataTree implements IDisposable try { const children = await childrenPromise; - this.setChildren(node, children, recursive, viewStateContext); + return this.setChildren(node, children, recursive, viewStateContext); } catch (err) { - node.needsRefresh = true; - if (node !== this.root) { this.tree.collapse(node === this.root ? null : node); } if (isPromiseCanceledError(err)) { - return; + return []; } throw err; @@ -748,7 +732,7 @@ export class AsyncDataTree implements IDisposable } private _onDidChangeCollapseState({ node, deep }: ICollapseStateChangeEvent, any>): void { - if (!node.collapsed && (node.element.state === AsyncDataTreeNodeState.Uninitialized || node.element.needsRefresh)) { + if (!node.collapsed && node.element.stale) { if (deep) { this.collapse(node.element.element as T); } else { @@ -758,7 +742,12 @@ export class AsyncDataTree implements IDisposable } } - private setChildren(node: IAsyncDataTreeNode, childrenElements: T[], recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext): void { + private setChildren(node: IAsyncDataTreeNode, childrenElements: T[], recursive: boolean, viewStateContext?: IAsyncDataTreeViewStateContext): IAsyncDataTreeNode[] { + // perf: if the node was and still is a leaf, avoid all this hassle + if (node.children.length === 0 && childrenElements.length === 0) { + return []; + } + let nodeChildren: Map> | undefined; if (this.identityProvider) { @@ -769,67 +758,57 @@ export class AsyncDataTree implements IDisposable } } + let childrenToRefresh: IAsyncDataTreeNode[] = []; + const children = childrenElements.map>(element => { if (!this.identityProvider) { - const hasChildren = !!this.dataSource.hasChildren(element); - - return { + return createAsyncDataTreeNode({ element, parent: node, - children: [], - state: AsyncDataTreeNodeState.Uninitialized, - hasChildren, - needsRefresh: false, - disposed: false, - slow: false - }; + hasChildren: !!this.dataSource.hasChildren(element), + }); } const id = this.identityProvider.getId(element).toString(); const asyncDataTreeNode = nodeChildren!.get(id); - if (!asyncDataTreeNode) { - const childAsyncDataTreeNode: IAsyncDataTreeNode = { - element, - parent: node, - children: [], - id, - state: AsyncDataTreeNodeState.Uninitialized, - hasChildren: !!this.dataSource.hasChildren(element), - needsRefresh: false, - disposed: false, - slow: false - }; + if (asyncDataTreeNode) { + asyncDataTreeNode.element = element; + asyncDataTreeNode.stale = asyncDataTreeNode.stale || recursive; + asyncDataTreeNode.hasChildren = !!this.dataSource.hasChildren(element); - if (viewStateContext && viewStateContext.viewState.focus && viewStateContext.viewState.focus.indexOf(id) > -1) { - viewStateContext.focus.push(childAsyncDataTreeNode); + if (recursive && !this.tree.isCollapsed(asyncDataTreeNode)) { + childrenToRefresh.push(asyncDataTreeNode); } - if (viewStateContext && viewStateContext.viewState.selection && viewStateContext.viewState.selection.indexOf(id) > -1) { - viewStateContext.selection.push(childAsyncDataTreeNode); - } - - return childAsyncDataTreeNode; + return asyncDataTreeNode; } - asyncDataTreeNode.element = element; + const childAsyncDataTreeNode = createAsyncDataTreeNode({ + element, + parent: node, + id, + hasChildren: !!this.dataSource.hasChildren(element) + }); - const hasChildren = this.dataSource.hasChildren(asyncDataTreeNode.element); - - if (asyncDataTreeNode.state === AsyncDataTreeNodeState.Loaded || (asyncDataTreeNode.state !== AsyncDataTreeNodeState.Uninitialized && asyncDataTreeNode.hasChildren !== !!hasChildren)) { - asyncDataTreeNode.needsRefresh = true; + if (viewStateContext && viewStateContext.viewState.focus && viewStateContext.viewState.focus.indexOf(id) > -1) { + viewStateContext.focus.push(childAsyncDataTreeNode); } - asyncDataTreeNode.hasChildren = hasChildren; - return asyncDataTreeNode; + if (viewStateContext && viewStateContext.viewState.selection && viewStateContext.viewState.selection.indexOf(id) > -1) { + viewStateContext.selection.push(childAsyncDataTreeNode); + } + + if (viewStateContext && viewStateContext.viewState.expanded && viewStateContext.viewState.expanded.indexOf(id) > -1) { + childrenToRefresh.push(childAsyncDataTreeNode); + } + + return childAsyncDataTreeNode; }); - // perf: if the node was and still is a leaf, avoid all these expensive no-ops - if (node.children.length === 0 && childrenElements.length === 0) { - return; - } - node.children.splice(0, node.children.length, ...children); + + return childrenToRefresh; } private render(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): void { diff --git a/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts b/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts index 6ceccbd08dc..3c934126df9 100644 --- a/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts +++ b/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts @@ -189,4 +189,141 @@ suite('AsyncDataTree', function () { assert(hasClass(twistie, 'collapsed')); assert(tree.getNode().children[0].collapsed); }); + + test('issue #67722 - once resolved, refreshed collapsed nodes should only get children when expanded', async () => { + const container = document.createElement('div'); + container.style.width = '200px'; + container.style.height = '200px'; + + const delegate = new class implements IListVirtualDelegate { + getHeight() { return 20; } + getTemplateId(element: Element): string { return 'default'; } + }; + + const renderer = new class implements ITreeRenderer { + readonly templateId = 'default'; + renderTemplate(container: HTMLElement): HTMLElement { + return container; + } + renderElement(element: ITreeNode, index: number, templateData: HTMLElement): void { + templateData.textContent = element.element.id; + } + disposeTemplate(templateData: HTMLElement): void { + // noop + } + }; + + const getChildrenCalls: string[] = []; + const dataSource = new class implements IAsyncDataSource { + hasChildren(element: Element): boolean { + return !!element.children && element.children.length > 0; + } + getChildren(element: Element): Promise { + getChildrenCalls.push(element.id); + return Promise.resolve(element.children || []); + } + }; + + const identityProvider = new class implements IIdentityProvider { + getId(element: Element) { + return element.id; + } + }; + + const root: Element = { + id: 'root', + children: [{ + id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }] + }] + }; + + const _: (id: string) => Element = find.bind(null, root.children); + + const tree = new AsyncDataTree(container, delegate, [renderer], dataSource, { identityProvider }); + tree.layout(200); + + await tree.setInput(root); + assert(tree.getNode(_('a')).collapsed); + assert.deepStrictEqual(getChildrenCalls, ['root']); + + await tree.expand(_('a')); + assert(!tree.getNode(_('a')).collapsed); + assert.deepStrictEqual(getChildrenCalls, ['root', 'a']); + + tree.collapse(_('a')); + assert(tree.getNode(_('a')).collapsed); + assert.deepStrictEqual(getChildrenCalls, ['root', 'a']); + + await tree.updateChildren(); + assert(tree.getNode(_('a')).collapsed); + assert.deepStrictEqual(getChildrenCalls, ['root', 'a', 'root'], 'a should not be refreshed, since it\' collapsed'); + }); + + test('resolved collapsed nodes which lose children should lose twistie as well', async () => { + const container = document.createElement('div'); + container.style.width = '200px'; + container.style.height = '200px'; + + const delegate = new class implements IListVirtualDelegate { + getHeight() { return 20; } + getTemplateId(element: Element): string { return 'default'; } + }; + + const renderer = new class implements ITreeRenderer { + readonly templateId = 'default'; + renderTemplate(container: HTMLElement): HTMLElement { + return container; + } + renderElement(element: ITreeNode, index: number, templateData: HTMLElement): void { + templateData.textContent = element.element.id; + } + disposeTemplate(templateData: HTMLElement): void { + // noop + } + }; + + const dataSource = new class implements IAsyncDataSource { + hasChildren(element: Element): boolean { + return !!element.children && element.children.length > 0; + } + getChildren(element: Element): Promise { + return Promise.resolve(element.children || []); + } + }; + + const identityProvider = new class implements IIdentityProvider { + getId(element: Element) { + return element.id; + } + }; + + const root: Element = { + id: 'root', + children: [{ + id: 'a', children: [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }] + }] + }; + + const _: (id: string) => Element = find.bind(null, root.children); + + const tree = new AsyncDataTree(container, delegate, [renderer], dataSource, { identityProvider }); + tree.layout(200); + + await tree.setInput(root); + await tree.expand(_('a')); + + let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement; + assert(hasClass(twistie, 'collapsible')); + assert(!hasClass(twistie, 'collapsed')); + assert(!tree.getNode(_('a')).collapsed); + + tree.collapse(_('a')); + _('a').children = []; + await tree.updateChildren(root); + + twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement; + assert(!hasClass(twistie, 'collapsible')); + assert(!hasClass(twistie, 'collapsed')); + assert(tree.getNode(_('a')).collapsed); + }); }); \ No newline at end of file From e6bc6699a47f123533ea5338412cb6c780d0fdbb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 6 Mar 2019 10:50:07 +0100 Subject: [PATCH 280/290] strict null checks: extHostSCM --- src/tsconfig.strictNullChecks.json | 1 + src/vs/workbench/api/node/extHost.protocol.ts | 2 +- src/vs/workbench/api/node/extHostSCM.ts | 27 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 21cb5fb6cae..0815dc052f9 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -97,6 +97,7 @@ "./vs/workbench/api/node/extHostOutputService.ts", "./vs/workbench/api/node/extHostProgress.ts", "./vs/workbench/api/node/extHostQuickOpen.ts", + "./vs/workbench/api/node/extHostSCM.ts", "./vs/workbench/api/node/extHostSearch.fileIndex.ts", "./vs/workbench/api/node/extHostSearch.ts", "./vs/workbench/api/node/extHostStorage.ts", diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 8d094cf262a..0d20d99f8e1 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -582,7 +582,7 @@ export interface SCMProviderFeatures { count?: number; commitTemplate?: string; acceptInputCommand?: modes.Command; - statusBarCommands?: modes.Command[]; + statusBarCommands?: CommandDto[]; } export interface SCMGroupFeatures { diff --git a/src/vs/workbench/api/node/extHostSCM.ts b/src/vs/workbench/api/node/extHostSCM.ts index 226b62e4396..f0a48e6c2a5 100644 --- a/src/vs/workbench/api/node/extHostSCM.ts +++ b/src/vs/workbench/api/node/extHostSCM.ts @@ -10,7 +10,7 @@ import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { asPromise } from 'vs/base/common/async'; import { IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands'; -import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape } from './extHost.protocol'; +import { MainContext, MainThreadSCMShape, SCMRawResource, SCMRawResourceSplice, SCMRawResourceSplices, IMainContext, ExtHostSCMShape, CommandDto } from './extHost.protocol'; import { sortedDiff } from 'vs/base/common/arrays'; import { comparePaths } from 'vs/base/common/comparers'; import * as vscode from 'vscode'; @@ -23,7 +23,7 @@ type ProviderHandle = number; type GroupHandle = number; type ResourceStateHandle = number; -function getIconPath(decorations: vscode.SourceControlResourceThemableDecorations) { +function getIconPath(decorations?: vscode.SourceControlResourceThemableDecorations): string | undefined { if (!decorations) { return undefined; } else if (typeof decorations.iconPath === 'string') { @@ -60,7 +60,7 @@ function compareResourceStatesDecorations(a: vscode.SourceControlResourceDecorat } if (a.tooltip !== b.tooltip) { - return (a.tooltip || '').localeCompare(b.tooltip); + return (a.tooltip || '').localeCompare(b.tooltip || ''); } result = compareResourceThemableDecorations(a, b); @@ -205,7 +205,7 @@ export class ExtHostSCMInputBox implements vscode.SourceControlInputBox { return this._visible; } - set visible(visible: boolean | undefined) { + set visible(visible: boolean) { visible = !!visible; this._visible = visible; this._proxy.$setInputBoxVisibility(this._sourceControlHandle, visible); @@ -287,7 +287,7 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG return Promise.resolve(undefined); } - return asPromise(() => this._commands.executeCommand(command.command, ...command.arguments)); + return asPromise(() => this._commands.executeCommand(command.command, ...(command.arguments || []))); } _takeResourceStateSnapshot(): SCMRawResourceSplice[] { @@ -309,11 +309,11 @@ class ExtHostSourceControlResourceGroup implements vscode.SourceControlResourceG this._resourceStatesCommandsMap.set(handle, r.command); } - if (lightIconPath || darkIconPath) { + if (lightIconPath) { icons.push(lightIconPath); } - if (darkIconPath !== lightIconPath) { + if (darkIconPath && (darkIconPath !== lightIconPath)) { icons.push(darkIconPath); } @@ -442,7 +442,7 @@ class ExtHostSourceControl implements vscode.SourceControl { this._statusBarCommands = statusBarCommands; - const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c)); + const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c)) as CommandDto[]; this._proxy.$updateSourceControl(this.handle, { statusBarCommands: internal }); } @@ -599,14 +599,12 @@ export class ExtHostSCM implements ExtHostSCMShape { } // Deprecated - getLastInputBox(extension: IExtensionDescription): ExtHostSCMInputBox { + getLastInputBox(extension: IExtensionDescription): ExtHostSCMInputBox | undefined { this.logService.trace('ExtHostSCM#getLastInputBox', extension.identifier.value); const sourceControls = this._sourceControlsByExtension.get(ExtensionIdentifier.toKey(extension.identifier)); const sourceControl = sourceControls && sourceControls[sourceControls.length - 1]; - const inputBox = sourceControl && sourceControl.inputBox; - - return inputBox; + return sourceControl && sourceControl.inputBox; } $provideOriginalResource(sourceControlHandle: number, uriComponents: UriComponents, token: CancellationToken): Promise { @@ -615,11 +613,12 @@ export class ExtHostSCM implements ExtHostSCMShape { const sourceControl = this._sourceControls.get(sourceControlHandle); - if (!sourceControl || !sourceControl.quickDiffProvider) { + if (!sourceControl || !sourceControl.quickDiffProvider || !sourceControl.quickDiffProvider.provideOriginalResource) { return Promise.resolve(null); } - return asPromise(() => sourceControl.quickDiffProvider.provideOriginalResource(uri, token)); + return asPromise(() => sourceControl.quickDiffProvider!.provideOriginalResource!(uri, token)) + .then(r => r || null); } $onInputBoxValueChange(sourceControlHandle: number, value: string): Promise { From df93a3767fc74bd8e089ee64774e886e869f4a17 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 6 Mar 2019 11:47:05 +0100 Subject: [PATCH 281/290] fixes #69589 --- src/vs/workbench/browser/contextkeys.ts | 8 ++++++-- src/vs/workbench/browser/parts/editor/editorActions.ts | 2 +- src/vs/workbench/common/viewlet.ts | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/contextkeys.ts b/src/vs/workbench/browser/contextkeys.ts index 79e2037b343..e5e53f47ef6 100644 --- a/src/vs/workbench/browser/contextkeys.ts +++ b/src/vs/workbench/browser/contextkeys.ts @@ -17,7 +17,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { EditorGroupsServiceImpl } from 'vs/workbench/browser/parts/editor/editor'; -import { SidebarVisibleContext } from 'vs/workbench/common/viewlet'; +import { SidebarVisibleContext, SideBarVisibleContext } from 'vs/workbench/common/viewlet'; import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; @@ -39,6 +39,8 @@ export class WorkbenchContextKeysHandler extends Disposable { private inZenModeContext: IContextKey; private sideBarVisibleContext: IContextKey; + //TODO@Isidor remove in May + private sidebarVisibleContext: IContextKey; constructor( @IContextKeyService private contextKeyService: IContextKeyService, @@ -127,7 +129,8 @@ export class WorkbenchContextKeysHandler extends Disposable { this.inZenModeContext = InEditorZenModeContext.bindTo(this.contextKeyService); // Sidebar - this.sideBarVisibleContext = SidebarVisibleContext.bindTo(this.contextKeyService); + this.sideBarVisibleContext = SideBarVisibleContext.bindTo(this.contextKeyService); + this.sidebarVisibleContext = SidebarVisibleContext.bindTo(this.contextKeyService); } private updateEditorContextKeys(): void { @@ -204,5 +207,6 @@ export class WorkbenchContextKeysHandler extends Disposable { private updateSideBarContextKeys(): void { this.sideBarVisibleContext.set(this.partService.isVisible(Parts.SIDEBAR_PART)); + this.sidebarVisibleContext.set(this.partService.isVisible(Parts.SIDEBAR_PART)); } } \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 205fdcaac49..0ef54f44bf5 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -882,7 +882,7 @@ export class ResetGroupSizesAction extends Action { export class MaximizeGroupAction extends Action { static readonly ID = 'workbench.action.maximizeEditor'; - static readonly LABEL = nls.localize('maximizeEditor', "Maximize Editor Group and Hide Sidebar"); + static readonly LABEL = nls.localize('maximizeEditor', "Maximize Editor Group and Hide Side Bar"); constructor( id: string, diff --git a/src/vs/workbench/common/viewlet.ts b/src/vs/workbench/common/viewlet.ts index b213967decd..09836ae5e8a 100644 --- a/src/vs/workbench/common/viewlet.ts +++ b/src/vs/workbench/common/viewlet.ts @@ -7,6 +7,7 @@ import { IComposite } from 'vs/workbench/common/composite'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; export const SidebarVisibleContext = new RawContextKey('sidebarVisible', false); +export const SideBarVisibleContext = new RawContextKey('sideBarVisible', false); export const SidebarFocusContext = new RawContextKey('sideBarFocus', false); export const ActiveViewletContext = new RawContextKey('activeViewlet', ''); From 97efb5af57f4454fb1f1866ce54e277eb17ef935 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Mar 2019 12:03:03 +0100 Subject: [PATCH 282/290] fix #68421 --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 3679da9592b..8eddb0f8231 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "gulp-rename": "^1.2.0", "gulp-replace": "^0.5.4", "gulp-shell": "^0.6.5", - "gulp-tsb": "2.0.6", + "gulp-tsb": "2.0.7", "gulp-tslint": "^8.1.3", "gulp-uglify": "^3.0.0", "gulp-vinyl-zip": "^2.1.2", @@ -150,4 +150,4 @@ "windows-mutex": "0.2.1", "windows-process-tree": "0.2.3" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 654114c0663..53dc4477514 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3944,10 +3944,10 @@ gulp-symdest@^1.1.1: queue "^3.1.0" vinyl-fs "^2.4.3" -gulp-tsb@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/gulp-tsb/-/gulp-tsb-2.0.6.tgz#2f8fbee9a81cf0da088744d6da2bca457f2893d1" - integrity sha512-tSIAPfU9rhbtwMgRWopipWFx3NZg943bCLPcP3LxQJ4KUkSdPVc2ZivCibMojw/7HwJUMjLWQ2NCN0yStTQP0g== +gulp-tsb@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/gulp-tsb/-/gulp-tsb-2.0.7.tgz#0e8c5cc20643d304979a59e90a6448260b314eba" + integrity sha512-9cllqseEkotum/aWHnCTQX/ATD3kyEi1aVzkGp0AEe768uNuU1DqPzRxvyVrfuIPcdYUUvtvmKvEvgIMffNmNA== dependencies: ansi-colors "^1.0.1" fancy-log "^1.3.2" From cd816afcc9991de89ab8dd28cab73b47747ea2ea Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Mar 2019 12:24:41 +0100 Subject: [PATCH 283/290] Take static arguments for the view descriptor ctor --- .../api/browser/viewsExtensionPoint.ts | 2 +- .../browser/parts/views/viewsViewlet.ts | 2 +- src/vs/workbench/common/views.ts | 3 +-- .../electron-browser/debug.contribution.ts | 10 ++++---- .../electron-browser/extensionsViewlet.ts | 22 ++++++++--------- .../contrib/files/browser/explorerViewlet.ts | 6 ++--- .../outline/browser/outline.contribution.ts | 2 +- .../contrib/scm/browser/scmViewlet.ts | 2 +- .../test/browser/parts/views/views.test.ts | 24 +++++++++---------- 9 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 03232b7c297..07aabc3588e 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -377,7 +377,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { const viewDescriptor = { id: item.id, name: item.name, - ctor: CustomTreeViewPanel, + ctorDescriptor: { ctor: CustomTreeViewPanel }, when: ContextKeyExpr.deserialize(item.when), canToggleVisibility: true, collapsed: this.showCollapsed(container), diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index 55b19d00586..804e934a8ce 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -178,7 +178,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView } protected createView(viewDescriptor: IViewDescriptor, options: IViewletViewOptions): ViewletPanel { - return this.instantiationService.createInstance(viewDescriptor.ctor, options) as ViewletPanel; + return (this.instantiationService as any).createInstance(viewDescriptor.ctorDescriptor.ctor, ...(viewDescriptor.ctorDescriptor.arguments || []), options) as ViewletPanel; } protected getView(id: string): ViewletPanel { diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 7d08589c1a7..236ffeacaa2 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -121,8 +121,7 @@ export interface IViewDescriptor { readonly name: string; - // TODO@Sandeep do we really need this?! - readonly ctor: any; + readonly ctorDescriptor: { ctor: any, arguments?: any[] }; readonly when?: ContextKeyExpr; diff --git a/src/vs/workbench/contrib/debug/electron-browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/electron-browser/debug.contribution.ts index fde17ef6833..631ccbbc368 100644 --- a/src/vs/workbench/contrib/debug/electron-browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/electron-browser/debug.contribution.ts @@ -112,11 +112,11 @@ Registry.as(PanelExtensions.Panels).registerPanel(new PanelDescri Registry.as(PanelExtensions.Panels).setDefaultPanelId(REPL_ID); // Register default debug views -ViewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctor: VariablesView, order: 10, weight: 40, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusVariablesView' } }], VIEW_CONTAINER); -ViewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctor: WatchExpressionsView, order: 20, weight: 10, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusWatchView' } }], VIEW_CONTAINER); -ViewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctor: CallStackView, order: 30, weight: 30, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusCallStackView' } }], VIEW_CONTAINER); -ViewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctor: BreakpointsView, order: 40, weight: 20, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' } }], VIEW_CONTAINER); -ViewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctor: LoadedScriptsView, order: 35, weight: 5, canToggleVisibility: true, collapsed: true, when: CONTEXT_LOADED_SCRIPTS_SUPPORTED }], VIEW_CONTAINER); +ViewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctorDescriptor: { ctor: VariablesView }, order: 10, weight: 40, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusVariablesView' } }], VIEW_CONTAINER); +ViewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctorDescriptor: { ctor: WatchExpressionsView }, order: 20, weight: 10, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusWatchView' } }], VIEW_CONTAINER); +ViewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctorDescriptor: { ctor: CallStackView }, order: 30, weight: 30, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusCallStackView' } }], VIEW_CONTAINER); +ViewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctorDescriptor: { ctor: BreakpointsView }, order: 40, weight: 20, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' } }], VIEW_CONTAINER); +ViewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctorDescriptor: { ctor: LoadedScriptsView }, order: 35, weight: 5, canToggleVisibility: true, collapsed: true, when: CONTEXT_LOADED_SCRIPTS_SUPPORTED }], VIEW_CONTAINER); // register action to open viewlet const registry = Registry.as(WorkbenchActionRegistryExtensions.WorkbenchActions); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts index 1a2d50168ba..215268085ae 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts @@ -114,7 +114,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: ExtensionsListView, + ctorDescriptor: { ctor: ExtensionsListView }, when: ContextKeyExpr.and(ContextKeyExpr.has('searchExtensions'), ContextKeyExpr.not('searchInstalledExtensions'), ContextKeyExpr.not('searchBuiltInExtensions'), ContextKeyExpr.not('recommendedExtensions'), ContextKeyExpr.not('groupByServersContext')), weight: 100 }; @@ -127,7 +127,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: EnabledExtensionsView, + ctorDescriptor: { ctor: EnabledExtensionsView }, when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('hasInstalledExtensions')), weight: 40, canToggleVisibility: true, @@ -142,7 +142,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: DisabledExtensionsView, + ctorDescriptor: { ctor: DisabledExtensionsView }, when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('hasInstalledExtensions')), weight: 10, canToggleVisibility: true, @@ -158,7 +158,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: ExtensionsListView, + ctorDescriptor: { ctor: ExtensionsListView }, when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.not('hasInstalledExtensions')), weight: 60, order: 1 @@ -169,7 +169,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return [{ id: `server.extensionsList.${server.authority}`, name: server.label, - ctor: GroupByServerExtensionsView, + ctorDescriptor: { ctor: GroupByServerExtensionsView }, when: ContextKeyExpr.has('groupByServersContext'), weight: 100 }]; @@ -183,7 +183,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: DefaultRecommendedExtensionsView, + ctorDescriptor: { ctor: DefaultRecommendedExtensionsView }, when: ContextKeyExpr.and(ContextKeyExpr.not('searchExtensions'), ContextKeyExpr.has('defaultRecommendedExtensions')), weight: 40, order: 2, @@ -198,7 +198,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: RecommendedExtensionsView, + ctorDescriptor: { ctor: RecommendedExtensionsView }, when: ContextKeyExpr.has('recommendedExtensions'), weight: 50, canToggleVisibility: true, @@ -213,7 +213,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: WorkspaceRecommendedExtensionsView, + ctorDescriptor: { ctor: WorkspaceRecommendedExtensionsView }, when: ContextKeyExpr.and(ContextKeyExpr.has('recommendedExtensions'), ContextKeyExpr.has('nonEmptyWorkspace')), weight: 50, canToggleVisibility: true, @@ -226,7 +226,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: BuiltInExtensionsView, + ctorDescriptor: { ctor: BuiltInExtensionsView }, when: ContextKeyExpr.has('searchBuiltInExtensions'), weight: 100, canToggleVisibility: true @@ -238,7 +238,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: BuiltInThemesExtensionsView, + ctorDescriptor: { ctor: BuiltInThemesExtensionsView }, when: ContextKeyExpr.has('searchBuiltInExtensions'), weight: 100, canToggleVisibility: true @@ -250,7 +250,7 @@ export class ExtensionsViewletViewsContribution implements IWorkbenchContributio return { id, name: viewIdNameMappings[id], - ctor: BuiltInBasicsExtensionsView, + ctorDescriptor: { ctor: BuiltInBasicsExtensionsView }, when: ContextKeyExpr.has('searchBuiltInExtensions'), weight: 100, canToggleVisibility: true diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index b8c1d34f383..4ba23bcf745 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -99,7 +99,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor return { id: OpenEditorsView.ID, name: OpenEditorsView.NAME, - ctor: OpenEditorsView, + ctorDescriptor: { ctor: OpenEditorsView }, order: 0, when: OpenEditorsVisibleCondition, canToggleVisibility: true, @@ -114,7 +114,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor return { id: EmptyView.ID, name: EmptyView.NAME, - ctor: EmptyView, + ctorDescriptor: { ctor: EmptyView }, order: 1, canToggleVisibility: false }; @@ -124,7 +124,7 @@ export class ExplorerViewletViewsContribution extends Disposable implements IWor return { id: ExplorerView.ID, name: localize('folders', "Folders"), - ctor: ExplorerView, + ctorDescriptor: { ctor: ExplorerView }, order: 1, canToggleVisibility: false }; diff --git a/src/vs/workbench/contrib/outline/browser/outline.contribution.ts b/src/vs/workbench/contrib/outline/browser/outline.contribution.ts index 7ac9a19b96f..8e787b1d4a6 100644 --- a/src/vs/workbench/contrib/outline/browser/outline.contribution.ts +++ b/src/vs/workbench/contrib/outline/browser/outline.contribution.ts @@ -14,7 +14,7 @@ import { OutlineConfigKeys, OutlineViewId } from 'vs/editor/contrib/documentSymb const _outlineDesc = { id: OutlineViewId, name: localize('name', "Outline"), - ctor: OutlinePanel, + ctorDescriptor: { ctor: OutlinePanel }, canToggleVisibility: true, hideByDefault: false, collapsed: true, diff --git a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts index 39eeddba79a..203d662dfb5 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewlet.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewlet.ts @@ -1366,7 +1366,7 @@ export class SCMViewlet extends PanelViewlet implements IViewModel, IViewsViewle const panelsToAdd: { panel: ViewletPanel, size: number, index: number }[] = []; for (const { viewDescriptor, collapsed, index, size } of added) { - const panel = this.instantiationService.createInstance(viewDescriptor.ctor, { + const panel = this.instantiationService.createInstance(viewDescriptor.ctorDescriptor.ctor, { id: viewDescriptor.id, title: viewDescriptor.name, actionRunner: this.getActionRunner(), diff --git a/src/vs/workbench/test/browser/parts/views/views.test.ts b/src/vs/workbench/test/browser/parts/views/views.test.ts index 11fd665875f..5b0dd4cc9af 100644 --- a/src/vs/workbench/test/browser/parts/views/views.test.ts +++ b/src/vs/workbench/test/browser/parts/views/views.test.ts @@ -63,7 +63,7 @@ suite('ContributableViewsModel', () => { const viewDescriptor: IViewDescriptor = { id: 'view1', - ctor: null, + ctorDescriptor: null, name: 'Test View 1' }; @@ -89,7 +89,7 @@ suite('ContributableViewsModel', () => { const viewDescriptor: IViewDescriptor = { id: 'view1', - ctor: null, + ctorDescriptor: null, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; @@ -128,8 +128,8 @@ suite('ContributableViewsModel', () => { const model = new ContributableViewsModel(container, viewsService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, name: 'Test View 1' }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, name: 'Test View 2', when: ContextKeyExpr.equals('showview2', true) }; + const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null, name: 'Test View 1' }; + const view2: IViewDescriptor = { id: 'view2', ctorDescriptor: null, name: 'Test View 2', when: ContextKeyExpr.equals('showview2', true) }; ViewsRegistry.registerViews([view1, view2], container); assert.deepEqual(model.visibleViewDescriptors, [view1], 'only view1 should be visible'); @@ -151,8 +151,8 @@ suite('ContributableViewsModel', () => { const model = new ContributableViewsModel(container, viewsService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, name: 'Test View 2' }; + const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; + const view2: IViewDescriptor = { id: 'view2', ctorDescriptor: null, name: 'Test View 2' }; ViewsRegistry.registerViews([view1, view2], container); assert.deepEqual(model.visibleViewDescriptors, [view2], 'only view2 should be visible'); @@ -174,9 +174,9 @@ suite('ContributableViewsModel', () => { const model = new ContributableViewsModel(container, viewsService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, name: 'Test View 1', canToggleVisibility: true }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, name: 'Test View 2', canToggleVisibility: true }; - const view3: IViewDescriptor = { id: 'view3', ctor: null, name: 'Test View 3', canToggleVisibility: true }; + const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null, name: 'Test View 1', canToggleVisibility: true }; + const view2: IViewDescriptor = { id: 'view2', ctorDescriptor: null, name: 'Test View 2', canToggleVisibility: true }; + const view3: IViewDescriptor = { id: 'view3', ctorDescriptor: null, name: 'Test View 3', canToggleVisibility: true }; ViewsRegistry.registerViews([view1, view2, view3], container); assert.deepEqual(model.visibleViewDescriptors, [view1, view2, view3]); @@ -219,9 +219,9 @@ suite('ContributableViewsModel', () => { const model = new ContributableViewsModel(container, viewsService); const seq = new ViewDescriptorSequence(model); - const view1: IViewDescriptor = { id: 'view1', ctor: null, name: 'Test View 1' }; - const view2: IViewDescriptor = { id: 'view2', ctor: null, name: 'Test View 2' }; - const view3: IViewDescriptor = { id: 'view3', ctor: null, name: 'Test View 3' }; + const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null, name: 'Test View 1' }; + const view2: IViewDescriptor = { id: 'view2', ctorDescriptor: null, name: 'Test View 2' }; + const view3: IViewDescriptor = { id: 'view3', ctorDescriptor: null, name: 'Test View 3' }; ViewsRegistry.registerViews([view1, view2, view3], container); assert.deepEqual(model.visibleViewDescriptors, [view1, view2, view3], 'model views should be OK'); From 4159cb41d37ad8844264b266e56082d49ac78044 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 6 Mar 2019 12:38:55 +0100 Subject: [PATCH 284/290] Fix #69205 --- src/vs/platform/files/common/files.ts | 58 +----------------- .../output/electron-browser/outputServices.ts | 61 +++++++++++++++++-- .../configuration/node/configuration.ts | 45 +++++++++----- 3 files changed, 89 insertions(+), 75 deletions(-) diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index 069e926bb47..fa87bbd829f 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -8,68 +8,14 @@ import { URI } from 'vs/base/common/uri'; import * as glob from 'vs/base/common/glob'; import { isLinux } from 'vs/base/common/platform'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Event } from 'vs/base/common/event'; import { startsWithIgnoreCase } from 'vs/base/common/strings'; -import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; +import { IDisposable } from 'vs/base/common/lifecycle'; import { isEqualOrParent, isEqual } from 'vs/base/common/resources'; import { isUndefinedOrNull } from 'vs/base/common/types'; -import { ThrottledDelayer } from 'vs/base/common/async'; export const IFileService = createDecorator('fileService'); -export class FileListener extends Disposable { - - private readonly _onDidContentChange = new Emitter(); - readonly onDidContentChange: Event = this._onDidContentChange.event; - - private watching: boolean = false; - private delayer: ThrottledDelayer; - private etag: string | undefined; - - constructor( - private readonly file: URI, - private readonly fileService: IFileService - ) { - super(); - this.delayer = new ThrottledDelayer(500); - } - - watch(eTag?: string): void { - if (!this.watching) { - this.etag = eTag; - this.poll(); - this.watching = true; - } - } - - private poll(): void { - const loop = () => this.doWatch().then(() => this.poll()); - this.delayer.trigger(loop); - } - - private doWatch(): Promise { - return this.fileService.resolveFile(this.file) - .then(stat => { - if (stat.etag !== this.etag) { - this.etag = stat.etag; - this._onDidContentChange.fire(stat); - } - }); - } - - unwatch(): void { - if (this.watching) { - this.delayer.cancel(); - this.watching = false; - } - } - - dispose(): void { - this.unwatch(); - super.dispose(); - } -} - export interface IResourceEncodings { getWriteEncoding(resource: URI, preferredEncoding?: string): string; } diff --git a/src/vs/workbench/contrib/output/electron-browser/outputServices.ts b/src/vs/workbench/contrib/output/electron-browser/outputServices.ts index 897620d45f8..60db5a4544d 100644 --- a/src/vs/workbench/contrib/output/electron-browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/electron-browser/outputServices.ts @@ -26,7 +26,7 @@ import { IModeService } from 'vs/editor/common/services/modeService'; import { RunOnceScheduler, ThrottledDelayer } from 'vs/base/common/async'; import { EditOperation } from 'vs/editor/common/core/editOperation'; import { Position } from 'vs/editor/common/core/position'; -import { IFileService, FileListener } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { IPanel } from 'vs/workbench/common/panel'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -277,12 +277,65 @@ class OutputChannelBackedByFile extends AbstractFileOutputChannel implements Out } } +class OutputFileListener extends Disposable { + + private readonly _onDidContentChange = new Emitter(); + readonly onDidContentChange: Event = this._onDidContentChange.event; + + private watching: boolean = false; + private syncDelayer: ThrottledDelayer; + private etag: string | undefined; + + constructor( + private readonly file: URI, + private readonly fileService: IFileService + ) { + super(); + this.syncDelayer = new ThrottledDelayer(500); + } + + watch(eTag: string | undefined): void { + if (!this.watching) { + this.etag = eTag; + this.poll(); + this.watching = true; + } + } + + private poll(): void { + const loop = () => this.doWatch().then(() => this.poll()); + this.syncDelayer.trigger(loop); + } + + private doWatch(): Promise { + return this.fileService.resolveFile(this.file) + .then(stat => { + if (stat.etag !== this.etag) { + this.etag = stat.etag; + this._onDidContentChange.fire(stat.size); + } + }); + } + + unwatch(): void { + if (this.watching) { + this.syncDelayer.cancel(); + this.watching = false; + } + } + + dispose(): void { + this.unwatch(); + super.dispose(); + } +} + /** * An output channel driven by a file and does not support appending messages. */ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChannel { - private readonly fileHandler: FileListener; + private readonly fileHandler: OutputFileListener; private updateInProgress: boolean = false; private etag: string | undefined = ''; @@ -297,8 +350,8 @@ class FileOutputChannel extends AbstractFileOutputChannel implements OutputChann ) { super(outputChannelDescriptor, modelUri, fileService, modelService, modeService); - this.fileHandler = this._register(new FileListener(this.file, this.fileService)); - this._register(this.fileHandler.onDidContentChange(({ size }) => this.update(size))); + this.fileHandler = this._register(new OutputFileListener(this.file, this.fileService)); + this._register(this.fileHandler.onDidContentChange(size => this.update(size))); this._register(toDisposable(() => this.fileHandler.unwatch())); } diff --git a/src/vs/workbench/services/configuration/node/configuration.ts b/src/vs/workbench/services/configuration/node/configuration.ts index cf439e7a9ef..b10f358735a 100644 --- a/src/vs/workbench/services/configuration/node/configuration.ts +++ b/src/vs/workbench/services/configuration/node/configuration.ts @@ -12,7 +12,7 @@ import * as errors from 'vs/base/common/errors'; import * as collections from 'vs/base/common/collections'; import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; import { RunOnceScheduler, Delayer } from 'vs/base/common/async'; -import { FileChangeType, FileChangesEvent, IContent, IFileService, FileListener } from 'vs/platform/files/common/files'; +import { FileChangeType, FileChangesEvent, IContent, IFileService } from 'vs/platform/files/common/files'; import { ConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, FolderSettingsModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY } from 'vs/workbench/services/configuration/common/configuration'; @@ -219,21 +219,33 @@ class FileServiceBasedWorkspaceConfiguration extends AbstractWorkspaceConfigurat private workspaceConfig: URI | null = null; private readonly reloadConfigurationScheduler: RunOnceScheduler; - private fileListener: FileListener | null; - private fileListenerDisposables: IDisposable[] = []; constructor(private fileService: IFileService, from?: IWorkspaceConfiguration) { super(from); this.workspaceConfig = from && from.workspaceIdentifier ? from.workspaceIdentifier.configPath : null; + this._register(fileService.onFileChanges(e => this.handleWorkspaceFileEvents(e))); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50)); - this.listenToWorkspaceConfigurationFile(); - this._register(toDisposable(() => dispose(this.fileListenerDisposables))); + this.watchWorkspaceConfigurationFile(); + this._register(toDisposable(() => this.unWatchWorkspaceConfigurtionFile())); + } + + private watchWorkspaceConfigurationFile(): void { + if (this.workspaceConfig) { + this.fileService.watchFileChanges(this.workspaceConfig); + } + } + + private unWatchWorkspaceConfigurtionFile(): void { + if (this.workspaceConfig) { + this.fileService.unwatchFileChanges(this.workspaceConfig); + } } protected loadWorkspaceConfigurationContents(workspaceIdentifier: IWorkspaceIdentifier): Promise { if (!(this.workspaceConfig && resources.isEqual(this.workspaceConfig, workspaceIdentifier.configPath))) { + this.unWatchWorkspaceConfigurtionFile(); this.workspaceConfig = workspaceIdentifier.configPath; - this.listenToWorkspaceConfigurationFile(); + this.watchWorkspaceConfigurationFile(); } return this.fileService.resolveContent(this.workspaceConfig) .then(content => content.value, e => { @@ -242,16 +254,19 @@ class FileServiceBasedWorkspaceConfiguration extends AbstractWorkspaceConfigurat }); } - private listenToWorkspaceConfigurationFile(): void { - if (this.fileListener) { - this.fileListenerDisposables = dispose(this.fileListenerDisposables); - this.fileListener = null; - } + private handleWorkspaceFileEvents(event: FileChangesEvent): void { if (this.workspaceConfig) { - this.fileListener = new FileListener(this.workspaceConfig, this.fileService); - this.fileListenerDisposables.push(this.fileListener); - this.fileListener.watch(); - this.fileListener.onDidContentChange(() => this.reloadConfigurationScheduler.schedule(), this, this.fileListenerDisposables); + const events = event.changes; + + let affectedByChanges = false; + // Find changes that affect workspace file + for (let i = 0, len = events.length; i < len && !affectedByChanges; i++) { + affectedByChanges = resources.isEqual(this.workspaceConfig, events[i].resource); + } + + if (affectedByChanges) { + this.reloadConfigurationScheduler.schedule(); + } } } } From 1b681fd98dc47888ee11764bfb7d7b6871ffe036 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 6 Mar 2019 12:43:19 +0100 Subject: [PATCH 285/290] showItemInFolder with URI --- src/vs/platform/windows/common/windows.ts | 2 +- src/vs/platform/windows/electron-main/windowsService.ts | 6 ++++-- src/vs/platform/windows/node/windowsIpc.ts | 4 ++-- src/vs/workbench/browser/parts/titlebar/titlebarPart.ts | 2 +- .../extensions/electron-browser/extensionsActions.ts | 6 +++--- .../contrib/files/browser/editors/binaryFileEditor.ts | 2 +- src/vs/workbench/contrib/files/browser/fileCommands.ts | 4 ++-- src/vs/workbench/contrib/logs/common/logsActions.ts | 3 ++- .../contrib/performance/electron-browser/startupProfiler.ts | 3 ++- src/vs/workbench/test/workbenchTestServices.ts | 2 +- 10 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index e28ca55477a..365c9200472 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -155,7 +155,7 @@ export interface IWindowsService { getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>; getWindowCount(): Promise; log(severity: string, ...messages: string[]): Promise; - showItemInFolder(path: string): Promise; + showItemInFolder(path: URI): Promise; getActiveWindowId(): Promise; // This needs to be handled from browser process to prevent diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index 016c59a3f20..33d89510c79 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -324,10 +324,12 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable console[severity].apply(console, ...messages); } - async showItemInFolder(path: string): Promise { + async showItemInFolder(path: URI): Promise { this.logService.trace('windowsService#showItemInFolder'); - shell.showItemInFolder(path); + if (path.scheme === Schemas.file) { + shell.showItemInFolder(path.fsPath); + } } async getActiveWindowId(): Promise { diff --git a/src/vs/platform/windows/node/windowsIpc.ts b/src/vs/platform/windows/node/windowsIpc.ts index 12b741138c0..bc726d9460e 100644 --- a/src/vs/platform/windows/node/windowsIpc.ts +++ b/src/vs/platform/windows/node/windowsIpc.ts @@ -95,7 +95,7 @@ export class WindowsChannel implements IServerChannel { case 'toggleSharedProcess': return this.service.toggleSharedProcess(); case 'quit': return this.service.quit(); case 'log': return this.service.log(arg[0], arg[1]); - case 'showItemInFolder': return this.service.showItemInFolder(arg); + case 'showItemInFolder': return this.service.showItemInFolder(URI.revive(arg)); case 'getActiveWindowId': return this.service.getActiveWindowId(); case 'openExternal': return this.service.openExternal(arg); case 'startCrashReporter': return this.service.startCrashReporter(arg); @@ -309,7 +309,7 @@ export class WindowsChannelClient implements IWindowsService { return this.channel.call('log', [severity, messages]); } - showItemInFolder(path: string): Promise { + showItemInFolder(path: URI): Promise { return this.channel.call('showItemInFolder', path); } diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts index 9bb6b629cf9..d4fa3b061d8 100644 --- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts +++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts @@ -617,7 +617,7 @@ class ShowItemInFolderAction extends Action { } run(): Promise { - return this.windowsService.showItemInFolder(this.path); + return this.windowsService.showItemInFolder(URI.file(this.path)); } } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts index 32eb8cc1048..f063733ef90 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts @@ -2529,11 +2529,11 @@ export class OpenExtensionsFolderAction extends Action { const extensionsHome = URI.file(this.environmentService.extensionsPath); return Promise.resolve(this.fileService.resolveFile(extensionsHome)).then(file => { - let itemToShow: string; + let itemToShow: URI; if (file.children && file.children.length > 0) { - itemToShow = file.children[0].resource.fsPath; + itemToShow = file.children[0].resource; } else { - itemToShow = extensionsHome.fsPath; + itemToShow = extensionsHome; } return this.windowsService.showItemInFolder(itemToShow); diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index 56e4ac1979b..854da7251dc 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -57,7 +57,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { private openExternal(resource: URI): void { this.windowsService.openExternal(resource.toString()).then(didOpen => { if (!didOpen) { - return this.windowsService.showItemInFolder(resource.fsPath); + return this.windowsService.showItemInFolder(resource); } return undefined; diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index d5483f119d8..734b84326b6 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -357,9 +357,9 @@ CommandsRegistry.registerCommand({ function revealResourcesInOS(resources: URI[], windowsService: IWindowsService, notificationService: INotificationService, workspaceContextService: IWorkspaceContextService): void { if (resources.length) { - sequence(resources.map(r => () => windowsService.showItemInFolder(r.fsPath))); + sequence(resources.map(r => () => windowsService.showItemInFolder(r))); } else if (workspaceContextService.getWorkspace().folders.length) { - windowsService.showItemInFolder(workspaceContextService.getWorkspace().folders[0].uri.fsPath); + windowsService.showItemInFolder(workspaceContextService.getWorkspace().folders[0].uri); } else { notificationService.info(nls.localize('openFileToReveal', "Open a file first to reveal")); } diff --git a/src/vs/workbench/contrib/logs/common/logsActions.ts b/src/vs/workbench/contrib/logs/common/logsActions.ts index faa6e33ec1e..56b54a4c89c 100644 --- a/src/vs/workbench/contrib/logs/common/logsActions.ts +++ b/src/vs/workbench/contrib/logs/common/logsActions.ts @@ -10,6 +10,7 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment' import { IWindowsService } from 'vs/platform/windows/common/windows'; import { ILogService, LogLevel, DEFAULT_LOG_LEVEL } from 'vs/platform/log/common/log'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { URI } from 'vs/base/common/uri'; export class OpenLogsFolderAction extends Action { @@ -24,7 +25,7 @@ export class OpenLogsFolderAction extends Action { } run(): Promise { - return this.windowsService.showItemInFolder(join(this.environmentService.logsPath, 'main.log')); + return this.windowsService.showItemInFolder(URI.file(join(this.environmentService.logsPath, 'main.log'))); } } diff --git a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts index dfd9214684a..8927080ea73 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/startupProfiler.ts @@ -16,6 +16,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { PerfviewInput } from 'vs/workbench/contrib/performance/electron-browser/perfviewEditor'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { URI } from 'vs/base/common/uri'; export class StartupProfiler implements IWorkbenchContribution { @@ -78,7 +79,7 @@ export class StartupProfiler implements IWorkbenchContribution { }).then(res => { if (res.confirmed) { Promise.all([ - this._windowsService.showItemInFolder(join(dir, files[0])), + this._windowsService.showItemInFolder(URI.file(join(dir, files[0]))), this._createPerfIssue(files) ]).then(() => { // keep window stable until restart is selected diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 6f31697329d..a9ea758e590 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -1332,7 +1332,7 @@ export class TestWindowsService implements IWindowsService { return Promise.resolve(); } - showItemInFolder(_path: string): Promise { + showItemInFolder(_path: URI): Promise { return Promise.resolve(); } From beca500a3878cdbc823fd8a571d2e3dfb8a97e30 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Mar 2019 12:07:45 +0100 Subject: [PATCH 286/290] debt - remove startup type logging --- .../performance/electron-browser/startupTimings.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts b/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts index 55020ca1872..fd937159d62 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts @@ -9,7 +9,6 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle'; -import { ILogService } from 'vs/platform/log/common/log'; import product from 'vs/platform/product/node/product'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IUpdateService } from 'vs/platform/update/common/update'; @@ -24,7 +23,6 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; export class StartupTimings implements IWorkbenchContribution { constructor( - @ILogService private readonly _logService: ILogService, @ITimerService private readonly _timerService: ITimerService, @IWindowsService private readonly _windowsService: IWindowsService, @IEditorService private readonly _editorService: IEditorService, @@ -88,36 +86,28 @@ export class StartupTimings implements IWorkbenchContribution { // * one text editor (not multiple, not webview, welcome etc...) // * cached data present (not rejected, not created) if (this._lifecycleService.startupKind !== StartupKind.NewWindow) { - this._logService.info('no standard startup: not a new window'); return false; } if (await this._windowsService.getWindowCount() !== 1) { - this._logService.info('no standard startup: not just one window'); return false; } const activeViewlet = this._viewletService.getActiveViewlet(); if (!activeViewlet || activeViewlet.getId() !== files.VIEWLET_ID) { - this._logService.info('no standard startup: not the explorer viewlet'); return false; } const visibleControls = this._editorService.visibleControls; if (visibleControls.length !== 1 || !isCodeEditor(visibleControls[0].getControl())) { - this._logService.info('no standard startup: not just one text editor'); return false; } if (this._panelService.getActivePanel()) { - this._logService.info('no standard startup: panel is active'); return false; } if (!didUseCachedData()) { - this._logService.info('no standard startup: not using cached data'); return false; } if (!await this._updateService.isLatestVersion()) { - this._logService.info('no standard startup: not running latest version'); return false; } - this._logService.info('standard startup'); return true; } } From 74955b29d7804cf3fe1fcde264c4d7f7cb926856 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Mar 2019 12:15:53 +0100 Subject: [PATCH 287/290] send raw timer ticks, #67650 --- .../performance/electron-browser/startupTimings.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts b/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts index fd937159d62..2af7ea08c5b 100644 --- a/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts +++ b/src/vs/workbench/contrib/performance/electron-browser/startupTimings.ts @@ -19,6 +19,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { didUseCachedData, ITimerService } from 'vs/workbench/services/timer/electron-browser/timerService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { getEntries } from 'vs/base/common/performance'; export class StartupTimings implements IWorkbenchContribution { @@ -41,6 +42,7 @@ export class StartupTimings implements IWorkbenchContribution { const isStandardStartup = await this._isStandardStartup(); this._reportStartupTimes().catch(onUnexpectedError); this._appendStartupTimes(isStandardStartup).catch(onUnexpectedError); + this._reportPerfTicks(); } private async _reportStartupTimes(): Promise { @@ -110,5 +112,11 @@ export class StartupTimings implements IWorkbenchContribution { } return true; } + + private _reportPerfTicks(): void { + const entries = getEntries(); + //todo@joh proper data declare + this._telemetryService.publicLog('startupRawTimers', entries); + } } From 0fa822f7d5fafd0623aff80cb97e3cea1e2b2ae3 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Mar 2019 14:52:29 +0100 Subject: [PATCH 288/290] add newline and warning-icon before the path, #69044 --- .../extensions/electron-browser/runtimeExtensionsEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts index da6880ff9b7..dcc921a7168 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts @@ -524,7 +524,7 @@ export class ReportExtensionIssueAction extends Action { const data = profiler.rewriteAbsolutePaths({ profile: extension.unresponsiveProfile!.data }, 'pii_removed'); profiler.writeProfile(data, path).then(undefined, onUnexpectedError); }; - message = `:warning: Make sure to **attach** this file from your *home*-directory: \`${path}\` :warning:\n\nFind more details here: https://github.com/Microsoft/vscode/wiki/Explain:-extension-causes-high-cpu-load`; + message = `:warning: Make sure to **attach** this file from your *home*-directory:\n:warning:\`${path}\`\n\nFind more details here: https://github.com/Microsoft/vscode/wiki/Explain:-extension-causes-high-cpu-load`; } else { // generic From 26f0a77c56ef675072aa3ed6b19987cb89e13fd2 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 6 Mar 2019 15:09:20 +0100 Subject: [PATCH 289/290] Make simple file picker case insensitive Fixes #69796 --- .../dialogs/electron-browser/remoteFileDialog.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts index 50395ba25f6..08f9ea471b8 100644 --- a/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/electron-browser/remoteFileDialog.ts @@ -214,7 +214,7 @@ export class RemoteFileDialog { if (value !== this.userValue) { const trimmedPickBoxValue = ((this.filePickBox.value.length > 1) && this.endsWithSlash(this.filePickBox.value)) ? this.filePickBox.value.substr(0, this.filePickBox.value.length - 1) : this.filePickBox.value; const valueUri = this.remoteUriFrom(trimmedPickBoxValue); - if (!resources.isEqual(this.currentFolder, valueUri)) { + if (!resources.isEqual(this.currentFolder, valueUri, true)) { await this.tryUpdateItems(value, valueUri); } this.setActiveItems(value); @@ -256,7 +256,7 @@ export class RemoteFileDialog { // Find resolve value if (this.filePickBox.activeItems.length === 0) { - if (!this.requiresTrailing && resources.isEqual(this.currentFolder, inputUri)) { + if (!this.requiresTrailing && resources.isEqual(this.currentFolder, inputUri, true)) { resolveValue = inputUri; } else if (this.requiresTrailing && statDirname && statDirname.isDirectory) { resolveValue = inputUri; @@ -288,7 +288,7 @@ export class RemoteFileDialog { } private async tryUpdateItems(value: string, valueUri: URI) { - if (this.endsWithSlash(value) || (!resources.isEqual(this.currentFolder, resources.dirname(valueUri)) && resources.isEqualOrParent(this.currentFolder, resources.dirname(valueUri)))) { + if (this.endsWithSlash(value) || (!resources.isEqual(this.currentFolder, resources.dirname(valueUri), true) && resources.isEqualOrParent(this.currentFolder, resources.dirname(valueUri), true))) { let stat: IFileStat | undefined; try { stat = await this.remoteFileService.resolveFile(valueUri); @@ -299,7 +299,7 @@ export class RemoteFileDialog { this.updateItems(valueUri); } else { const inputUriDirname = resources.dirname(valueUri); - if (!resources.isEqual(this.currentFolder, inputUriDirname)) { + if (!resources.isEqual(this.currentFolder, inputUriDirname, true)) { let statWithoutTrailing: IFileStat | undefined; try { statWithoutTrailing = await this.remoteFileService.resolveFile(inputUriDirname); @@ -321,7 +321,7 @@ export class RemoteFileDialog { for (let i = 0; i < this.filePickBox.items.length; i++) { const item = this.filePickBox.items[i]; const itemBasename = resources.basename(item.uri); - if ((itemBasename.length >= inputBasename.length) && (itemBasename.substr(0, inputBasename.length) === inputBasename)) { + if ((itemBasename.length >= inputBasename.length) && (itemBasename.substr(0, inputBasename.length).toLowerCase() === inputBasename.toLowerCase())) { this.filePickBox.activeItems = [item]; this.filePickBox.value = this.filePickBox.value + itemBasename.substr(inputBasename.length); this.filePickBox.valueSelection = [value.length, this.filePickBox.value.length]; @@ -442,7 +442,7 @@ export class RemoteFileDialog { private createBackItem(currFolder: URI): FileQuickPickItem | null { const parentFolder = resources.dirname(currFolder)!; - if (!resources.isEqual(currFolder, parentFolder)) { + if (!resources.isEqual(currFolder, parentFolder, true)) { return { label: '..', uri: resources.dirname(currFolder), isFolder: true }; } return null; From 40905b95ac88cea03619a4fe4a39edcea00a2594 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Mar 2019 15:23:00 +0100 Subject: [PATCH 290/290] eng - strict null checks for remoteFileService --- src/tsconfig.strictNullChecks.json | 3 +- src/vs/platform/files/common/files.ts | 2 +- .../externalTerminal.contribution.ts | 2 +- .../contrib/stats/node/workspaceStats.ts | 4 +- .../services/files/node/remoteFileService.ts | 87 +++++++++---------- 5 files changed, 47 insertions(+), 51 deletions(-) diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 0815dc052f9..9ececdd3e50 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -433,6 +433,7 @@ "./vs/workbench/services/extensions/node/rpcProtocol.ts", "./vs/workbench/services/extensions/test/node/rpcProtocol.test.ts", "./vs/workbench/services/files/node/encoding.ts", + "./vs/workbench/services/files/node/remoteFileService.ts", "./vs/workbench/services/files/node/fileService.ts", "./vs/workbench/services/files/node/streams.ts", "./vs/workbench/services/files/test/electron-browser/utils.ts", @@ -521,4 +522,4 @@ "./typings/require-monaco.d.ts", "./vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts" ] -} \ No newline at end of file +} diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index fa87bbd829f..399a6001e09 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -455,7 +455,7 @@ export interface IFileStat extends IBaseStat { } export interface IResolveFileResult { - stat: IFileStat; + stat?: IFileStat; success: boolean; } diff --git a/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts index d72561ce0a0..34c5c845166 100644 --- a/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts +++ b/src/vs/workbench/contrib/externalTerminal/electron-browser/externalTerminal.contribution.ts @@ -91,7 +91,7 @@ CommandsRegistry.registerCommand({ const resources = getMultiSelectedResources(resource, accessor.get(IListService), editorService); return fileService.resolveFiles(resources.map(r => ({ resource: r }))).then(stats => { - const directoriesToOpen = distinct(stats.map(({ stat }) => stat.isDirectory ? stat.resource.fsPath : paths.dirname(stat.resource.fsPath))); + const directoriesToOpen = distinct(stats.filter(data => data.success).map(({ stat }) => stat!.isDirectory ? stat!.resource.fsPath : paths.dirname(stat!.resource.fsPath))); return directoriesToOpen.map(dir => { if (configurationService.getValue().terminal.explorerKind === 'integrated') { const instance = integratedTerminalService.createTerminal({ cwd: dir }, true); diff --git a/src/vs/workbench/contrib/stats/node/workspaceStats.ts b/src/vs/workbench/contrib/stats/node/workspaceStats.ts index 10ea1691f99..ea4cc981bee 100644 --- a/src/vs/workbench/contrib/stats/node/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/node/workspaceStats.ts @@ -368,7 +368,7 @@ export class WorkspaceStats implements IWorkbenchContribution { } return this.fileService.resolveFiles(folders.map(resource => ({ resource }))).then((files: IResolveFileResult[]) => { - const names = ([]).concat(...files.map(result => result.success ? (result.stat.children || []) : [])).map(c => c.name); + const names = ([]).concat(...files.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name); const nameSet = names.reduce((s, n) => s.add(n.toLowerCase()), new Set()); if (participant) { @@ -664,7 +664,7 @@ export class WorkspaceStats implements IWorkbenchContribution { }); return this.fileService.resolveFiles(uris.map(resource => ({ resource }))).then( results => { - const names = ([]).concat(...results.map(result => result.success ? (result.stat.children || []) : [])).map(c => c.name); + const names = ([]).concat(...results.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name); const referencesAzure = WorkspaceStats.searchArray(names, /azure/i); if (referencesAzure) { tags['node'] = true; diff --git a/src/vs/workbench/services/files/node/remoteFileService.ts b/src/vs/workbench/services/files/node/remoteFileService.ts index e9beb32812c..36687a83c68 100644 --- a/src/vs/workbench/services/files/node/remoteFileService.ts +++ b/src/vs/workbench/services/files/node/remoteFileService.ts @@ -70,7 +70,7 @@ function toIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], recurse return Promise.resolve(fileStat); } -export function toDeepIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], to: URI[]): Promise { +export function toDeepIFileStat(provider: IFileSystemProvider, tuple: [URI, IStat], to?: URI[]): Promise { const trie = TernarySearchTree.forPaths(); trie.set(tuple[0].toString(), true); @@ -281,7 +281,7 @@ export class RemoteFileService extends FileService { FileOperationResult.FILE_NOT_FOUND ); } else { - return data[0].stat; + return data[0].stat!; } }); } @@ -319,7 +319,7 @@ export class RemoteFileService extends FileService { return toDeepIFileStat(provider, [item.resource, stat], item.options && item.options.resolveTo).then(fileStat => { result[idx] = { stat: fileStat, success: true }; }); - }, err => { + }, _err => { result[idx] = { stat: undefined, success: false }; }); }); @@ -440,7 +440,7 @@ export class RemoteFileService extends FileService { 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) }); + return this._writeFile(provider, resource, new StringSnapshot(content || ''), encoding, { create: true, overwrite: Boolean(options && options.overwrite) }); }); }).then(fileStat => { @@ -449,7 +449,7 @@ export class RemoteFileService extends FileService { }, err => { const message = localize('err.create', "Failed to create file {0}", resource.toString(false)); const result = this._tryParseFileOperationResult(err); - throw new FileOperationError(message, result, options); + throw new FileOperationError(message, result || -1, options); }); } } @@ -467,7 +467,7 @@ export class RemoteFileService extends FileService { } } - private _writeFile(provider: IFileSystemProvider, resource: URI, snapshot: ITextSnapshot, preferredEncoding: string, options: FileWriteOptions): Promise { + private _writeFile(provider: IFileSystemProvider, resource: URI, snapshot: ITextSnapshot, preferredEncoding: string | undefined = undefined, options: FileWriteOptions): Promise { const readable = createReadableOfSnapshot(snapshot); const encoding = this.encoding.getWriteEncoding(resource, preferredEncoding); const encoder = encodeStream(encoding); @@ -549,13 +549,13 @@ export class RemoteFileService extends FileService { } } - private _doMoveWithInScheme(source: URI, target: URI, overwrite?: boolean): Promise { + private async _doMoveWithInScheme(source: URI, target: URI, overwrite: boolean = false): Promise { - const prepare = overwrite - ? Promise.resolve(this.del(target, { recursive: true }).then(undefined, err => { /*ignore*/ })) - : Promise.resolve(null); + if (overwrite) { + await this.del(target, { recursive: true }).catch(_err => { /*ignore*/ }); + } - return prepare.then(() => this._withProvider(source)).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => { + return this._withProvider(source).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => { return RemoteFileService._mkdirp(provider, resources.dirname(target)).then(() => { return provider.rename(source, target, { overwrite }).then(() => { return this.resolveFile(target); @@ -589,11 +589,11 @@ export class RemoteFileService extends FileService { return super.copyFile(source, target, overwrite); } - return this._withProvider(target).then(RemoteFileService._throwIfFileSystemIsReadonly).then(provider => { + return this._withProvider(target).then(RemoteFileService._throwIfFileSystemIsReadonly).then(async provider => { if (source.scheme === target.scheme && (provider.capabilities & FileSystemProviderCapabilities.FileFolderCopy)) { // good: provider supports copy withing scheme - return provider.copy(source, target, { overwrite: !!overwrite }).then(() => { + return provider.copy!(source, target, { overwrite: !!overwrite }).then(() => { return this.resolveFile(target); }).then(fileStat => { this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat)); @@ -607,51 +607,46 @@ export class RemoteFileService extends FileService { }); } - const prepare = overwrite - ? Promise.resolve(this.del(target, { recursive: true }).then(undefined, err => { /*ignore*/ })) - : Promise.resolve(null); + if (overwrite) { + await this.del(target, { recursive: true }).catch(_err => { /*ignore*/ }); + } - return prepare.then(() => { - // todo@ben, can only copy text files - // https://github.com/Microsoft/vscode/issues/41543 - return this.resolveContent(source, { acceptTextOnly: true }).then(content => { - return this._withProvider(target).then(provider => { - return this._writeFile( - provider, target, - new StringSnapshot(content.value), - content.encoding, - { create: true, overwrite: !!overwrite } - ).then(fileStat => { - this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat)); - return fileStat; - }); - }, err => { - const result = this._tryParseFileOperationResult(err); - if (result === FileOperationResult.FILE_MOVE_CONFLICT) { - throw new FileOperationError(localize('fileMoveConflict', "Unable to move/copy. File already exists at destination."), result); - } else if (err instanceof Error && err.name === 'ENOPRO') { - // file scheme - return super.updateContent(target, content.value, { encoding: content.encoding }); - } else { - return Promise.reject(err); - } + // todo@ben, can only copy text files + // https://github.com/Microsoft/vscode/issues/41543 + return this.resolveContent(source, { acceptTextOnly: true }).then(content => { + return this._withProvider(target).then(provider => { + return this._writeFile( + provider, target, + new StringSnapshot(content.value), + content.encoding, + { create: true, overwrite: !!overwrite } + ).then(fileStat => { + this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.COPY, fileStat)); + return fileStat; }); + }, err => { + const result = this._tryParseFileOperationResult(err); + if (result === FileOperationResult.FILE_MOVE_CONFLICT) { + throw new FileOperationError(localize('fileMoveConflict', "Unable to move/copy. File already exists at destination."), result); + } else if (err instanceof Error && err.name === 'ENOPRO') { + // file scheme + return super.updateContent(target, content.value, { encoding: content.encoding }); + } else { + return Promise.reject(err); + } }); }); + }); } private _activeWatches = new Map, count: number }>(); - watchFileChanges(resource: URI, opts?: IWatchOptions): void { + watchFileChanges(resource: URI, opts: IWatchOptions = { recursive: false, excludes: [] }): void { if (resource.scheme === Schemas.file) { return super.watchFileChanges(resource); } - if (!opts) { - opts = { recursive: false, excludes: [] }; - } - const key = resource.toString(); const entry = this._activeWatches.get(key); if (entry) { @@ -663,7 +658,7 @@ export class RemoteFileService extends FileService { count: 1, unwatch: this._withProvider(resource).then(provider => { return provider.watch(resource, opts); - }, err => { + }, _err => { return { dispose() { } }; }) });