Path: blob/main/src/vs/workbench/browser/quickaccess.ts
3294 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { localize } from '../../nls.js';6import { ContextKeyExpr, RawContextKey } from '../../platform/contextkey/common/contextkey.js';7import { ICommandHandler } from '../../platform/commands/common/commands.js';8import { IKeybindingService } from '../../platform/keybinding/common/keybinding.js';9import { IQuickInputService } from '../../platform/quickinput/common/quickInput.js';10import { Disposable } from '../../base/common/lifecycle.js';11import { getIEditor } from '../../editor/browser/editorBrowser.js';12import { ICodeEditorViewState, IDiffEditorViewState } from '../../editor/common/editorCommon.js';13import { IResourceEditorInput, ITextResourceEditorInput } from '../../platform/editor/common/editor.js';14import { EditorInput } from '../common/editor/editorInput.js';15import { IEditorGroup, IEditorGroupsService } from '../services/editor/common/editorGroupsService.js';16import { ACTIVE_GROUP_TYPE, AUX_WINDOW_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from '../services/editor/common/editorService.js';17import { IUntitledTextResourceEditorInput, IUntypedEditorInput, GroupIdentifier, IEditorPane } from '../common/editor.js';1819export const inQuickPickContextKeyValue = 'inQuickOpen';20export const InQuickPickContextKey = new RawContextKey<boolean>(inQuickPickContextKeyValue, false, localize('inQuickOpen', "Whether keyboard focus is inside the quick open control"));21export const inQuickPickContext = ContextKeyExpr.has(inQuickPickContextKeyValue);2223export const defaultQuickAccessContextKeyValue = 'inFilesPicker';24export const defaultQuickAccessContext = ContextKeyExpr.and(inQuickPickContext, ContextKeyExpr.has(defaultQuickAccessContextKeyValue));2526export interface IWorkbenchQuickAccessConfiguration {27readonly workbench: {28readonly commandPalette: {29readonly history: number;30readonly preserveInput: boolean;31readonly experimental: {32readonly suggestCommands: boolean;33readonly enableNaturalLanguageSearch: boolean;34readonly askChatLocation: 'quickChat' | 'chatView';35};36};37readonly quickOpen: {38readonly enableExperimentalNewVersion: boolean;39readonly preserveInput: boolean;40};41};42}4344export function getQuickNavigateHandler(id: string, next?: boolean): ICommandHandler {45return accessor => {46const keybindingService = accessor.get(IKeybindingService);47const quickInputService = accessor.get(IQuickInputService);4849const keys = keybindingService.lookupKeybindings(id);50const quickNavigate = { keybindings: keys };5152quickInputService.navigate(!!next, quickNavigate);53};54}55export class PickerEditorState extends Disposable {56private _editorViewState: {57editor: EditorInput;58group: IEditorGroup;59state: ICodeEditorViewState | IDiffEditorViewState | undefined;60} | undefined = undefined;6162private readonly openedTransientEditors = new Set<EditorInput>(); // editors that were opened between set and restore6364constructor(65@IEditorService private readonly editorService: IEditorService,66@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService67) {68super();69}7071set(): void {72if (this._editorViewState) {73return; // return early if already done74}7576const activeEditorPane = this.editorService.activeEditorPane;77if (activeEditorPane) {78this._editorViewState = {79group: activeEditorPane.group,80editor: activeEditorPane.input,81state: getIEditor(activeEditorPane.getControl())?.saveViewState() ?? undefined,82};83}84}8586/**87* Open a transient editor such that it may be closed when the state is restored.88* Note that, when the state is restored, if the editor is no longer transient, it will not be closed.89*/90async openTransientEditor(editor: IResourceEditorInput | ITextResourceEditorInput | IUntitledTextResourceEditorInput | IUntypedEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE | AUX_WINDOW_GROUP_TYPE): Promise<IEditorPane | undefined> {91editor.options = { ...editor.options, transient: true };9293const editorPane = await this.editorService.openEditor(editor, group);94if (editorPane?.input && editorPane.input !== this._editorViewState?.editor && editorPane.group.isTransient(editorPane.input)) {95this.openedTransientEditors.add(editorPane.input);96}9798return editorPane;99}100101async restore(): Promise<void> {102if (this._editorViewState) {103for (const editor of this.openedTransientEditors) {104if (editor.isDirty()) {105continue;106}107108for (const group of this.editorGroupsService.groups) {109if (group.isTransient(editor)) {110await group.closeEditor(editor, { preserveFocus: true });111}112}113}114115await this._editorViewState.group.openEditor(this._editorViewState.editor, {116viewState: this._editorViewState.state,117preserveFocus: true // important to not close the picker as a result118});119120this.reset();121}122}123124reset() {125this._editorViewState = undefined;126this.openedTransientEditors.clear();127}128129override dispose(): void {130super.dispose();131132this.reset();133}134}135136137