Editors: revisit need for populateEditorId
and doResolveEditor
(#127787)
* extract `editorGroupFinder` to its own type
* Adopt new findGroup
* Address PR feedback
* make preferred group reusable
* 💄
Co-authored-by: Logan Ramos <lramos15@gmail.com>
This commit is contained in:
parent
c9aea49a87
commit
4fbcc9c3a2
|
@ -756,12 +756,22 @@ export interface IEditorInputWithOptions {
|
|||
options?: IEditorOptions;
|
||||
}
|
||||
|
||||
export interface IEditorInputWithOptionsAndGroup extends IEditorInputWithOptions {
|
||||
group: IEditorGroup;
|
||||
}
|
||||
|
||||
export function isEditorInputWithOptions(editor: unknown): editor is IEditorInputWithOptions {
|
||||
const candidate = editor as IEditorInputWithOptions | undefined;
|
||||
|
||||
return isEditorInput(candidate?.editor);
|
||||
}
|
||||
|
||||
export function isEditorInputWithOptionsAndGroup(editor: unknown): editor is IEditorInputWithOptionsAndGroup {
|
||||
const candidate = editor as IEditorInputWithOptionsAndGroup | undefined;
|
||||
|
||||
return isEditorInputWithOptions(editor) && candidate?.group !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Context passed into `EditorPane#setInput` to give additional
|
||||
* context information around why the editor was opened.
|
||||
|
|
|
@ -55,7 +55,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor {
|
|||
input.setForceOpenAsText();
|
||||
|
||||
// Try to let the user pick an override if there is one availabe
|
||||
let overridenInput: ReturnedOverride | undefined = await this.editorOverrideService.resolveEditorInput({ resource: editor.resource, options: { ...options, override: EditorOverride.PICK } }, this.group);
|
||||
let overridenInput: ReturnedOverride | undefined = await this.editorOverrideService.resolveEditor({ resource: editor.resource, options: { ...options, override: EditorOverride.PICK } }, this.group);
|
||||
if (overridenInput === OverrideStatus.NONE) {
|
||||
overridenInput = undefined;
|
||||
} else if (overridenInput === OverrideStatus.ABORT) {
|
||||
|
|
131
src/vs/workbench/services/editor/browser/editorGroupFinder.ts
Normal file
131
src/vs/workbench/services/editor/browser/editorGroupFinder.ts
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { EditorActivation } from 'vs/platform/editor/common/editor';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IEditorInputWithOptions, isEditorInputWithOptions, IUntypedEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IEditorGroup, GroupsOrder, preferredSideBySideGroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { PreferredGroup, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
/**
|
||||
* Finds the target `IEditorGroup` given the instructions provided
|
||||
* that is best for the editor and matches the preferred group if
|
||||
* posisble.
|
||||
*/
|
||||
export function findGroup(accessor: ServicesAccessor, editor: IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
export function findGroup(accessor: ServicesAccessor, editor: IEditorInputWithOptions, preferredGroup: PreferredGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
export function findGroup(accessor: ServicesAccessor, editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
export function findGroup(accessor: ServicesAccessor, editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): [IEditorGroup, EditorActivation | undefined] {
|
||||
const editorGroupService = accessor.get(IEditorGroupsService);
|
||||
const configurationService = accessor.get(IConfigurationService);
|
||||
|
||||
const group = doFindGroup(editor, preferredGroup, editorGroupService, configurationService);
|
||||
|
||||
// Resolve editor activation strategy
|
||||
let activation: EditorActivation | undefined = undefined;
|
||||
if (
|
||||
editorGroupService.activeGroup !== group && // only if target group is not already active
|
||||
editor.options && !editor.options.inactive && // never for inactive editors
|
||||
editor.options.preserveFocus && // only if preserveFocus
|
||||
typeof editor.options.activation !== 'number' && // only if activation is not already defined (either true or false)
|
||||
preferredGroup !== SIDE_GROUP // never for the SIDE_GROUP
|
||||
) {
|
||||
// If the resolved group is not the active one, we typically
|
||||
// want the group to become active. There are a few cases
|
||||
// where we stay away from encorcing this, e.g. if the caller
|
||||
// is already providing `activation`.
|
||||
//
|
||||
// Specifically for historic reasons we do not activate a
|
||||
// group is it is opened as `SIDE_GROUP` with `preserveFocus:true`.
|
||||
// repeated Alt-clicking of files in the explorer always open
|
||||
// into the same side group and not cause a group to be created each time.
|
||||
activation = EditorActivation.ACTIVATE;
|
||||
}
|
||||
|
||||
return [group, activation];
|
||||
}
|
||||
|
||||
function doFindGroup(input: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined, editorGroupService: IEditorGroupsService, configurationService: IConfigurationService): IEditorGroup {
|
||||
let group: IEditorGroup | undefined;
|
||||
let editor = isEditorInputWithOptions(input) ? input.editor : input;
|
||||
let options = input.options;
|
||||
|
||||
// Group: Instance of Group
|
||||
if (preferredGroup && typeof preferredGroup !== 'number') {
|
||||
group = preferredGroup;
|
||||
}
|
||||
|
||||
// Group: Side by Side
|
||||
else if (preferredGroup === SIDE_GROUP) {
|
||||
group = doFindSideBySideGroup(editorGroupService, configurationService);
|
||||
}
|
||||
|
||||
// Group: Specific Group
|
||||
else if (typeof preferredGroup === 'number' && preferredGroup >= 0) {
|
||||
group = editorGroupService.getGroup(preferredGroup);
|
||||
}
|
||||
|
||||
// Group: Unspecified without a specific index to open
|
||||
else if (!options || typeof options.index !== 'number') {
|
||||
const groupsByLastActive = editorGroupService.getGroups(GroupsOrder.MOST_RECENTLY_ACTIVE);
|
||||
|
||||
// Respect option to reveal an editor if it is already visible in any group
|
||||
if (options?.revealIfVisible) {
|
||||
for (const lastActiveGroup of groupsByLastActive) {
|
||||
if (lastActiveGroup.isActive(editor)) {
|
||||
group = lastActiveGroup;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Respect option to reveal an editor if it is open (not necessarily visible)
|
||||
// Still prefer to reveal an editor in a group where the editor is active though.
|
||||
if (!group) {
|
||||
if (options?.revealIfOpened || configurationService.getValue<boolean>('workbench.editor.revealIfOpen')) {
|
||||
let groupWithInputActive: IEditorGroup | undefined = undefined;
|
||||
let groupWithInputOpened: IEditorGroup | undefined = undefined;
|
||||
|
||||
for (const group of groupsByLastActive) {
|
||||
if (group.contains(editor)) {
|
||||
if (!groupWithInputOpened) {
|
||||
groupWithInputOpened = group;
|
||||
}
|
||||
|
||||
if (!groupWithInputActive && group.isActive(editor)) {
|
||||
groupWithInputActive = group;
|
||||
}
|
||||
}
|
||||
|
||||
if (groupWithInputOpened && groupWithInputActive) {
|
||||
break; // we found all groups we wanted
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer a target group where the input is visible
|
||||
group = groupWithInputActive || groupWithInputOpened;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to active group if target not valid
|
||||
if (!group) {
|
||||
group = editorGroupService.activeGroup;
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function doFindSideBySideGroup(editorGroupService: IEditorGroupsService, configurationService: IConfigurationService): IEditorGroup {
|
||||
const direction = preferredSideBySideGroupDirection(configurationService);
|
||||
|
||||
let neighbourGroup = editorGroupService.findGroup({ direction });
|
||||
if (!neighbourGroup) {
|
||||
neighbourGroup = editorGroupService.addGroup(editorGroupService.activeGroup, direction);
|
||||
}
|
||||
|
||||
return neighbourGroup;
|
||||
}
|
|
@ -10,7 +10,7 @@ import { basename, extname, isEqual } from 'vs/base/common/resources';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { EditorActivation, EditorOverride, IEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, IEditorInput, IEditorInputWithOptions, isResourceDiffEditorInput, isUntitledResourceEditorInput, IUntypedEditorInput, SideBySideEditor } from 'vs/workbench/common/editor';
|
||||
import { DEFAULT_EDITOR_ASSOCIATION, EditorResourceAccessor, IEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, isResourceDiffEditorInput, isUntitledResourceEditorInput, IUntypedEditorInput, SideBySideEditor, UntypedEditorContext } from 'vs/workbench/common/editor';
|
||||
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { RegisteredEditorInfo, RegisteredEditorPriority, RegisteredEditorOptions, DiffEditorInputFactoryFunction, EditorAssociation, EditorAssociations, EditorInputFactoryFunction, editorsAssociationsSettingId, globMatchesResource, IEditorOverrideService, priorityToRank, ReturnedOverride, OverrideStatus, UntitledEditorInputFactoryFunction } from 'vs/workbench/services/editor/common/editorOverrideService';
|
||||
|
@ -22,6 +22,9 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
|||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { findGroup } from 'vs/workbench/services/editor/browser/editorGroupFinder';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { PreferredGroup } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
interface RegisteredEditor {
|
||||
globPattern: string | glob.IRelativePattern,
|
||||
|
@ -48,6 +51,7 @@ export class EditorOverrideService extends Disposable implements IEditorOverride
|
|||
|
||||
constructor(
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
|
@ -80,8 +84,50 @@ export class EditorOverrideService extends Disposable implements IEditorOverride
|
|||
}));
|
||||
}
|
||||
|
||||
async populateEditorId(editor: IUntypedEditorInput): Promise<{ conflictingDefault: boolean } | undefined> {
|
||||
let resource = EditorResourceAccessor.getCanonicalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY });
|
||||
private async resolveUntypedInputAndGroup(editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<[IUntypedEditorInput, IEditorGroup, EditorActivation | undefined] | undefined> {
|
||||
let untypedEditor: IUntypedEditorInput | undefined = undefined;
|
||||
|
||||
// Typed: convert to untyped to be able to resolve the override
|
||||
if (isEditorInputWithOptions(editor)) {
|
||||
untypedEditor = editor.editor.toUntyped(undefined, UntypedEditorContext.Default);
|
||||
|
||||
if (untypedEditor) {
|
||||
// Preserve original options: specifically it is
|
||||
// possible that a `override` was defined from
|
||||
// the outside and we do not want to loose it.
|
||||
untypedEditor.options = { ...untypedEditor.options, ...editor.options };
|
||||
}
|
||||
}
|
||||
|
||||
// Untyped: take as is
|
||||
else {
|
||||
untypedEditor = editor;
|
||||
}
|
||||
|
||||
// Typed editors that cannot convert to untyped will be returned as undefined
|
||||
if (!untypedEditor) {
|
||||
return undefined;
|
||||
}
|
||||
// Use the untyped editor to find a group
|
||||
const [group, activation] = this.instantiationService.invokeFunction(findGroup, untypedEditor, preferredGroup);
|
||||
|
||||
return [untypedEditor, group, activation];
|
||||
}
|
||||
|
||||
async resolveEditor(editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ReturnedOverride> {
|
||||
const resolvedUntypedAndGroup = await this.resolveUntypedInputAndGroup(editor, preferredGroup);
|
||||
if (!resolvedUntypedAndGroup) {
|
||||
return OverrideStatus.NONE;
|
||||
}
|
||||
// Get the resolved untyped editor, group, and activation
|
||||
const [untypedEditor, group, activation] = resolvedUntypedAndGroup;
|
||||
if (activation) {
|
||||
untypedEditor.options = { ...untypedEditor.options, activation };
|
||||
}
|
||||
|
||||
let resource = EditorResourceAccessor.getCanonicalUri(untypedEditor, { supportSideBySide: SideBySideEditor.PRIMARY });
|
||||
let options = untypedEditor.options;
|
||||
|
||||
// If it was an override before we await for the extensions to activate and then proceed with overriding or else they won't be registered
|
||||
if (this.cache && resource && this.resourceMatchesCache(resource)) {
|
||||
await this.extensionService.whenInstalledExtensionsRegistered();
|
||||
|
@ -91,47 +137,28 @@ export class EditorOverrideService extends Disposable implements IEditorOverride
|
|||
resource = URI.from({ scheme: Schemas.untitled });
|
||||
}
|
||||
|
||||
if (editor.options?.override === EditorOverride.DISABLED) {
|
||||
if (untypedEditor.options?.override === EditorOverride.DISABLED) {
|
||||
throw new Error(`Calling resolve editor override when override is explicitly disabled!`);
|
||||
}
|
||||
|
||||
if (editor.options?.override === EditorOverride.PICK) {
|
||||
const picked = await this.doPickEditorOverride(editor);
|
||||
if (untypedEditor.options?.override === EditorOverride.PICK) {
|
||||
const picked = await this.doPickEditorOverride(untypedEditor);
|
||||
// If the picker was cancelled we will stop resolving the override
|
||||
if (!picked) {
|
||||
return undefined;
|
||||
return OverrideStatus.ABORT;
|
||||
}
|
||||
// Populate the options with the new ones
|
||||
editor.options = picked;
|
||||
return { conflictingDefault: false };
|
||||
}
|
||||
|
||||
const { editor: selectedEditor, conflictingDefault } = this.getEditor(resource, editor.options?.override);
|
||||
editor.options = { ...editor.options, override: selectedEditor?.editorInfo.id };
|
||||
return { conflictingDefault };
|
||||
}
|
||||
|
||||
async resolveEditorInput(editor: IUntypedEditorInput, group: IEditorGroup, conflictingDefault?: boolean): Promise<ReturnedOverride> {
|
||||
let resource = EditorResourceAccessor.getCanonicalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY });
|
||||
let options = editor.options;
|
||||
|
||||
|
||||
if (resource === undefined) {
|
||||
resource = URI.from({ scheme: Schemas.untitled });
|
||||
}
|
||||
|
||||
if (!options?.override || typeof options.override !== 'string') {
|
||||
await this.populateEditorId(editor);
|
||||
untypedEditor.options = picked;
|
||||
}
|
||||
|
||||
// Resolved the override as much as possible, now find a given editor (cast here is ok because we resolve down to a string above)
|
||||
const { editor: selectedEditor } = this.getEditor(resource, editor.options?.override as string | undefined);
|
||||
const { editor: selectedEditor, conflictingDefault } = this.getEditor(resource, untypedEditor.options?.override as (string | EditorOverride.EXCLUSIVE_ONLY | undefined));
|
||||
if (!selectedEditor) {
|
||||
return OverrideStatus.NONE;
|
||||
}
|
||||
|
||||
const handlesDiff = typeof selectedEditor.options?.canHandleDiff === 'function' ? selectedEditor.options.canHandleDiff() : selectedEditor.options?.canHandleDiff;
|
||||
if (handlesDiff === false && isResourceDiffEditorInput(editor)) {
|
||||
if (handlesDiff === false && isResourceDiffEditorInput(untypedEditor)) {
|
||||
return OverrideStatus.NONE;
|
||||
}
|
||||
|
||||
|
@ -139,17 +166,17 @@ export class EditorOverrideService extends Disposable implements IEditorOverride
|
|||
const activeEditor = group.activeEditor;
|
||||
const isActive = activeEditor ? activeEditor.editorId === selectedEditor.editorInfo.id && isEqual(activeEditor.resource, resource) : false;
|
||||
if (activeEditor && isActive) {
|
||||
return { editor: activeEditor, options };
|
||||
return { editor: activeEditor, options, group };
|
||||
}
|
||||
const input = await this.doOverrideEditorInput(editor, group, selectedEditor);
|
||||
const input = await this.doOverrideEditorInput(untypedEditor, group, selectedEditor);
|
||||
if (conflictingDefault && input) {
|
||||
// Show the conflicting default dialog
|
||||
await this.doHandleConflictingDefaults(resource, selectedEditor.editorInfo.label, editor, input.editor, group);
|
||||
await this.doHandleConflictingDefaults(resource, selectedEditor.editorInfo.label, untypedEditor, input.editor, group);
|
||||
}
|
||||
|
||||
if (input) {
|
||||
this.sendOverrideTelemetry(input.editor);
|
||||
return input;
|
||||
return { ...input, group };
|
||||
}
|
||||
return OverrideStatus.ABORT;
|
||||
}
|
||||
|
@ -440,7 +467,7 @@ export class EditorOverrideService extends Disposable implements IEditorOverride
|
|||
return;
|
||||
}
|
||||
untypedInput.options = picked;
|
||||
const replacementEditor = await this.resolveEditorInput(untypedInput, group);
|
||||
const replacementEditor = await this.resolveEditor(untypedInput, group);
|
||||
if (replacementEditor === OverrideStatus.ABORT || replacementEditor === OverrideStatus.NONE) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IResourceEditorInput, IEditorOptions, EditorActivation, EditorOverride, IResourceEditorInputIdentifier, ITextEditorOptions, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { SideBySideEditor, IEditorInput, IEditorPane, GroupIdentifier, IFileEditorInput, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputFactoryRegistry, EditorExtensions, IEditorInputWithOptions, isEditorInputWithOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditorPane, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, isTextEditorPane, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, EditorInputCapabilities, isResourceDiffEditorInput, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, UntypedEditorContext, isResourceEditorInput, isEditorInput } from 'vs/workbench/common/editor';
|
||||
import { SideBySideEditor, IEditorInput, IEditorPane, GroupIdentifier, IFileEditorInput, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputFactoryRegistry, EditorExtensions, IEditorInputWithOptions, isEditorInputWithOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditorPane, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, isTextEditorPane, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, EditorInputCapabilities, isResourceDiffEditorInput, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, isResourceEditorInput, isEditorInput, isEditorInputWithOptionsAndGroup } from 'vs/workbench/common/editor';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
|
@ -18,8 +18,8 @@ import { Event, Emitter } from 'vs/base/common/event';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { basename, joinPath } from 'vs/base/common/resources';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsOrder, IEditorReplacement, GroupChangeKind, preferredSideBySideGroupDirection, isEditorReplacement, isEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { SIDE_GROUP, IUntypedEditorReplacement, IEditorService, SIDE_GROUP_TYPE, ACTIVE_GROUP_TYPE, ISaveEditorsOptions, ISaveAllEditorsOptions, IRevertAllEditorsOptions, IBaseSaveRevertAllEditorOptions, IOpenEditorsOptions } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsOrder, IEditorReplacement, GroupChangeKind, isEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IUntypedEditorReplacement, IEditorService, ISaveEditorsOptions, ISaveAllEditorsOptions, IRevertAllEditorsOptions, IBaseSaveRevertAllEditorOptions, IOpenEditorsOptions, PreferredGroup, isPreferredGroup } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Disposable, IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { coalesce, distinct } from 'vs/base/common/arrays';
|
||||
|
@ -34,19 +34,13 @@ import { Promises, timeout } from 'vs/base/common/async';
|
|||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { indexOfPath } from 'vs/base/common/extpath';
|
||||
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
|
||||
import { RegisteredEditorPriority, IEditorOverrideService, OverrideStatus, ReturnedOverride } from 'vs/workbench/services/editor/common/editorOverrideService';
|
||||
import { RegisteredEditorPriority, IEditorOverrideService, OverrideStatus } from 'vs/workbench/services/editor/common/editorOverrideService';
|
||||
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { IWorkspaceTrustRequestService, WorkspaceTrustUriResponse } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { findGroup } from 'vs/workbench/services/editor/browser/editorGroupFinder';
|
||||
|
||||
type CachedEditorInput = TextResourceEditorInput | IFileEditorInput | UntitledTextEditorInput;
|
||||
type OpenInEditorGroup = IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE;
|
||||
|
||||
function isOpenInEditorGroup(obj: unknown): obj is OpenInEditorGroup {
|
||||
const candidate = obj as OpenInEditorGroup | undefined;
|
||||
|
||||
return typeof obj === 'number' || isEditorGroup(candidate);
|
||||
}
|
||||
|
||||
export class EditorService extends Disposable implements EditorServiceImpl {
|
||||
|
||||
|
@ -514,36 +508,34 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
//#region openEditor()
|
||||
|
||||
openEditor(editor: IEditorInput, options?: IEditorOptions, group?: OpenInEditorGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IUntypedEditorInput, group?: OpenInEditorGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IResourceEditorInput, group?: OpenInEditorGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: ITextResourceEditorInput | IUntitledTextResourceEditorInput, group?: OpenInEditorGroup): Promise<ITextEditorPane | undefined>;
|
||||
openEditor(editor: IResourceDiffEditorInput, group?: OpenInEditorGroup): Promise<ITextDiffEditorPane | undefined>;
|
||||
async openEditor(editor: IEditorInput | IUntypedEditorInput, optionsOrPreferredGroup?: IEditorOptions | OpenInEditorGroup, preferredGroup?: OpenInEditorGroup): Promise<IEditorPane | undefined> {
|
||||
openEditor(editor: IEditorInput, options?: IEditorOptions, group?: PreferredGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IUntypedEditorInput, options?: IEditorOptions, group?: PreferredGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IResourceEditorInput, group?: PreferredGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: ITextResourceEditorInput | IUntitledTextResourceEditorInput, group?: PreferredGroup): Promise<ITextEditorPane | undefined>;
|
||||
openEditor(editor: IResourceDiffEditorInput, group?: PreferredGroup): Promise<ITextDiffEditorPane | undefined>;
|
||||
openEditor(editor: IEditorInput | IUntypedEditorInput, optionsOrPreferredGroup?: IEditorOptions | PreferredGroup, preferredGroup?: PreferredGroup): Promise<IEditorPane | undefined>;
|
||||
async openEditor(editor: IEditorInput | IUntypedEditorInput, optionsOrPreferredGroup?: IEditorOptions | PreferredGroup, preferredGroup?: PreferredGroup): Promise<IEditorPane | undefined> {
|
||||
let typedEditor: IEditorInput | undefined = undefined;
|
||||
let options = isEditorInput(editor) ? optionsOrPreferredGroup as IEditorOptions : editor.options;
|
||||
let group: IEditorGroup | undefined = undefined;
|
||||
let activation: EditorActivation | undefined = undefined;
|
||||
|
||||
if (isOpenInEditorGroup(optionsOrPreferredGroup)) {
|
||||
if (isPreferredGroup(optionsOrPreferredGroup)) {
|
||||
preferredGroup = optionsOrPreferredGroup;
|
||||
}
|
||||
|
||||
// Resolve override unless disabled
|
||||
if (options?.override !== EditorOverride.DISABLED) {
|
||||
const [resolvedEditor, resolvedGroup, resolvedActivation] = await this.doResolveEditor(isEditorInput(editor) ? { editor, options } : editor, preferredGroup);
|
||||
const resolvedEditor = await this.editorOverrideService.resolveEditor(isEditorInput(editor) ? { editor, options } : editor, preferredGroup);
|
||||
|
||||
if (resolvedEditor === OverrideStatus.ABORT) {
|
||||
return; // skip editor if override is aborted
|
||||
}
|
||||
|
||||
group = resolvedGroup;
|
||||
activation = resolvedActivation;
|
||||
|
||||
// We resolved an editor to use
|
||||
if (isEditorInputWithOptions(resolvedEditor)) {
|
||||
if (isEditorInputWithOptionsAndGroup(resolvedEditor)) {
|
||||
typedEditor = resolvedEditor.editor;
|
||||
options = resolvedEditor.options;
|
||||
group = resolvedEditor.group;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,185 +546,26 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
// If group still isn't defined because of a disabled override we resolve it
|
||||
if (!group) {
|
||||
([group, activation] = this.findTargetGroup({ editor: typedEditor, options }, preferredGroup));
|
||||
}
|
||||
let activation: EditorActivation | undefined = undefined;
|
||||
([group, activation] = this.instantiationService.invokeFunction(findGroup, { editor: typedEditor, options }, preferredGroup));
|
||||
|
||||
// Mixin editor group activation if any
|
||||
if (activation) {
|
||||
options = { ...options, activation };
|
||||
// Mixin editor group activation if returned
|
||||
if (activation) {
|
||||
options = { ...options, activation };
|
||||
}
|
||||
}
|
||||
|
||||
return group.openEditor(typedEditor, options);
|
||||
}
|
||||
|
||||
private async doResolveEditor(editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: OpenInEditorGroup | undefined): Promise<[ReturnedOverride, IEditorGroup | undefined, EditorActivation | undefined]> {
|
||||
let untypedEditor: IUntypedEditorInput | undefined = undefined;
|
||||
|
||||
// Typed: convert to untyped to be able to resolve the override
|
||||
if (isEditorInputWithOptions(editor)) {
|
||||
untypedEditor = editor.editor.toUntyped(undefined, UntypedEditorContext.Default);
|
||||
|
||||
if (untypedEditor) {
|
||||
// Preserve original options: specifically it is
|
||||
// possible that a `override` was defined from
|
||||
// the outside and we do not want to loose it.
|
||||
untypedEditor.options = { ...untypedEditor.options, ...editor.options };
|
||||
}
|
||||
}
|
||||
|
||||
// Untyped: take as is
|
||||
else {
|
||||
untypedEditor = editor;
|
||||
}
|
||||
|
||||
// Typed editors that cannot convert to untyped will be taken
|
||||
// as is without override.
|
||||
if (!untypedEditor) {
|
||||
return [OverrideStatus.NONE, undefined, undefined];
|
||||
}
|
||||
|
||||
// We need a `override` for the untyped editor if it is
|
||||
// not there so we call into the editor override service
|
||||
let hasConflictingDefaults = false;
|
||||
if (typeof untypedEditor.options?.override !== 'string') {
|
||||
const populatedInfo = await this.editorOverrideService.populateEditorId(untypedEditor);
|
||||
if (!populatedInfo) {
|
||||
return [OverrideStatus.ABORT, undefined, undefined]; // we could not resolve the editor id
|
||||
}
|
||||
|
||||
hasConflictingDefaults = populatedInfo.conflictingDefault;
|
||||
}
|
||||
|
||||
// If we didn't get an override just return as none and let the editor continue as normal
|
||||
if (!untypedEditor.options?.override) {
|
||||
return [OverrideStatus.NONE, undefined, undefined];
|
||||
}
|
||||
|
||||
// Find the target group for the editor
|
||||
const [group, activation] = this.findTargetGroup(untypedEditor, preferredGroup);
|
||||
|
||||
return [await this.editorOverrideService.resolveEditorInput(untypedEditor, group, hasConflictingDefaults), group, activation];
|
||||
}
|
||||
|
||||
private findTargetGroup(editor: IEditorInputWithOptions, preferredGroup: OpenInEditorGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
private findTargetGroup(editor: IUntypedEditorInput, preferredGroup: OpenInEditorGroup | undefined): [IEditorGroup, EditorActivation | undefined];
|
||||
private findTargetGroup(editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: OpenInEditorGroup | undefined): [IEditorGroup, EditorActivation | undefined] {
|
||||
const group = this.doFindTargetGroup(editor, preferredGroup);
|
||||
|
||||
// Resolve editor activation strategy
|
||||
let activation: EditorActivation | undefined = undefined;
|
||||
if (
|
||||
this.editorGroupService.activeGroup !== group && // only if target group is not already active
|
||||
editor.options && !editor.options.inactive && // never for inactive editors
|
||||
editor.options.preserveFocus && // only if preserveFocus
|
||||
typeof editor.options.activation !== 'number' && // only if activation is not already defined (either true or false)
|
||||
preferredGroup !== SIDE_GROUP // never for the SIDE_GROUP
|
||||
) {
|
||||
// If the resolved group is not the active one, we typically
|
||||
// want the group to become active. There are a few cases
|
||||
// where we stay away from encorcing this, e.g. if the caller
|
||||
// is already providing `activation`.
|
||||
//
|
||||
// Specifically for historic reasons we do not activate a
|
||||
// group is it is opened as `SIDE_GROUP` with `preserveFocus:true`.
|
||||
// repeated Alt-clicking of files in the explorer always open
|
||||
// into the same side group and not cause a group to be created each time.
|
||||
activation = EditorActivation.ACTIVATE;
|
||||
}
|
||||
|
||||
return [group, activation];
|
||||
}
|
||||
|
||||
private doFindTargetGroup(input: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: OpenInEditorGroup | undefined): IEditorGroup {
|
||||
let group: IEditorGroup | undefined;
|
||||
let editor = isEditorInputWithOptions(input) ? input.editor : input;
|
||||
let options = input.options;
|
||||
|
||||
// Group: Instance of Group
|
||||
if (preferredGroup && typeof preferredGroup !== 'number') {
|
||||
group = preferredGroup;
|
||||
}
|
||||
|
||||
// Group: Side by Side
|
||||
else if (preferredGroup === SIDE_GROUP) {
|
||||
group = this.findSideBySideGroup();
|
||||
}
|
||||
|
||||
// Group: Specific Group
|
||||
else if (typeof preferredGroup === 'number' && preferredGroup >= 0) {
|
||||
group = this.editorGroupService.getGroup(preferredGroup);
|
||||
}
|
||||
|
||||
// Group: Unspecified without a specific index to open
|
||||
else if (!options || typeof options.index !== 'number') {
|
||||
const groupsByLastActive = this.editorGroupService.getGroups(GroupsOrder.MOST_RECENTLY_ACTIVE);
|
||||
|
||||
// Respect option to reveal an editor if it is already visible in any group
|
||||
if (options?.revealIfVisible) {
|
||||
for (const lastActiveGroup of groupsByLastActive) {
|
||||
if (lastActiveGroup.isActive(editor)) {
|
||||
group = lastActiveGroup;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Respect option to reveal an editor if it is open (not necessarily visible)
|
||||
// Still prefer to reveal an editor in a group where the editor is active though.
|
||||
if (!group) {
|
||||
if (options?.revealIfOpened || this.configurationService.getValue<boolean>('workbench.editor.revealIfOpen')) {
|
||||
let groupWithInputActive: IEditorGroup | undefined = undefined;
|
||||
let groupWithInputOpened: IEditorGroup | undefined = undefined;
|
||||
|
||||
for (const group of groupsByLastActive) {
|
||||
if (group.contains(editor)) {
|
||||
if (!groupWithInputOpened) {
|
||||
groupWithInputOpened = group;
|
||||
}
|
||||
|
||||
if (!groupWithInputActive && group.isActive(editor)) {
|
||||
groupWithInputActive = group;
|
||||
}
|
||||
}
|
||||
|
||||
if (groupWithInputOpened && groupWithInputActive) {
|
||||
break; // we found all groups we wanted
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer a target group where the input is visible
|
||||
group = groupWithInputActive || groupWithInputOpened;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to active group if target not valid
|
||||
if (!group) {
|
||||
group = this.editorGroupService.activeGroup;
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
private findSideBySideGroup(): IEditorGroup {
|
||||
const direction = preferredSideBySideGroupDirection(this.configurationService);
|
||||
|
||||
let neighbourGroup = this.editorGroupService.findGroup({ direction });
|
||||
if (!neighbourGroup) {
|
||||
neighbourGroup = this.editorGroupService.addGroup(this.editorGroupService.activeGroup, direction);
|
||||
}
|
||||
|
||||
return neighbourGroup;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region openEditors()
|
||||
|
||||
openEditors(editors: IEditorInputWithOptions[], group?: OpenInEditorGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]>;
|
||||
openEditors(editors: IUntypedEditorInput[], group?: OpenInEditorGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]>;
|
||||
openEditors(editors: Array<IEditorInputWithOptions | IUntypedEditorInput>, group?: OpenInEditorGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]>;
|
||||
async openEditors(editors: Array<IEditorInputWithOptions | IUntypedEditorInput>, preferredGroup?: OpenInEditorGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]> {
|
||||
openEditors(editors: IEditorInputWithOptions[], group?: PreferredGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]>;
|
||||
openEditors(editors: IUntypedEditorInput[], group?: PreferredGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]>;
|
||||
openEditors(editors: Array<IEditorInputWithOptions | IUntypedEditorInput>, group?: PreferredGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]>;
|
||||
async openEditors(editors: Array<IEditorInputWithOptions | IUntypedEditorInput>, preferredGroup?: PreferredGroup, options?: IOpenEditorsOptions): Promise<IEditorPane[]> {
|
||||
|
||||
// Pass all editors to trust service to determine if
|
||||
// we should proceed with opening the editors if we
|
||||
|
@ -752,17 +585,16 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
// Resolve override unless disabled
|
||||
if (editor.options?.override !== EditorOverride.DISABLED) {
|
||||
const [resolvedEditor, resolvedGroup] = await this.doResolveEditor(editor, preferredGroup);
|
||||
const resolvedEditor = await this.editorOverrideService.resolveEditor(editor, preferredGroup);
|
||||
|
||||
if (resolvedEditor === OverrideStatus.ABORT) {
|
||||
continue; // skip editor if override is aborted
|
||||
}
|
||||
|
||||
group = resolvedGroup;
|
||||
|
||||
// We resolved an editor to use
|
||||
if (isEditorInputWithOptions(resolvedEditor)) {
|
||||
if (isEditorInputWithOptionsAndGroup(resolvedEditor)) {
|
||||
typedEditor = resolvedEditor;
|
||||
group = resolvedEditor.group;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,7 +605,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
// If group still isn't defined because of a disabled override we resolve it
|
||||
if (!group) {
|
||||
group = this.doFindTargetGroup(typedEditor, preferredGroup);
|
||||
[group] = this.instantiationService.invokeFunction(findGroup, typedEditor, preferredGroup);
|
||||
}
|
||||
|
||||
// Update map of groups to editors
|
||||
|
@ -991,7 +823,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
|
||||
// Resolve override unless disabled
|
||||
if (override !== EditorOverride.DISABLED) {
|
||||
const [resolvedEditor] = await this.doResolveEditor(
|
||||
const resolvedEditor = await this.editorOverrideService.resolveEditor(
|
||||
isEditorReplacement(replacement) ? { editor: replacement.replacement, options: replacement.options } : replacement.replacement,
|
||||
targetGroup
|
||||
);
|
||||
|
@ -1001,7 +833,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
}
|
||||
|
||||
// We resolved an editor to use
|
||||
if (isEditorInputWithOptions(resolvedEditor)) {
|
||||
if (isEditorInputWithOptionsAndGroup(resolvedEditor)) {
|
||||
typedReplacement = {
|
||||
editor: replacement.editor,
|
||||
replacement: resolvedEditor.editor,
|
||||
|
|
|
@ -15,8 +15,9 @@ import { Extensions as ConfigurationExtensions, IConfigurationNode, IConfigurati
|
|||
import { IResourceEditorInput, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IEditorInputWithOptions, IResourceDiffEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IEditorInputWithOptions, IEditorInputWithOptionsAndGroup, IResourceDiffEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { PreferredGroup } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
export const IEditorOverrideService = createDecorator<IEditorOverrideService>('editorOverrideService');
|
||||
|
||||
|
@ -75,7 +76,7 @@ export const enum OverrideStatus {
|
|||
NONE = 2,
|
||||
}
|
||||
|
||||
export type ReturnedOverride = IEditorInputWithOptions | OverrideStatus;
|
||||
export type ReturnedOverride = IEditorInputWithOptionsAndGroup | OverrideStatus;
|
||||
|
||||
export type RegisteredEditorOptions = {
|
||||
/**
|
||||
|
@ -139,22 +140,13 @@ export interface IEditorOverrideService {
|
|||
createDiffEditorInput?: DiffEditorInputFactoryFunction
|
||||
): IDisposable;
|
||||
|
||||
/**
|
||||
* Populates the override field of the untyped editor input
|
||||
* @param editor The editor input
|
||||
* @returns If one is populated whether or not there was a conflicting default, else undefined
|
||||
*/
|
||||
populateEditorId(editor: IUntypedEditorInput): Promise<{ conflictingDefault: boolean } | undefined>
|
||||
|
||||
/**
|
||||
* Given an editor determines if there's a suitable override for it, if so returns an IEditorInputWithOptions for opening
|
||||
* @param editor The editor to override
|
||||
* @param options The current options for the editor
|
||||
* @param group The current group
|
||||
* @param conflictingDefault Whether or not to show the conflicting default prompt
|
||||
* @param preferredGroup The group you want to open the editor in
|
||||
* @returns An IEditorInputWithOptionsAndGroup if there is an available override or a status of how to proceed
|
||||
*/
|
||||
resolveEditorInput(editor: IUntypedEditorInput, group: IEditorGroup, conflictingDefault?: boolean): Promise<ReturnedOverride>;
|
||||
resolveEditor(editor: IEditorInputWithOptions | IUntypedEditorInput, preferredGroup: PreferredGroup | undefined): Promise<ReturnedOverride>;
|
||||
|
||||
/**
|
||||
* Given a resource returns all the editor ids that match that resource
|
||||
|
|
|
@ -8,12 +8,40 @@ import { IResourceEditorInput, IEditorOptions, IResourceEditorInputIdentifier, I
|
|||
import { IEditorInput, IEditorPane, GroupIdentifier, IEditorInputWithOptions, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, ITextEditorPane, ITextDiffEditorPane, IEditorIdentifier, ISaveOptions, IRevertOptions, EditorsOrder, IVisibleEditorPane, IEditorCloseEvent, IUntypedEditorInput } from 'vs/workbench/common/editor';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IEditor, IDiffEditor } from 'vs/editor/common/editorCommon';
|
||||
import { IEditorGroup, IEditorReplacement } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorGroup, IEditorReplacement, isEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
|
||||
|
||||
export const IEditorService = createDecorator<IEditorService>('editorService');
|
||||
|
||||
/**
|
||||
* Open an editor in the currently active group.
|
||||
*/
|
||||
export const ACTIVE_GROUP = -1;
|
||||
export type ACTIVE_GROUP_TYPE = typeof ACTIVE_GROUP;
|
||||
|
||||
/**
|
||||
* Open an editor to the side of the active group.
|
||||
*/
|
||||
export const SIDE_GROUP = -2;
|
||||
export type SIDE_GROUP_TYPE = typeof SIDE_GROUP;
|
||||
|
||||
export type PreferredGroup = IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE;
|
||||
|
||||
export function isPreferredGroup(obj: unknown): obj is PreferredGroup {
|
||||
const candidate = obj as PreferredGroup | undefined;
|
||||
|
||||
return typeof obj === 'number' || isEditorGroup(candidate);
|
||||
}
|
||||
|
||||
export interface ISaveEditorsOptions extends ISaveOptions {
|
||||
|
||||
/**
|
||||
* If true, will ask for a location of the editor to save to.
|
||||
*/
|
||||
readonly saveAs?: boolean;
|
||||
}
|
||||
|
||||
export interface IUntypedEditorReplacement {
|
||||
readonly editor: IEditorInput;
|
||||
readonly replacement: IUntypedEditorInput;
|
||||
|
@ -25,20 +53,6 @@ export interface IUntypedEditorReplacement {
|
|||
forceReplaceDirty?: boolean;
|
||||
}
|
||||
|
||||
export const ACTIVE_GROUP = -1;
|
||||
export type ACTIVE_GROUP_TYPE = typeof ACTIVE_GROUP;
|
||||
|
||||
export const SIDE_GROUP = -2;
|
||||
export type SIDE_GROUP_TYPE = typeof SIDE_GROUP;
|
||||
|
||||
export interface ISaveEditorsOptions extends ISaveOptions {
|
||||
|
||||
/**
|
||||
* If true, will ask for a location of the editor to save to.
|
||||
*/
|
||||
readonly saveAs?: boolean;
|
||||
}
|
||||
|
||||
export interface IBaseSaveRevertAllEditorOptions {
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,7 +43,7 @@ suite('EditorOverrideService', () => {
|
|||
({ resource, options }, group) => ({ editor: new TestFileEditorInput(URI.parse(resource.toString()), TEST_EDITOR_INPUT_ID) }),
|
||||
);
|
||||
|
||||
const resultingOverride = await service.resolveEditorInput({ resource: URI.file('my://resource-basics.test') }, part.activeGroup);
|
||||
const resultingOverride = await service.resolveEditor({ resource: URI.file('my://resource-basics.test') }, part.activeGroup);
|
||||
assert.ok(resultingOverride);
|
||||
assert.notStrictEqual(typeof resultingOverride, 'number');
|
||||
if (resultingOverride !== OverrideStatus.ABORT && resultingOverride !== OverrideStatus.NONE) {
|
||||
|
@ -69,13 +69,13 @@ suite('EditorOverrideService', () => {
|
|||
);
|
||||
|
||||
// Untyped untitled - no resource
|
||||
let resultingOverride = await service.resolveEditorInput({ resource: undefined }, part.activeGroup);
|
||||
let resultingOverride = await service.resolveEditor({ resource: undefined }, part.activeGroup);
|
||||
assert.ok(resultingOverride);
|
||||
// We don't expect untitled to match the *.test glob
|
||||
assert.strictEqual(typeof resultingOverride, 'number');
|
||||
|
||||
// Untyped untitled - with untitled resource
|
||||
resultingOverride = await service.resolveEditorInput({ resource: URI.from({ scheme: Schemas.untitled, path: 'foo.test' }) }, part.activeGroup);
|
||||
resultingOverride = await service.resolveEditor({ resource: URI.from({ scheme: Schemas.untitled, path: 'foo.test' }) }, part.activeGroup);
|
||||
assert.ok(resultingOverride);
|
||||
assert.notStrictEqual(typeof resultingOverride, 'number');
|
||||
if (resultingOverride !== OverrideStatus.ABORT && resultingOverride !== OverrideStatus.NONE) {
|
||||
|
@ -84,7 +84,7 @@ suite('EditorOverrideService', () => {
|
|||
}
|
||||
|
||||
// Untyped untitled - file resource with forceUntitled
|
||||
resultingOverride = await service.resolveEditorInput({ resource: URI.file('/fake.test'), forceUntitled: true }, part.activeGroup);
|
||||
resultingOverride = await service.resolveEditor({ resource: URI.file('/fake.test'), forceUntitled: true }, part.activeGroup);
|
||||
assert.ok(resultingOverride);
|
||||
assert.notStrictEqual(typeof resultingOverride, 'number');
|
||||
if (resultingOverride !== OverrideStatus.ABORT && resultingOverride !== OverrideStatus.NONE) {
|
||||
|
|
|
@ -7,13 +7,13 @@ import * as assert from 'assert';
|
|||
import { EditorActivation, EditorOverride, IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { DEFAULT_EDITOR_ASSOCIATION, EditorsOrder, GroupIdentifier, IEditorInputWithOptions, IEditorPane, IResourceDiffEditorInput, isEditorInputWithOptions, isResourceDiffEditorInput, isUntitledResourceEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput, UntypedEditorContext } from 'vs/workbench/common/editor';
|
||||
import { DEFAULT_EDITOR_ASSOCIATION, EditorsOrder, IEditorInputWithOptions, IEditorPane, IResourceDiffEditorInput, isEditorInputWithOptions, isResourceDiffEditorInput, isUntitledResourceEditorInput, IUntitledTextResourceEditorInput, IUntypedEditorInput, UntypedEditorContext } from 'vs/workbench/common/editor';
|
||||
import { workbenchInstantiationService, TestServiceAccessor, registerTestEditor, TestFileEditorInput, ITestInstantiationService, registerTestResourceEditor, registerTestSideBySideEditor, createEditorPart, registerTestFileEditor, TestEditorWithOptions, TestTextFileEditor } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { TextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput';
|
||||
import { EditorService } from 'vs/workbench/services/editor/browser/editorService';
|
||||
import { IEditorGroup, IEditorGroupsService, GroupDirection, GroupsArrangement } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart';
|
||||
import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorService, PreferredGroup, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/fileEditorInput';
|
||||
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
|
||||
|
@ -245,7 +245,7 @@ suite('EditorService', () => {
|
|||
rootGroup = part.activeGroup;
|
||||
}
|
||||
|
||||
async function openEditor(editor: IEditorInputWithOptions | IUntypedEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined> {
|
||||
async function openEditor(editor: IEditorInputWithOptions | IUntypedEditorInput, group?: PreferredGroup): Promise<IEditorPane | undefined> {
|
||||
if (useOpenEditors) {
|
||||
const panes = await service.openEditors([editor], group);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EditorResourceAccessor, SideBySideEditor, IEditorInputWithPreferredResource, EditorInputCapabilities, isEditorIdentifier, IResourceDiffEditorInput, IUntitledTextResourceEditorInput, isResourceEditorInput, isUntitledResourceEditorInput, isResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { EditorResourceAccessor, SideBySideEditor, IEditorInputWithPreferredResource, EditorInputCapabilities, isEditorIdentifier, IResourceDiffEditorInput, IUntitledTextResourceEditorInput, isResourceEditorInput, isUntitledResourceEditorInput, isResourceDiffEditorInput, isEditorInputWithOptionsAndGroup, IEditorInputWithOptions, isEditorInputWithOptions, isEditorInput, IEditorInputWithOptionsAndGroup } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -331,6 +331,24 @@ suite('Workbench editor utils', () => {
|
|||
assert.strictEqual(isEditorIdentifier({ editor: testInput1, groupId: 3 }), true);
|
||||
});
|
||||
|
||||
test('isEditorInputWithOptionsAndGroup', () => {
|
||||
const editorInput = new TestFileEditorInput(URI.file('resource1'), 'testTypeId');
|
||||
assert.strictEqual(isEditorInput(editorInput), true);
|
||||
assert.strictEqual(isEditorInputWithOptions(editorInput), false);
|
||||
assert.strictEqual(isEditorInputWithOptionsAndGroup(editorInput), false);
|
||||
|
||||
const editorInputWithOptions: IEditorInputWithOptions = { editor: editorInput, options: { override: EditorOverride.PICK } };
|
||||
assert.strictEqual(isEditorInput(editorInputWithOptions), false);
|
||||
assert.strictEqual(isEditorInputWithOptions(editorInputWithOptions), true);
|
||||
assert.strictEqual(isEditorInputWithOptionsAndGroup(editorInputWithOptions), false);
|
||||
|
||||
const service = accessor.editorGroupService;
|
||||
const editorInputWithOptionsAndGroup: IEditorInputWithOptionsAndGroup = { editor: editorInput, options: { override: EditorOverride.PICK }, group: service.activeGroup };
|
||||
assert.strictEqual(isEditorInput(editorInputWithOptionsAndGroup), false);
|
||||
assert.strictEqual(isEditorInputWithOptions(editorInputWithOptionsAndGroup), true);
|
||||
assert.strictEqual(isEditorInputWithOptionsAndGroup(editorInputWithOptionsAndGroup), true);
|
||||
});
|
||||
|
||||
test('whenEditorClosed (single editor)', async function () {
|
||||
return testWhenEditorClosed(false, false, toResource.call(this, '/path/index.txt'));
|
||||
});
|
||||
|
|
|
@ -52,7 +52,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
|||
import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/browser/decorations';
|
||||
import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IEditorReplacement, IGroupChangeEvent, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, SIDE_GROUP_TYPE, ACTIVE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, PreferredGroup } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { IEditorRegistry, EditorDescriptor } from 'vs/workbench/browser/editor';
|
||||
import { Dimension, IDimension } from 'vs/base/browser/dom';
|
||||
|
@ -813,10 +813,10 @@ export class TestEditorService implements EditorServiceImpl {
|
|||
constructor(private editorGroupService?: IEditorGroupsService) { }
|
||||
getEditors() { return []; }
|
||||
findEditors() { return [] as any; }
|
||||
openEditor(editor: IEditorInput, options?: IEditorOptions, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IResourceEditorInput | IUntitledTextResourceEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<ITextEditorPane | undefined>;
|
||||
openEditor(editor: IResourceDiffEditorInput, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<ITextDiffEditorPane | undefined>;
|
||||
async openEditor(editor: IEditorInput | IUntypedEditorInput, optionsOrGroup?: IEditorOptions | IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditorPane | undefined> {
|
||||
openEditor(editor: IEditorInput, options?: IEditorOptions, group?: PreferredGroup): Promise<IEditorPane | undefined>;
|
||||
openEditor(editor: IResourceEditorInput | IUntitledTextResourceEditorInput, group?: PreferredGroup): Promise<ITextEditorPane | undefined>;
|
||||
openEditor(editor: IResourceDiffEditorInput, group?: PreferredGroup): Promise<ITextDiffEditorPane | undefined>;
|
||||
async openEditor(editor: IEditorInput | IUntypedEditorInput, optionsOrGroup?: IEditorOptions | PreferredGroup, group?: PreferredGroup): Promise<IEditorPane | undefined> {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
doResolveEditorOpenRequest(editor: IEditorInput | IUntypedEditorInput): [IEditorGroup, EditorInput, IEditorOptions | undefined] | undefined {
|
||||
|
|
Loading…
Reference in a new issue