diff --git a/product.json b/product.json index 30a7f0708ea14..515530c80851a 100644 --- a/product.json +++ b/product.json @@ -91,7 +91,7 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.49.6", + "version": "1.49.7", "repo": "https://github.com/Microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index c1e2a84946af5..d4dfefd7fd144 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -92,9 +92,9 @@ export class ProxyAuthHandler extends Disposable { if (channel === 'vscode:proxyAuthResponse') { const { username, password } = credentials; cb(username, password); + win.removeListener('close', onWindowClose); + win.close(); } - win.removeListener('close', onWindowClose); - win.close(); }); win.loadURL(url); } diff --git a/src/vs/editor/common/modes/supports/tokenization.ts b/src/vs/editor/common/modes/supports/tokenization.ts index e701b60f0a9d1..12566c3b00e7b 100644 --- a/src/vs/editor/common/modes/supports/tokenization.ts +++ b/src/vs/editor/common/modes/supports/tokenization.ts @@ -399,10 +399,10 @@ export function generateTokensCSSForColorMap(colorMap: Color[]): string { let rules: string[] = []; for (let i = 1, len = colorMap.length; i < len; i++) { let color = colorMap[i]; - rules[i] = `.monaco-editor .mtk${i} { color: ${color}; }`; + rules[i] = `.mtk${i} { color: ${color}; }`; } - rules.push('.monaco-editor .mtki { font-style: italic; }'); - rules.push('.monaco-editor .mtkb { font-weight: bold; }'); - rules.push('.monaco-editor .mtku { text-decoration: underline; text-underline-position: under; }'); + rules.push('.mtki { font-style: italic; }'); + rules.push('.mtkb { font-weight: bold; }'); + rules.push('.mtku { text-decoration: underline; text-underline-position: under; }'); return rules.join('\n'); } diff --git a/src/vs/editor/contrib/suggest/completionModel.ts b/src/vs/editor/contrib/suggest/completionModel.ts index 8926c628e435e..61ddc7d839fff 100644 --- a/src/vs/editor/contrib/suggest/completionModel.ts +++ b/src/vs/editor/contrib/suggest/completionModel.ts @@ -10,6 +10,7 @@ import { InternalSuggestOptions } from 'vs/editor/common/config/editorOptions'; import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance'; import { CharCode } from 'vs/base/common/charCode'; import { compareIgnoreCase } from 'vs/base/common/strings'; +import { Event } from 'vs/base/common/event'; // Unused import type StrictCompletionItem = Required; @@ -56,6 +57,7 @@ export class CompletionModel { private _refilterKind: Refilter; private _filteredItems?: StrictCompletionItem[]; private _isIncomplete?: Set; + private _allProvider?: Set; // TODO@jrieken merge incomplete and all provider info private _stats?: ICompletionStats; constructor( @@ -99,6 +101,11 @@ export class CompletionModel { return this._filteredItems!; } + get allProvider(): Set { + this._ensureCachedState(); + return this._allProvider!; + } + get incomplete(): Set { this._ensureCachedState(); return this._isIncomplete!; @@ -136,6 +143,7 @@ export class CompletionModel { private _createCachedState(): void { this._isIncomplete = new Set(); + this._allProvider = new Set(); this._stats = { suggestionCount: 0, snippetCount: 0, textCount: 0 }; const { leadingLineContent, characterCountDelta } = this._lineContext; @@ -164,6 +172,7 @@ export class CompletionModel { if (item.container.incomplete) { this._isIncomplete.add(item.provider); } + this._allProvider.add(item.provider); // 'word' is that remainder of the current line that we // filter and score against. In theory each suggestion uses a @@ -290,4 +299,4 @@ export class CompletionModel { } return CompletionModel._compareCompletionItems(a, b); } -} +} \ No newline at end of file diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index bb4f269ece8e7..ea890f7285bb0 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -23,6 +23,7 @@ import { WordDistance } from 'vs/editor/contrib/suggest/wordDistance'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { isLowSurrogate, isHighSurrogate } from 'vs/base/common/strings'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { URI } from 'vs/base/common/uri'; // Unused import export interface ICancelEvent { readonly retrigger: boolean; @@ -44,6 +45,7 @@ export interface ISuggestEvent { export interface SuggestTriggerContext { readonly auto: boolean; readonly shy: boolean; + readonly triggerKind?: CompletionTriggerKind; readonly triggerCharacter?: string; } @@ -393,16 +395,12 @@ export class SuggestModel implements IDisposable { this._context = ctx; // Build context for request - let suggestCtx: CompletionContext; + let suggestCtx: CompletionContext = { triggerKind: context.triggerKind ?? CompletionTriggerKind.Invoke }; if (context.triggerCharacter) { suggestCtx = { triggerKind: CompletionTriggerKind.TriggerCharacter, triggerCharacter: context.triggerCharacter }; - } else if (onlyFrom && onlyFrom.size > 0) { - suggestCtx = { triggerKind: CompletionTriggerKind.TriggerForIncompleteCompletions }; - } else { - suggestCtx = { triggerKind: CompletionTriggerKind.Invoke }; } this._requestToken = new CancellationTokenSource(); @@ -558,7 +556,13 @@ export class SuggestModel implements IDisposable { if (ctx.leadingWord.word.length !== 0 && ctx.leadingWord.startColumn > this._context.leadingWord.startColumn) { // started a new word while IntelliSense shows -> retrigger - this.trigger({ auto: this._context.auto, shy: false }, true); + + // Select those providers have not contributed to this completion model and re-trigger completions for + // them. Also adopt the existing items and merge them into the new completion model + const inactiveProvider = new Set(CompletionProviderRegistry.all(this._editor.getModel()!)); + this._completionModel.allProvider.forEach(provider => inactiveProvider.delete(provider)); + const items = this._completionModel.adopt(new Set()); + this.trigger({ auto: this._context.auto, shy: false }, true, inactiveProvider, items); return; } @@ -566,7 +570,7 @@ export class SuggestModel implements IDisposable { // typed -> moved cursor RIGHT & incomple model & still on a word -> retrigger const { incomplete } = this._completionModel; const adopted = this._completionModel.adopt(incomplete); - this.trigger({ auto: this._state === State.Auto, shy: false }, true, incomplete, adopted); + this.trigger({ auto: this._state === State.Auto, shy: false, triggerKind: CompletionTriggerKind.TriggerForIncompleteCompletions }, true, incomplete, adopted); } else { // typed -> moved cursor RIGHT -> update UI @@ -613,4 +617,4 @@ export class SuggestModel implements IDisposable { }); } } -} +} \ No newline at end of file diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 0ed16cec59b64..511d7376a2bfe 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -216,8 +216,9 @@ class BrowserMain extends Disposable { // Initialize required resources - settings & global state await userDataInitializationService.initializeRequiredResources(); - // Reload configuration after initializing - await configurationService.reloadConfiguration(); + // Important: Reload only local user configuration after initializing + // Reloading complete configuraiton blocks workbench until remote configuration is loaded. + await configurationService.reloadLocalUserConfiguration(); } return { serviceCollection, logService, storageService }; diff --git a/src/vs/workbench/contrib/views/browser/treeView.ts b/src/vs/workbench/contrib/views/browser/treeView.ts index 64a90c8d0b6d7..faa3a219f2c8e 100644 --- a/src/vs/workbench/contrib/views/browser/treeView.ts +++ b/src/vs/workbench/contrib/views/browser/treeView.ts @@ -40,7 +40,6 @@ import { isFalsyOrWhitespace } from 'vs/base/common/strings'; import { SIDE_BAR_BACKGROUND, PANEL_BACKGROUND } from 'vs/workbench/common/theme'; import { IHoverService, IHoverOptions, IHoverTarget } from 'vs/workbench/services/hover/browser/hover'; import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; -import { IMarkdownString } from 'vs/base/common/htmlContent'; import { isMacintosh } from 'vs/base/common/platform'; class Root implements ITreeItem { @@ -756,6 +755,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer { - if (node instanceof ResolvableTreeItem) { - await node.resolve(); - } - let tooltip: IMarkdownString | string | undefined = node.tooltip ?? label; + await resolvableNode.resolve(); + const tooltip = resolvableNode.tooltip ?? label; if (isHovering && tooltip) { if (!hoverOptions) { const target: IHoverTarget = { diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 650b4c9fad36d..fb63eeb6fa811 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -403,7 +403,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic if (!this.localUserConfiguration.hasTasksLoaded) { // Reload local user configuration again to load user tasks - runWhenIdle(() => this.reloadLocalUserConfiguration().then(configurationModel => this.onLocalUserConfigurationChanged(configurationModel)), 5000); + runWhenIdle(() => this.reloadLocalUserConfiguration(), 5000); } }); } @@ -436,16 +436,27 @@ export class WorkspaceService extends Disposable implements IConfigurationServic .then(([local, remote]) => ({ local, remote })); } - private reloadUserConfiguration(key?: string): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> { - return Promise.all([this.reloadLocalUserConfiguration(), this.reloadRemoeUserConfiguration()]).then(([local, remote]) => ({ local, remote })); + private reloadUserConfiguration(): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> { + return Promise.all([this.reloadLocalUserConfiguration(true), this.reloadRemoteUserConfiguration(true)]).then(([local, remote]) => ({ local, remote })); } - private reloadLocalUserConfiguration(key?: string): Promise { - return this.localUserConfiguration.reload(); + async reloadLocalUserConfiguration(donotTrigger?: boolean): Promise { + const model = await this.localUserConfiguration.reload(); + if (!donotTrigger) { + this.onLocalUserConfigurationChanged(model); + } + return model; } - private reloadRemoeUserConfiguration(key?: string): Promise { - return this.remoteUserConfiguration ? this.remoteUserConfiguration.reload() : Promise.resolve(new ConfigurationModel()); + private async reloadRemoteUserConfiguration(donotTrigger?: boolean): Promise { + if (this.remoteUserConfiguration) { + const model = await this.remoteUserConfiguration.reload(); + if (!donotTrigger) { + this.onRemoteUserConfigurationChanged(model); + } + return model; + } + return new ConfigurationModel(); } private reloadWorkspaceConfiguration(key?: string): Promise { @@ -667,9 +678,9 @@ export class WorkspaceService extends Disposable implements IConfigurationServic .then(() => { switch (editableConfigurationTarget) { case EditableConfigurationTarget.USER_LOCAL: - return this.reloadLocalUserConfiguration().then(local => this.onLocalUserConfigurationChanged(local)); + return this.reloadLocalUserConfiguration().then(() => undefined); case EditableConfigurationTarget.USER_REMOTE: - return this.reloadRemoeUserConfiguration().then(remote => this.onRemoteUserConfigurationChanged(remote)); + return this.reloadRemoteUserConfiguration().then(() => undefined); case EditableConfigurationTarget.WORKSPACE: return this.reloadWorkspaceConfiguration(); case EditableConfigurationTarget.WORKSPACE_FOLDER: diff --git a/src/vs/workbench/services/userData/browser/userDataInit.ts b/src/vs/workbench/services/userData/browser/userDataInit.ts index 95f57c555d4cf..f80a4b754cd39 100644 --- a/src/vs/workbench/services/userData/browser/userDataInit.ts +++ b/src/vs/workbench/services/userData/browser/userDataInit.ts @@ -107,19 +107,23 @@ export class UserDataInitializationService implements IUserDataInitializationSer } async requiresInitialization(): Promise { + this.logService.trace(`UserDataInitializationService#requiresInitialization`); const userDataSyncStoreClient = await this.createUserDataSyncStoreClient(); return !!userDataSyncStoreClient; } async initializeRequiredResources(): Promise { + this.logService.trace(`UserDataInitializationService#initializeRequiredResources`); return this.initialize([SyncResource.Settings, SyncResource.GlobalState]); } async initializeOtherResources(): Promise { + this.logService.trace(`UserDataInitializationService#initializeOtherResources`); return this.initialize([SyncResource.Keybindings, SyncResource.Snippets]); } async initializeExtensions(instantiationService: IInstantiationService): Promise { + this.logService.trace(`UserDataInitializationService#initializeExtensions`); return this.initialize([SyncResource.Extensions], instantiationService); }