From 72807c5acc5a8235b109bb722f41e4f8bf595066 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 4 Mar 2020 15:48:06 +0100 Subject: [PATCH] quick pick - add quick pick service to platform and register for standalone editor --- .../standalone/browser/standaloneServices.ts | 6 +- .../platform/quickinput/browser/quickInput.ts | 194 +++++++++-- .../browser/parts/quickinput/quickInput.ts | 307 ------------------ .../parts/quickopen/quickOpenActions.ts | 25 ++ .../browser/parts/quickopen/quickopen.ts | 59 +++- src/vs/workbench/workbench.common.main.ts | 4 +- 6 files changed, 258 insertions(+), 337 deletions(-) delete mode 100644 src/vs/workbench/browser/parts/quickinput/quickInput.ts diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index 0ee9ba495d0..e3908aa99e3 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -52,6 +52,8 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { BrowserClipboardService } from 'vs/platform/clipboard/browser/clipboardService'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; +import { QuickInputService } from 'vs/platform/quickinput/browser/quickInput'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; export interface IEditorOverrideServices { [index: string]: any; @@ -198,7 +200,7 @@ export class DynamicStandaloneServices extends Disposable { let contextKeyService = ensure(IContextKeyService, () => this._register(new ContextKeyService(configurationService))); - ensure(IAccessibilityService, () => new AccessibilityService(contextKeyService, configurationService)); + let accessibilityService = ensure(IAccessibilityService, () => new AccessibilityService(contextKeyService, configurationService)); ensure(IListService, () => new ListService(themeService)); @@ -208,6 +210,8 @@ export class DynamicStandaloneServices extends Disposable { let layoutService = ensure(ILayoutService, () => new SimpleLayoutService(StaticServices.codeEditorService.get(ICodeEditorService), domElement)); + ensure(IQuickInputService, () => new QuickInputService(Object.create(null), configurationService, _instantiationService, keybindingService, contextKeyService, themeService, accessibilityService, layoutService)); + let contextViewService = ensure(IContextViewService, () => this._register(new ContextViewService(layoutService))); ensure(IClipboardService, () => new BrowserClipboardService()); diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index af94b071f7a..86ddb1bd1bf 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -3,67 +3,207 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event } from 'vs/base/common/event'; -import { IQuickInputService, IQuickPickItem, IQuickInputButton, IQuickPick, IInputBox, QuickPickInput, IPickOptions, IInputOptions, IQuickNavigateConfiguration } from 'vs/platform/quickinput/common/quickInput'; -import { CancellationToken } from 'vs/base/common/cancellation'; +import { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInputButton, IInputBox, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; +import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IThemeService, Themable } from 'vs/platform/theme/common/themeService'; +import { inputBackground, inputForeground, inputBorder, inputValidationInfoBackground, inputValidationInfoForeground, inputValidationInfoBorder, inputValidationWarningBackground, inputValidationWarningForeground, inputValidationWarningBorder, inputValidationErrorBackground, inputValidationErrorForeground, inputValidationErrorBorder, badgeBackground, badgeForeground, contrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, progressBarBackground, widgetShadow, listFocusForeground, listFocusBackground, activeContrastBorder, pickerGroupBorder, pickerGroupForeground, quickInputForeground, quickInputBackground, quickInputTitleBackground } from 'vs/platform/theme/common/colorRegistry'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { computeStyles } from 'vs/platform/theme/common/styler'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { QuickInputController, IQuickInputStyles } from 'vs/base/parts/quickinput/browser/quickInput'; +import { WorkbenchList } from 'vs/platform/list/browser/listService'; +import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget'; +import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list'; -export abstract class PlatformQuickInputService extends Themable implements IQuickInputService { +export class QuickInputService extends Themable implements IQuickInputService { - public _serviceBrand: undefined; + _serviceBrand: undefined; - readonly backButton!: IQuickInputButton; + get backButton(): IQuickInputButton { return this.controller.backButton; } - get onShow() { return Event.None; } - get onHide() { return Event.None; } + get onShow() { return this.controller.onShow; } + get onHide() { return this.controller.onHide; } + + private readonly controller: QuickInputController; + private readonly contexts = new Map>(); constructor( - @IThemeService themeService: IThemeService + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IKeybindingService private readonly keybindingService: IKeybindingService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IThemeService themeService: IThemeService, + @IAccessibilityService private readonly accessibilityService: IAccessibilityService, + @ILayoutService private readonly layoutService: ILayoutService ) { super(themeService); + + this.controller = this._register(new QuickInputController({ + idPrefix: 'quickInput_', // Constant since there is still only one. + container: this.layoutService.container, + ignoreFocusOut: () => this.environmentService.args['sticky-quickopen'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'), + isScreenReaderOptimized: () => this.accessibilityService.isScreenReaderOptimized(), + backKeybindingLabel: () => this.keybindingService.lookupKeybinding('workbench.action.quickInputBack')?.getLabel() || undefined, + setContextKey: (id?: string) => this.setContextKey(id), + returnFocus: () => this.layoutService.focus(), + createList: ( + user: string, + container: HTMLElement, + delegate: IListVirtualDelegate, + renderers: IListRenderer[], + options: IListOptions, + ) => this.instantiationService.createInstance(WorkbenchList, user, container, delegate, renderers, options) as List, + styles: this.computeStyles(), + })); + + this.controller.layout(this.layoutService.dimension, this.layoutService.offset?.top ?? 0); + + this.registerListeners(); + } + + private registerListeners(): void { + + // Layout changes + this._register(this.layoutService.onLayout(dimension => this.controller.layout(dimension, this.layoutService.offset?.top ?? 0))); + + // Context keys + this._register(this.controller.onShow(() => this.resetContextKeys())); + this._register(this.controller.onHide(() => this.resetContextKeys())); + } + + private setContextKey(id?: string) { + let key: IContextKey | undefined; + if (id) { + key = this.contexts.get(id); + if (!key) { + key = new RawContextKey(id, false) + .bindTo(this.contextKeyService); + this.contexts.set(id, key); + } + } + + if (key && key.get()) { + return; // already active context + } + + this.resetContextKeys(); + + if (key) { + key.set(true); + } + } + + private resetContextKeys() { + this.contexts.forEach(context => { + if (context.get()) { + context.reset(); + } + }); } pick>(picks: Promise[]> | QuickPickInput[], options: O = {}, token: CancellationToken = CancellationToken.None): Promise { - throw new Error('Method not implemented.'); + return this.controller.pick(picks, options, token); } - input(options?: IInputOptions | undefined, token?: CancellationToken | undefined): Promise { - throw new Error('Method not implemented.'); + input(options: IInputOptions = {}, token: CancellationToken = CancellationToken.None): Promise { + return this.controller.input(options, token); } createQuickPick(): IQuickPick { - throw new Error('Method not implemented.'); + return this.controller.createQuickPick(); } createInputBox(): IInputBox { - throw new Error('Method not implemented.'); + return this.controller.createInputBox(); } - focus(): void { - throw new Error('Method not implemented.'); + focus() { + this.controller.focus(); } - toggle(): void { - throw new Error('Method not implemented.'); + toggle() { + this.controller.toggle(); } - navigate(next: boolean, quickNavigate?: IQuickNavigateConfiguration | undefined): void { - throw new Error('Method not implemented.'); + navigate(next: boolean, quickNavigate?: IQuickNavigateConfiguration) { + this.controller.navigate(next, quickNavigate); } - accept(): Promise { - throw new Error('Method not implemented.'); + accept() { + return this.controller.accept(); } - back(): Promise { - throw new Error('Method not implemented.'); + back() { + return this.controller.back(); } - cancel(): Promise { - throw new Error('Method not implemented.'); + cancel() { + return this.controller.cancel(); } hide(focusLost?: boolean): void { - throw new Error('Method not implemented.'); + return this.controller.hide(focusLost); + } + + protected updateStyles() { + this.controller.applyStyles(this.computeStyles()); + } + + private computeStyles(): IQuickInputStyles { + return { + widget: { + ...computeStyles(this.theme, { + quickInputBackground, + quickInputForeground, + contrastBorder, + widgetShadow, + quickInputTitleBackground + }), + }, + inputBox: computeStyles(this.theme, { + inputForeground, + inputBackground, + inputBorder, + inputValidationInfoBackground, + inputValidationInfoForeground, + inputValidationInfoBorder, + inputValidationWarningBackground, + inputValidationWarningForeground, + inputValidationWarningBorder, + inputValidationErrorBackground, + inputValidationErrorForeground, + inputValidationErrorBorder + }), + countBadge: computeStyles(this.theme, { + badgeBackground, + badgeForeground, + badgeBorder: contrastBorder + }), + button: computeStyles(this.theme, { + buttonForeground, + buttonBackground, + buttonHoverBackground, + buttonBorder: contrastBorder + }), + progressBar: computeStyles(this.theme, { + progressBarBackground + }), + list: computeStyles(this.theme, { + listBackground: quickInputBackground, + // Look like focused when inactive. + listInactiveFocusForeground: listFocusForeground, + listInactiveFocusBackground: listFocusBackground, + listFocusOutline: activeContrastBorder, + listInactiveFocusOutline: activeContrastBorder, + pickerGroupBorder, + pickerGroupForeground + }), + }; } } diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts deleted file mode 100644 index 864500291df..00000000000 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ /dev/null @@ -1,307 +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 { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInputButton, IInputBox, QuickPickInput } from 'vs/platform/quickinput/common/quickInput'; -import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { inputBackground, inputForeground, inputBorder, inputValidationInfoBackground, inputValidationInfoForeground, inputValidationInfoBorder, inputValidationWarningBackground, inputValidationWarningForeground, inputValidationWarningBorder, inputValidationErrorBackground, inputValidationErrorForeground, inputValidationErrorBorder, badgeBackground, badgeForeground, contrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, progressBarBackground, widgetShadow, listFocusForeground, listFocusBackground, activeContrastBorder, pickerGroupBorder, pickerGroupForeground, quickInputForeground, quickInputBackground, quickInputTitleBackground } from 'vs/platform/theme/common/colorRegistry'; -import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { computeStyles } from 'vs/platform/theme/common/styler'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; -import { ICommandAndKeybindingRule, KeybindingWeight, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { inQuickOpenContext, InQuickOpenContextKey } from 'vs/workbench/browser/parts/quickopen/quickopen'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { QuickInputController, IQuickInputStyles } from 'vs/base/parts/quickinput/browser/quickInput'; -import { WorkbenchList } from 'vs/platform/list/browser/listService'; -import { List, IListOptions } from 'vs/base/browser/ui/list/listWidget'; -import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list'; -import { PlatformQuickInputService } from 'vs/platform/quickinput/browser/quickInput'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { Disposable } from 'vs/base/common/lifecycle'; - -export class QuickInputService extends PlatformQuickInputService { - - _serviceBrand: undefined; - - get backButton(): IQuickInputButton { return this.controller.backButton; } - - get onShow() { return this.controller.onShow; } - get onHide() { return this.controller.onHide; } - - private readonly controller: QuickInputController; - private readonly contexts = new Map>(); - - constructor( - @IEnvironmentService private readonly environmentService: IEnvironmentService, - @IConfigurationService private readonly configurationService: IConfigurationService, - @IInstantiationService private readonly instantiationService: IInstantiationService, - @IKeybindingService private readonly keybindingService: IKeybindingService, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IThemeService themeService: IThemeService, - @IAccessibilityService private readonly accessibilityService: IAccessibilityService, - @ILayoutService private readonly layoutService: ILayoutService - ) { - super(themeService); - - this.controller = this._register(new QuickInputController({ - idPrefix: 'quickInput_', // Constant since there is still only one. - container: this.layoutService.container, - ignoreFocusOut: () => this.environmentService.args['sticky-quickopen'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'), - isScreenReaderOptimized: () => this.accessibilityService.isScreenReaderOptimized(), - backKeybindingLabel: () => this.keybindingService.lookupKeybinding(QuickPickBack.id)?.getLabel() || undefined, - setContextKey: (id?: string) => this.setContextKey(id), - returnFocus: () => this.layoutService.focus(), - createList: ( - user: string, - container: HTMLElement, - delegate: IListVirtualDelegate, - renderers: IListRenderer[], - options: IListOptions, - ) => this.instantiationService.createInstance(WorkbenchList, user, container, delegate, renderers, options) as List, - styles: this.computeStyles(), - })); - - this.controller.layout(this.layoutService.dimension, this.layoutService.offset?.top ?? 0); - - this.registerListeners(); - } - - private registerListeners(): void { - - // Layout changes - this._register(this.layoutService.onLayout(dimension => this.controller.layout(dimension, this.layoutService.offset?.top ?? 0))); - - // Context keys - this._register(this.controller.onShow(() => this.resetContextKeys())); - this._register(this.controller.onHide(() => this.resetContextKeys())); - } - - private setContextKey(id?: string) { - let key: IContextKey | undefined; - if (id) { - key = this.contexts.get(id); - if (!key) { - key = new RawContextKey(id, false) - .bindTo(this.contextKeyService); - this.contexts.set(id, key); - } - } - - if (key && key.get()) { - return; // already active context - } - - this.resetContextKeys(); - - if (key) { - key.set(true); - } - } - - private resetContextKeys() { - this.contexts.forEach(context => { - if (context.get()) { - context.reset(); - } - }); - } - - pick>(picks: Promise[]> | QuickPickInput[], options: O = {}, token: CancellationToken = CancellationToken.None): Promise { - return this.controller.pick(picks, options, token); - } - - input(options: IInputOptions = {}, token: CancellationToken = CancellationToken.None): Promise { - return this.controller.input(options, token); - } - - createQuickPick(): IQuickPick { - return this.controller.createQuickPick(); - } - - createInputBox(): IInputBox { - return this.controller.createInputBox(); - } - - focus() { - this.controller.focus(); - } - - toggle() { - this.controller.toggle(); - } - - navigate(next: boolean, quickNavigate?: IQuickNavigateConfiguration) { - this.controller.navigate(next, quickNavigate); - } - - accept() { - return this.controller.accept(); - } - - back() { - return this.controller.back(); - } - - cancel() { - return this.controller.cancel(); - } - - hide(focusLost?: boolean): void { - return this.controller.hide(focusLost); - } - - protected updateStyles() { - this.controller.applyStyles(this.computeStyles()); - } - - private computeStyles(): IQuickInputStyles { - return { - widget: { - ...computeStyles(this.theme, { - quickInputBackground, - quickInputForeground, - contrastBorder, - widgetShadow, - quickInputTitleBackground - }), - }, - inputBox: computeStyles(this.theme, { - inputForeground, - inputBackground, - inputBorder, - inputValidationInfoBackground, - inputValidationInfoForeground, - inputValidationInfoBorder, - inputValidationWarningBackground, - inputValidationWarningForeground, - inputValidationWarningBorder, - inputValidationErrorBackground, - inputValidationErrorForeground, - inputValidationErrorBorder, - }), - countBadge: computeStyles(this.theme, { - badgeBackground, - badgeForeground, - badgeBorder: contrastBorder - }), - button: computeStyles(this.theme, { - buttonForeground, - buttonBackground, - buttonHoverBackground, - buttonBorder: contrastBorder - }), - progressBar: computeStyles(this.theme, { - progressBarBackground - }), - list: computeStyles(this.theme, { - listBackground: quickInputBackground, - // Look like focused when inactive. - listInactiveFocusForeground: listFocusForeground, - listInactiveFocusBackground: listFocusBackground, - listFocusOutline: activeContrastBorder, - listInactiveFocusOutline: activeContrastBorder, - pickerGroupBorder, - pickerGroupForeground, - }), - }; - } -} - -export const QuickPickManyToggle: ICommandAndKeybindingRule = { - id: 'workbench.action.quickPickManyToggle', - weight: KeybindingWeight.WorkbenchContrib, - when: inQuickOpenContext, - primary: 0, - handler: accessor => { - const quickInputService = accessor.get(IQuickInputService); - quickInputService.toggle(); - } -}; - -export const QuickPickBack: ICommandAndKeybindingRule = { - id: 'workbench.action.quickInputBack', - weight: KeybindingWeight.WorkbenchContrib + 50, - when: inQuickOpenContext, - primary: 0, - win: { primary: KeyMod.Alt | KeyCode.LeftArrow }, - mac: { primary: KeyMod.WinCtrl | KeyCode.US_MINUS }, - linux: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.US_MINUS }, - handler: accessor => { - const quickInputService = accessor.get(IQuickInputService); - quickInputService.back(); - } -}; - -KeybindingsRegistry.registerCommandAndKeybindingRule(QuickPickManyToggle); -KeybindingsRegistry.registerCommandAndKeybindingRule(QuickPickBack); - -registerSingleton(IQuickInputService, QuickInputService, true); - - - - - - -// TODO@Ben delete eventually when quick open is implemented using quick input -export class LegacyQuickInputQuickOpenController extends Disposable { - - private readonly inQuickOpenWidgets: Record = Object.create(null); - private readonly inQuickOpenContext = InQuickOpenContextKey.bindTo(this.contextKeyService); - - constructor( - @IQuickOpenService private readonly quickOpenService: IQuickOpenService, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IQuickInputService private readonly quickInputService: IQuickInputService - ) { - super(); - - this.registerListeners(); - } - - private registerListeners(): void { - this._register(this.quickOpenService.onShow(() => this.inQuickOpen('quickOpen', true))); - this._register(this.quickOpenService.onHide(() => this.inQuickOpen('quickOpen', false))); - - this._register(this.quickOpenService.onShow(() => this.quickInputService.hide(true))); - - this._register(this.quickInputService.onShow(() => { - this.quickOpenService.close(); - this.inQuickOpen('quickInput', true); - })); - - this._register(this.quickInputService.onHide(() => { - this.inQuickOpen('quickInput', false); - })); - } - - private inQuickOpen(widget: 'quickInput' | 'quickOpen', open: boolean) { - if (open) { - this.inQuickOpenWidgets[widget] = true; - } else { - delete this.inQuickOpenWidgets[widget]; - } - - if (Object.keys(this.inQuickOpenWidgets).length) { - if (!this.inQuickOpenContext.get()) { - this.inQuickOpenContext.set(true); - } - } else { - if (this.inQuickOpenContext.get()) { - this.inQuickOpenContext.reset(); - } - } - } -} - -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenActions.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenActions.ts index 0a8187a8759..3187a683ec4 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenActions.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenActions.ts @@ -99,3 +99,28 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ secondary: undefined } }); + +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'workbench.action.quickPickManyToggle', + weight: KeybindingWeight.WorkbenchContrib, + when: inQuickOpenContext, + primary: 0, + handler: accessor => { + const quickInputService = accessor.get(IQuickInputService); + quickInputService.toggle(); + } +}); + +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'workbench.action.quickInputBack', + weight: KeybindingWeight.WorkbenchContrib + 50, + when: inQuickOpenContext, + primary: 0, + win: { primary: KeyMod.Alt | KeyCode.LeftArrow }, + mac: { primary: KeyMod.WinCtrl | KeyCode.US_MINUS }, + linux: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.US_MINUS }, + handler: accessor => { + const quickInputService = accessor.get(IQuickInputService); + quickInputService.back(); + } +}); diff --git a/src/vs/workbench/browser/parts/quickopen/quickopen.ts b/src/vs/workbench/browser/parts/quickopen/quickopen.ts index 2e79e602673..5f7373c0d3f 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickopen.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickopen.ts @@ -8,9 +8,13 @@ import { Action } from 'vs/base/common/actions'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, RawContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { Registry } from 'vs/platform/registry/common/platform'; const inQuickOpenKey = 'inQuickOpen'; export const InQuickOpenContextKey = new RawContextKey(inQuickOpenKey, false); @@ -146,3 +150,56 @@ export class QuickOpenSelectPreviousAction extends BaseQuickOpenNavigateAction { super(id, label, false, false, quickOpenService, quickInputService, keybindingService); } } + +// TODO@Ben delete eventually when quick open is implemented using quick input +export class LegacyQuickInputQuickOpenController extends Disposable { + + private readonly inQuickOpenWidgets: Record = Object.create(null); + private readonly inQuickOpenContext = InQuickOpenContextKey.bindTo(this.contextKeyService); + + constructor( + @IQuickOpenService private readonly quickOpenService: IQuickOpenService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IQuickInputService private readonly quickInputService: IQuickInputService + ) { + super(); + + this.registerListeners(); + } + + private registerListeners(): void { + this._register(this.quickOpenService.onShow(() => this.inQuickOpen('quickOpen', true))); + this._register(this.quickOpenService.onHide(() => this.inQuickOpen('quickOpen', false))); + + this._register(this.quickOpenService.onShow(() => this.quickInputService.hide(true))); + + this._register(this.quickInputService.onShow(() => { + this.quickOpenService.close(); + this.inQuickOpen('quickInput', true); + })); + + this._register(this.quickInputService.onHide(() => { + this.inQuickOpen('quickInput', false); + })); + } + + private inQuickOpen(widget: 'quickInput' | 'quickOpen', open: boolean) { + if (open) { + this.inQuickOpenWidgets[widget] = true; + } else { + delete this.inQuickOpenWidgets[widget]; + } + + if (Object.keys(this.inQuickOpenWidgets).length) { + if (!this.inQuickOpenContext.get()) { + this.inQuickOpenContext.set(true); + } + } else { + if (this.inQuickOpenContext.get()) { + this.inQuickOpenContext.reset(); + } + } + } +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LegacyQuickInputQuickOpenController, LifecyclePhase.Ready); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index f528738e5e5..0aac4046cb5 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -41,7 +41,6 @@ import 'vs/workbench/api/browser/viewsExtensionPoint'; //#region --- workbench parts -import 'vs/workbench/browser/parts/quickinput/quickInput'; import 'vs/workbench/browser/parts/quickopen/quickOpenController'; import 'vs/workbench/browser/parts/editor/editorPart'; import 'vs/workbench/browser/parts/activitybar/activitybarPart'; @@ -113,6 +112,8 @@ import { OpenerService } from 'vs/editor/browser/services/openerService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync'; import { UserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSyncEnablementService'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { QuickInputService } from 'vs/platform/quickinput/browser/quickInput'; registerSingleton(IUserDataSyncEnablementService, UserDataSyncEnablementService); registerSingleton(IGlobalExtensionEnablementService, GlobalExtensionEnablementService); @@ -128,6 +129,7 @@ registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationSe registerSingleton(IMenuService, MenuService, true); registerSingleton(IDownloadService, DownloadService, true); registerSingleton(IOpenerService, OpenerService, true); +registerSingleton(IQuickInputService, QuickInputService, true); //#endregion -- GitLab