diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index 7e09d9d1bbf01..df98d5b76fc5b 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -15,7 +15,6 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { EditorActivation, ITextEditorOptions } from 'vs/platform/editor/common/editor'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { viewColumnToEditorGroup } from 'vs/workbench/common/editor'; @@ -27,7 +26,6 @@ import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType, DisplayOrderKey, ICell import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService'; import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService'; import { IEditorGroup, IEditorGroupsService, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity'; import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, INotebookCellStatusBarEntryDto, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookModelAddedData, MainContext, MainThreadNotebookShape, NotebookEditorRevealType, NotebookExtensionDescription } from '../common/extHost.protocol'; @@ -130,8 +128,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo @ILogService private readonly logService: ILogService, @INotebookCellStatusBarService private readonly cellStatusBarService: INotebookCellStatusBarService, @INotebookEditorModelResolverService private readonly _notebookModelResolverService: INotebookEditorModelResolverService, - @IUriIdentityService private readonly _uriIdentityService: IUriIdentityService, - @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IUriIdentityService private readonly _uriIdentityService: IUriIdentityService ) { super(); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebook); @@ -680,7 +677,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo const input = this.editorService.createEditorInput({ resource: URI.revive(resource), options: editorOptions }); // TODO: handle options.selection - const editorPane = await this._instantiationService.invokeFunction(openEditorWith, input, viewType, options, group); + const editorPane = await group.openEditorWith(input, viewType, options); const notebookEditor = (editorPane as unknown as { isNotebookEditor?: boolean })?.isNotebookEditor ? (editorPane!.getControl() as INotebookEditor) : undefined; if (notebookEditor) { diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index db48f41714888..0bd1d70bfe8c2 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -5,7 +5,7 @@ import * as nls from 'vs/nls'; import { Action } from 'vs/base/common/actions'; -import { IEditorInput, IEditorIdentifier, IEditorCommandsContext, CloseDirection, SaveReason, EditorsOrder, SideBySideEditorInput } from 'vs/workbench/common/editor'; +import { IEditorInput, IEditorIdentifier, IEditorCommandsContext, CloseDirection, SaveReason, EditorsOrder, SideBySideEditorInput, getAllAvailableEditors } from 'vs/workbench/common/editor'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -22,8 +22,6 @@ import { ItemActivation, IQuickInputService } from 'vs/platform/quickinput/commo import { AllEditorsByMostRecentlyUsedQuickAccess, ActiveGroupEditorsByMostRecentlyUsedQuickAccess, AllEditorsByAppearanceQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess'; import { Codicon } from 'vs/base/common/codicons'; import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; -import { openEditorWith, getAllAvailableEditors } from 'vs/workbench/services/editor/common/editorOpenWith'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class ExecuteCommandAction extends Action { @@ -1894,8 +1892,7 @@ export class ReopenResourcesAction extends Action { constructor( id: string, label: string, - @IEditorService private readonly editorService: IEditorService, - @IInstantiationService private readonly instantiationService: IInstantiationService, + @IEditorService private readonly editorService: IEditorService ) { super(id, label); } @@ -1913,7 +1910,7 @@ export class ReopenResourcesAction extends Action { const options = activeEditorPane.options; const group = activeEditorPane.group; - await this.instantiationService.invokeFunction(openEditorWith, activeInput, undefined, options, group); + await group.openEditorWith(activeInput, undefined, options); } } diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index f9fd2d5716473..478db3cc000b8 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -25,7 +25,6 @@ import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { ActiveGroupEditorsByMostRecentlyUsedQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; -import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith'; export const CLOSE_SAVED_EDITORS_COMMAND_ID = 'workbench.action.closeUnmodifiedEditors'; export const CLOSE_EDITORS_IN_GROUP_COMMAND_ID = 'workbench.action.closeEditorsInGroup'; @@ -502,7 +501,7 @@ function registerOpenEditorAPICommands(): void { const textOptions: ITextEditorOptions = optionsArg ? { ...optionsArg, override: false } : { override: false }; const input = editorService.createEditorInput({ resource: URI.revive(resource) }); - return openEditorWith(accessor, input, id, textOptions, group); + return group.openEditorWith(input, id, textOptions); }); } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 1ad4ee402dc47..c419bab4c9b2d 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -5,7 +5,7 @@ import 'vs/css!./media/editorgroupview'; import { EditorGroup, IEditorOpenOptions, EditorCloseEvent, ISerializedEditorGroup, isSerializedEditorGroup } from 'vs/workbench/common/editor/editorGroup'; -import { EditorInput, EditorOptions, GroupIdentifier, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, ActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, ActiveEditorStickyContext, ActiveEditorPinnedContext, EditorResourceAccessor } from 'vs/workbench/common/editor'; +import { EditorInput, EditorOptions, GroupIdentifier, SideBySideEditorInput, CloseDirection, IEditorCloseEvent, ActiveEditorDirtyContext, IEditorPane, EditorGroupEditorsCountContext, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, ActiveEditorStickyContext, ActiveEditorPinnedContext, EditorResourceAccessor, IEditorInput, getTargetGroup, CustomEditorAssociation, CustomEditorsAssociations, customEditorsAssociationsSettingId, getAllAvailableEditors } from 'vs/workbench/common/editor'; import { Event, Emitter, Relay } from 'vs/base/common/event'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { Dimension, trackFocus, addDisposableListener, EventType, EventHelper, findParentWithClass, clearNode, isAncestor, asCSSUrl } from 'vs/base/browser/dom'; @@ -16,7 +16,7 @@ import { attachProgressBarStyler } from 'vs/platform/theme/common/styler'; import { IThemeService, registerThemingParticipant, Themable } from 'vs/platform/theme/common/themeService'; import { editorBackground, contrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { EDITOR_GROUP_HEADER_TABS_BACKGROUND, EDITOR_GROUP_HEADER_NO_TABS_BACKGROUND, EDITOR_GROUP_EMPTY_BACKGROUND, EDITOR_GROUP_FOCUSED_EMPTY_BORDER, EDITOR_GROUP_HEADER_BORDER } from 'vs/workbench/common/theme'; -import { IMoveEditorOptions, ICopyEditorOptions, ICloseEditorsFilter, IGroupChangeEvent, GroupChangeKind, GroupsOrder, ICloseEditorOptions, ICloseAllEditorsOptions, OpenEditorContext } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IMoveEditorOptions, ICopyEditorOptions, ICloseEditorsFilter, IGroupChangeEvent, GroupChangeKind, GroupsOrder, ICloseEditorOptions, ICloseAllEditorsOptions, OpenEditorContext, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { TabsTitleControl } from 'vs/workbench/browser/parts/editor/tabsTitleControl'; import { EditorControl } from 'vs/workbench/browser/parts/editor/editorControl'; import { IEditorProgressService } from 'vs/platform/progress/common/progress'; @@ -40,17 +40,19 @@ import { IMenuService, MenuId, IMenu } from 'vs/platform/actions/common/actions' import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IEditorService, IOpenEditorOverrideHandler } from 'vs/workbench/services/editor/common/editorService'; import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; import { hash } from 'vs/base/common/hash'; import { guessMimeTypes } from 'vs/base/common/mime'; -import { extname } from 'vs/base/common/resources'; +import { basename, extname } from 'vs/base/common/resources'; import { FileAccess, Schemas } from 'vs/base/common/network'; -import { EditorActivation, EditorOpenContext } from 'vs/platform/editor/common/editor'; +import { EditorActivation, EditorOpenContext, IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { IDialogService, IFileDialogService, ConfirmResult } from 'vs/platform/dialogs/common/dialogs'; import { ILogService } from 'vs/platform/log/common/log'; import { Codicon } from 'vs/base/common/codicons'; import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IQuickPickItem, IKeyMods, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class EditorGroupView extends Themable implements IEditorGroupView { @@ -138,7 +140,10 @@ export class EditorGroupView extends Themable implements IEditorGroupView { @IFileDialogService private readonly fileDialogService: IFileDialogService, @ILogService private readonly logService: ILogService, @IEditorService private readonly editorService: EditorServiceImpl, - @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService, + @IConfigurationService private readonly configurationService: IConfigurationService, + @IQuickInputService private readonly quickInputService: IQuickInputService, + @IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService ) { super(themeService); @@ -894,6 +899,147 @@ export class EditorGroupView extends Themable implements IEditorGroupView { return withUndefinedAsNull(await this.doOpenEditor(editor, options)); } + /** + * Try to open an resource with a given editor. + * + * @param input Resource to open. + * @param id Id of the editor to use. If not provided, the user is prompted for which editor to use. + */ + async openEditorWith( + input: IEditorInput, + id: string | undefined, + options: IEditorOptions | ITextEditorOptions | undefined, + ): Promise { + + const resource = input.resource; + if (!resource) { + return; + } + + const overrideOptions = { ...options, override: id }; + + const allEditorOverrides = getAllAvailableEditors(resource, id, overrideOptions, this, this.editorService); + if (!allEditorOverrides.length) { + return; + } + + let overrideToUse; + if (typeof id === 'string') { + overrideToUse = allEditorOverrides.find(([_, entry]) => entry.id === id); + } else if (allEditorOverrides.length === 1) { + overrideToUse = allEditorOverrides[0]; + } + if (overrideToUse) { + return overrideToUse[0].open(input, overrideOptions, this, OpenEditorContext.NEW_EDITOR)?.override; + } + + // Prompt + const originalResource = EditorResourceAccessor.getOriginalUri(input) || resource; + const resourceExt = extname(originalResource); + + const items: (IQuickPickItem & { handler: IOpenEditorOverrideHandler })[] = allEditorOverrides.map(([handler, entry]) => { + return { + handler: handler, + id: entry.id, + label: entry.label, + description: entry.active ? localize('promptOpenWith.currentlyActive', 'Currently Active') : undefined, + detail: entry.detail, + buttons: resourceExt ? [{ + iconClass: Codicon.gear.classNames, + tooltip: localize('promptOpenWith.setDefaultTooltip', "Set as default editor for '{0}' files", resourceExt) + }] : undefined + }; + }); + type QuickPickItem = IQuickPickItem & { + readonly handler: IOpenEditorOverrideHandler; + }; + + const picker = this.quickInputService.createQuickPick(); + picker.items = items; + if (items.length) { + picker.selectedItems = [items[0]]; + } + picker.placeholder = localize('promptOpenWith.placeHolder', "Select editor for '{0}'", basename(originalResource)); + picker.canAcceptInBackground = true; + + type PickedResult = { + readonly item: QuickPickItem; + readonly keyMods?: IKeyMods; + readonly openInBackground: boolean; + }; + + const openEditor = (picked: PickedResult) => { + const targetGroup = getTargetGroup(this, picked.keyMods, this.configurationService, this.editorGroupsService); + + const openOptions: IEditorOptions = { + ...options, + override: picked.item.id, + preserveFocus: picked.openInBackground || options?.preserveFocus, + }; + return picked.item.handler.open(input, openOptions, targetGroup, OpenEditorContext.NEW_EDITOR)?.override; + }; + + let picked: PickedResult | undefined; + try { + picked = await new Promise(resolve => { + picker.onDidAccept(e => { + if (picker.selectedItems.length === 1) { + const result: PickedResult = { + item: picker.selectedItems[0], + keyMods: picker.keyMods, + openInBackground: e.inBackground + }; + + if (e.inBackground) { + openEditor(result); + } else { + resolve(result); + } + } else { + resolve(undefined); + } + }); + + picker.onDidTriggerItemButton(e => { + const pick = e.item; + const id = pick.id; + resolve({ item: pick, openInBackground: false }); // open the view + picker.dispose(); + + // And persist the setting + if (pick && id) { + const newAssociation: CustomEditorAssociation = { viewType: id, filenamePattern: '*' + resourceExt }; + const currentAssociations = [...this.configurationService.getValue(customEditorsAssociationsSettingId)]; + + // First try updating existing association + for (let i = 0; i < currentAssociations.length; ++i) { + const existing = currentAssociations[i]; + if (existing.filenamePattern === newAssociation.filenamePattern) { + currentAssociations.splice(i, 1, newAssociation); + this.configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations); + return; + } + } + + // Otherwise, create a new one + currentAssociations.unshift(newAssociation); + this.configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations); + } + }); + + picker.show(); + }); + } finally { + picker.dispose(); + } + + if (!picked) { + return undefined; + } + + return openEditor(picked); + } + private async doOpenEditor(editor: EditorInput, options?: EditorOptions): Promise { // Guard against invalid inputs. Disposed inputs diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 5471bd95d6f92..8ef8605a1b366 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -14,15 +14,20 @@ import { IInstantiationService, IConstructorSignature0, ServicesAccessor, Brande import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Registry } from 'vs/platform/registry/common/platform'; import { ITextModel } from 'vs/editor/common/model'; -import { GroupsOrder, IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { GroupsOrder, IEditorGroup, IEditorGroupsService, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService'; import { ICompositeControl, IComposite } from 'vs/workbench/common/composite'; import { ActionRunner, IAction } from 'vs/base/common/actions'; import { IFileService } from 'vs/platform/files/common/files'; import { IPathData } from 'vs/platform/windows/common/windows'; import { coalesce, firstOrDefault } from 'vs/base/common/arrays'; -import { ACTIVE_GROUP, IResourceEditorInputType, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; +import { ACTIVE_GROUP, ICustomEditorInfo, IEditorService, IOpenEditorOverrideEntry, IOpenEditorOverrideHandler, IResourceEditorInputType, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IRange } from 'vs/editor/common/core/range'; -import { IExtUri } from 'vs/base/common/resources'; +import { IExtUri, isEqual } from 'vs/base/common/resources'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IKeyMods } from 'vs/platform/quickinput/common/quickInput'; +import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; +import { Extensions as ConfigurationExtensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; // Editor State Context Keys export const ActiveEditorDirtyContext = new RawContextKey('activeEditorIsDirty', false); @@ -1549,9 +1554,9 @@ export async function pathsToEditors(paths: IPathData[] | undefined, fileService pinned: true, override: path.overrideId } : { - pinned: true, - override: path.overrideId - }; + pinned: true, + override: path.overrideId + }; let input: IResourceEditorInput | IUntitledTextResourceEditorInput; if (!exists) { @@ -1637,3 +1642,147 @@ export function editorGroupToViewColumn(editorGroupService: IEditorGroupsService } //#endregion + +////#region editorOpenWith + +/** + * Get the group to open the editor in by looking at the pressed keys from the picker. + */ +export function getTargetGroup( + startingGroup: IEditorGroup, + keyMods: IKeyMods | undefined, + configurationService: IConfigurationService, + editorGroupsService: IEditorGroupsService, +) { + if (keyMods?.alt || keyMods?.ctrlCmd) { + const direction = preferredSideBySideGroupDirection(configurationService); + const targetGroup = editorGroupsService.findGroup({ direction }, startingGroup.id); + return targetGroup ?? editorGroupsService.addGroup(startingGroup, direction); + } + return startingGroup; +} + +/** + * Id of the default editor for open with. + */ +export const DEFAULT_EDITOR_ID = 'default'; + +const builtinProviderDisplayName = localize('builtinProviderDisplayName', "Built-in"); + +export const defaultEditorOverrideEntry = Object.freeze({ + id: DEFAULT_EDITOR_ID, + label: localize('promptOpenWith.defaultEditor.displayName', "Text Editor"), + detail: builtinProviderDisplayName +}); + +/** + * Get a list of all available editors, including the default text editor. + */ +export function getAllAvailableEditors( + resource: URI, + id: string | undefined, + options: IEditorOptions | ITextEditorOptions | undefined, + group: IEditorGroup, + editorService: IEditorService +): Array<[IOpenEditorOverrideHandler, IOpenEditorOverrideEntry]> { + const fileEditorInputFactory = Registry.as(Extensions.EditorInputFactories).getFileEditorInputFactory(); + const overrides = editorService.getEditorOverrides(resource, options, group); + if (!overrides.some(([_, entry]) => entry.id === DEFAULT_EDITOR_ID)) { + overrides.unshift([ + { + open: (input: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup) => { + const resource = EditorResourceAccessor.getOriginalUri(input); + if (!resource) { + return; + } + + const fileEditorInput = editorService.createEditorInput({ resource, forceFile: true }); + const textOptions: IEditorOptions | ITextEditorOptions = options ? { ...options, override: false } : { override: false }; + return { + override: (async () => { + // Try to replace existing editors for resource + const existingEditor = firstOrDefault(editorService.findEditors(resource, group)); + if (existingEditor && !fileEditorInput.matches(existingEditor)) { + await editorService.replaceEditors([{ + editor: existingEditor, + replacement: fileEditorInput, + options: options ? EditorOptions.create(options) : undefined, + }], group); + } + + return editorService.openEditor(fileEditorInput, textOptions, group); + })() + }; + } + }, + { + ...defaultEditorOverrideEntry, + active: fileEditorInputFactory.isFileEditorInput(editorService.activeEditor) && isEqual(editorService.activeEditor.resource, resource), + }]); + } + + return overrides; +} + +export const customEditorsAssociationsSettingId = 'workbench.editorAssociations'; + +export const viewTypeSchemaAddition: IJSONSchema = { + type: 'string', + enum: [] +}; + +export type CustomEditorAssociation = { + readonly viewType: string; + readonly filenamePattern?: string; +}; + +export type CustomEditorsAssociations = readonly CustomEditorAssociation[]; + +export const editorAssociationsConfigurationNode: IConfigurationNode = { + ...workbenchConfigurationNodeBase, + properties: { + [customEditorsAssociationsSettingId]: { + type: 'array', + markdownDescription: localize('editor.editorAssociations', "Configure which editor to use for specific file types."), + items: { + type: 'object', + defaultSnippets: [{ + body: { + 'viewType': '$1', + 'filenamePattern': '$2' + } + }], + properties: { + 'viewType': { + anyOf: [ + { + type: 'string', + description: localize('editor.editorAssociations.viewType', "The unique id of the editor to use."), + }, + viewTypeSchemaAddition + ] + }, + 'filenamePattern': { + type: 'string', + description: localize('editor.editorAssociations.filenamePattern', "Glob pattern specifying which files the editor should be used for."), + } + } + } + } + } +}; + +export const DEFAULT_CUSTOM_EDITOR: ICustomEditorInfo = { + id: 'default', + displayName: localize('promptOpenWith.defaultEditor.displayName', "Text Editor"), + providerDisplayName: builtinProviderDisplayName +}; + +export function updateViewTypeSchema(enumValues: string[], enumDescriptions: string[]): void { + viewTypeSchemaAddition.enum = enumValues; + viewTypeSchemaAddition.enumDescriptions = enumDescriptions; + + Registry.as(ConfigurationExtensions.Configuration) + .notifyConfigurationSchemaUpdated(editorAssociationsConfigurationNode); +} +////#endregion diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditors.ts b/src/vs/workbench/contrib/customEditor/browser/customEditors.ts index 66de7e83c0c35..40f8ab9e70e2d 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditors.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditors.ts @@ -24,13 +24,12 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import * as colorRegistry from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { EditorInput, EditorOptions, Extensions as EditorInputExtensions, GroupIdentifier, IEditorInput, IEditorInputFactoryRegistry, IEditorPane } from 'vs/workbench/common/editor'; +import { CustomEditorAssociation, CustomEditorsAssociations, customEditorsAssociationsSettingId, EditorInput, EditorOptions, Extensions as EditorInputExtensions, GroupIdentifier, IEditorInput, IEditorInputFactoryRegistry, IEditorPane } from 'vs/workbench/common/editor'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { CONTEXT_CUSTOM_EDITORS, CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE, CustomEditorCapabilities, CustomEditorInfo, CustomEditorInfoCollection, CustomEditorPriority, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { CustomEditorModelManager } from 'vs/workbench/contrib/customEditor/common/customEditorModelManager'; import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { CustomEditorAssociation, CustomEditorsAssociations, customEditorsAssociationsSettingId } from 'vs/workbench/services/editor/common/editorOpenWith'; import { ICustomEditorInfo, ICustomEditorViewTypesHandler, IEditorService, IOpenEditorOverride, IOpenEditorOverrideEntry } from 'vs/workbench/services/editor/common/editorService'; import { ContributedCustomEditors, defaultCustomEditor } from '../common/contributedCustomEditors'; import { CustomEditorInput } from './customEditorInput'; diff --git a/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts b/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts index 98fcdb9b97474..82cff6cac7ee1 100644 --- a/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts +++ b/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.ts @@ -9,10 +9,10 @@ import { URI } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { DEFAULT_EDITOR_ID } from 'vs/workbench/common/editor'; import { Memento } from 'vs/workbench/common/memento'; import { CustomEditorDescriptor, CustomEditorInfo, CustomEditorPriority } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { customEditorsExtensionPoint, ICustomEditorsExtensionPoint } from 'vs/workbench/contrib/customEditor/common/extensionPoint'; -import { DEFAULT_EDITOR_ID } from 'vs/workbench/services/editor/common/editorOpenWith'; import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; const builtinProviderDisplayName = nls.localize('builtinProviderDisplayName', "Built-in"); diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index 1cc203a01e339..6b3b4a9383f7c 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -13,8 +13,6 @@ import { BINARY_FILE_EDITOR_ID } from 'vs/workbench/contrib/files/common/files'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; /** * An implementation of editor for binary files that cannot be displayed. @@ -27,7 +25,6 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { @ITelemetryService telemetryService: ITelemetryService, @IThemeService themeService: IThemeService, @IOpenerService private readonly openerService: IOpenerService, - @IInstantiationService private readonly instantiationService: IInstantiationService, @IStorageService storageService: IStorageService, @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, ) { @@ -51,7 +48,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { input.setForceOpenAsText(); // If more editors are installed that can handle this input, show a picker - await this.instantiationService.invokeFunction(openEditorWith, input, undefined, options, this.group); + await this.group.openEditorWith(input, undefined, options); } } diff --git a/src/vs/workbench/contrib/files/browser/fileCommands.ts b/src/vs/workbench/contrib/files/browser/fileCommands.ts index d33543aaf0f5e..b2122db4283ba 100644 --- a/src/vs/workbench/contrib/files/browser/fileCommands.ts +++ b/src/vs/workbench/contrib/files/browser/fileCommands.ts @@ -41,7 +41,6 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity'; -import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { toAction } from 'vs/base/common/actions'; @@ -359,7 +358,7 @@ CommandsRegistry.registerCommand({ const uri = getResourceForCommand(resource, accessor.get(IListService), accessor.get(IEditorService)); if (uri) { const input = editorService.createEditorInput({ resource: uri }); - openEditorWith(accessor, input, undefined, undefined, editorGroupsService.activeGroup); + editorGroupsService.activeGroup.openEditorWith(input, undefined, undefined); } } }); @@ -679,8 +678,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ const editorGroupsService = accessor.get(IEditorGroupsService); const textInput = editorService.createEditorInput({ options: { pinned: true } }); - const group = editorGroupsService.activeGroup; - await openEditorWith(accessor, textInput, args.viewType, { pinned: true }, group); + await editorGroupsService.activeGroup.openEditorWith(textInput, args.viewType, { pinned: true }); } else { await editorService.openEditor({ options: { pinned: true } }); // untitled are always pinned } diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index a5d6464c50c32..cc58e8c3e2619 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -24,7 +24,7 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle import { Registry } from 'vs/platform/registry/common/platform'; import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } from 'vs/workbench/browser/editor'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { EditorInput, Extensions as EditorInputExtensions, ICustomEditorInputFactory, IEditorInput, IEditorInputFactory, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; +import { CustomEditorsAssociations, customEditorsAssociationsSettingId, EditorInput, Extensions as EditorInputExtensions, ICustomEditorInputFactory, IEditorInput, IEditorInputFactory, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEditor'; import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput'; @@ -34,7 +34,6 @@ import { CellKind, CellToolbarLocKey, CellUri, DisplayOrderKey, getCellUndoRedoC import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, IOpenEditorOverride } from 'vs/workbench/services/editor/common/editorService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { CustomEditorsAssociations, customEditorsAssociationsSettingId } from 'vs/workbench/services/editor/common/editorOpenWith'; import { CustomEditorInfo } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { INotebookEditor, IN_NOTEBOOK_TEXT_DIFF_EDITOR, NotebookEditorOptions, NOTEBOOK_EDITOR_OPEN } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; diff --git a/src/vs/workbench/services/editor/browser/editorService.ts b/src/vs/workbench/services/editor/browser/editorService.ts index b99e476e2df03..5b1873f9cf6ca 100644 --- a/src/vs/workbench/services/editor/browser/editorService.ts +++ b/src/vs/workbench/services/editor/browser/editorService.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IResourceEditorInput, ITextEditorOptions, IEditorOptions, EditorActivation } from 'vs/platform/editor/common/editor'; -import { SideBySideEditor, IEditorInput, IEditorPane, GroupIdentifier, IFileEditorInput, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputFactoryRegistry, Extensions as EditorExtensions, EditorInput, SideBySideEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, EditorOptions, TextEditorOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditorPane, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, isTextEditorPane, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane } from 'vs/workbench/common/editor'; +import { SideBySideEditor, IEditorInput, IEditorPane, GroupIdentifier, IFileEditorInput, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorInputFactoryRegistry, Extensions as EditorExtensions, EditorInput, SideBySideEditorInput, IEditorInputWithOptions, isEditorInputWithOptions, EditorOptions, TextEditorOptions, IEditorIdentifier, IEditorCloseEvent, ITextEditorPane, ITextDiffEditorPane, IRevertOptions, SaveReason, EditorsOrder, isTextEditorPane, IWorkbenchEditorConfiguration, EditorResourceAccessor, IVisibleEditorPane, updateViewTypeSchema, DEFAULT_CUSTOM_EDITOR, editorAssociationsConfigurationNode } from 'vs/workbench/common/editor'; import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; import { Registry } from 'vs/platform/registry/common/platform'; import { ResourceMap } from 'vs/base/common/map'; @@ -33,7 +33,6 @@ import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/u import { Promises, timeout } from 'vs/base/common/async'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { indexOfPath } from 'vs/base/common/extpath'; -import { DEFAULT_CUSTOM_EDITOR, updateViewTypeSchema, editorAssociationsConfigurationNode } from 'vs/workbench/services/editor/common/editorOpenWith'; import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity'; diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index c54ec57ee84df..1f0c40e8c3f6a 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -472,6 +472,14 @@ export interface IEditorGroup { */ openEditor(editor: IEditorInput, options?: IEditorOptions | ITextEditorOptions, context?: OpenEditorContext): Promise; + /** + * Open an editor with a given ID, if none is passed in we prompt the user to select it based on available overrides + * + * @returns a promise that resolves around an IEditor instance unless + * the call failed, or the editor was not opened + */ + openEditorWith(editor: IEditorInput, id: string | undefined, options: IEditorOptions | ITextEditorOptions | undefined): Promise; + /** * Opens editors in this group. * diff --git a/src/vs/workbench/services/editor/common/editorOpenWith.ts b/src/vs/workbench/services/editor/common/editorOpenWith.ts deleted file mode 100644 index 7dc8cdfa3663e..0000000000000 --- a/src/vs/workbench/services/editor/common/editorOpenWith.ts +++ /dev/null @@ -1,309 +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 * as nls from 'vs/nls'; -import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { IConfigurationNode, IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry'; -import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { ICustomEditorInfo, IEditorService, IOpenEditorOverrideHandler, IOpenEditorOverrideEntry } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorInput, IEditorPane, IEditorInputFactoryRegistry, Extensions as EditorExtensions, EditorResourceAccessor, EditorOptions } from 'vs/workbench/common/editor'; -import { ITextEditorOptions, IEditorOptions } from 'vs/platform/editor/common/editor'; -import { IEditorGroup, IEditorGroupsService, OpenEditorContext, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IKeyMods, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { URI } from 'vs/base/common/uri'; -import { extname, basename, isEqual } from 'vs/base/common/resources'; -import { Codicon } from 'vs/base/common/codicons'; -import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { firstOrDefault } from 'vs/base/common/arrays'; - -/** - * Id of the default editor for open with. - */ -export const DEFAULT_EDITOR_ID = 'default'; - -/** - * Try to open an resource with a given editor. - * - * @param input Resource to open. - * @param id Id of the editor to use. If not provided, the user is prompted for which editor to use. - */ -export async function openEditorWith( - accessor: ServicesAccessor, - input: IEditorInput, - id: string | undefined, - options: IEditorOptions | ITextEditorOptions | undefined, - group: IEditorGroup, -): Promise { - const editorService = accessor.get(IEditorService); - const editorGroupsService = accessor.get(IEditorGroupsService); - const configurationService = accessor.get(IConfigurationService); - const quickInputService = accessor.get(IQuickInputService); - - const resource = input.resource; - if (!resource) { - return; - } - - const overrideOptions = { ...options, override: id }; - - const allEditorOverrides = getAllAvailableEditors(resource, id, overrideOptions, group, editorService); - if (!allEditorOverrides.length) { - return; - } - - let overrideToUse; - if (typeof id === 'string') { - overrideToUse = allEditorOverrides.find(([_, entry]) => entry.id === id); - } else if (allEditorOverrides.length === 1) { - overrideToUse = allEditorOverrides[0]; - } - if (overrideToUse) { - return overrideToUse[0].open(input, overrideOptions, group, OpenEditorContext.NEW_EDITOR)?.override; - } - - // Prompt - const originalResource = EditorResourceAccessor.getOriginalUri(input) || resource; - const resourceExt = extname(originalResource); - - const items: (IQuickPickItem & { handler: IOpenEditorOverrideHandler })[] = allEditorOverrides.map(([handler, entry]) => { - return { - handler: handler, - id: entry.id, - label: entry.label, - description: entry.active ? nls.localize('promptOpenWith.currentlyActive', 'Currently Active') : undefined, - detail: entry.detail, - buttons: resourceExt ? [{ - iconClass: Codicon.gear.classNames, - tooltip: nls.localize('promptOpenWith.setDefaultTooltip', "Set as default editor for '{0}' files", resourceExt) - }] : undefined - }; - }); - type QuickPickItem = IQuickPickItem & { - readonly handler: IOpenEditorOverrideHandler; - }; - - const picker = quickInputService.createQuickPick(); - picker.items = items; - if (items.length) { - picker.selectedItems = [items[0]]; - } - picker.placeholder = nls.localize('promptOpenWith.placeHolder', "Select editor for '{0}'", basename(originalResource)); - picker.canAcceptInBackground = true; - - type PickedResult = { - readonly item: QuickPickItem; - readonly keyMods?: IKeyMods; - readonly openInBackground: boolean; - }; - - function openEditor(picked: PickedResult) { - const targetGroup = getTargetGroup(group, picked.keyMods, configurationService, editorGroupsService); - - const openOptions: IEditorOptions = { - ...options, - override: picked.item.id, - preserveFocus: picked.openInBackground || options?.preserveFocus, - }; - return picked.item.handler.open(input, openOptions, targetGroup, OpenEditorContext.NEW_EDITOR)?.override; - } - - let picked: PickedResult | undefined; - try { - picked = await new Promise(resolve => { - picker.onDidAccept(e => { - if (picker.selectedItems.length === 1) { - const result: PickedResult = { - item: picker.selectedItems[0], - keyMods: picker.keyMods, - openInBackground: e.inBackground - }; - - if (e.inBackground) { - openEditor(result); - } else { - resolve(result); - } - } else { - resolve(undefined); - } - }); - - picker.onDidTriggerItemButton(e => { - const pick = e.item; - const id = pick.id; - resolve({ item: pick, openInBackground: false }); // open the view - picker.dispose(); - - // And persist the setting - if (pick && id) { - const newAssociation: CustomEditorAssociation = { viewType: id, filenamePattern: '*' + resourceExt }; - const currentAssociations = [...configurationService.getValue(customEditorsAssociationsSettingId)]; - - // First try updating existing association - for (let i = 0; i < currentAssociations.length; ++i) { - const existing = currentAssociations[i]; - if (existing.filenamePattern === newAssociation.filenamePattern) { - currentAssociations.splice(i, 1, newAssociation); - configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations); - return; - } - } - - // Otherwise, create a new one - currentAssociations.unshift(newAssociation); - configurationService.updateValue(customEditorsAssociationsSettingId, currentAssociations); - } - }); - - picker.show(); - }); - } finally { - picker.dispose(); - } - - if (!picked) { - return undefined; - } - - return openEditor(picked); -} - -const builtinProviderDisplayName = nls.localize('builtinProviderDisplayName', "Built-in"); - -export const defaultEditorOverrideEntry = Object.freeze({ - id: DEFAULT_EDITOR_ID, - label: nls.localize('promptOpenWith.defaultEditor.displayName', "Text Editor"), - detail: builtinProviderDisplayName -}); - -/** - * Get the group to open the editor in by looking at the pressed keys from the picker. - */ -function getTargetGroup( - startingGroup: IEditorGroup, - keyMods: IKeyMods | undefined, - configurationService: IConfigurationService, - editorGroupsService: IEditorGroupsService, -) { - if (keyMods?.alt || keyMods?.ctrlCmd) { - const direction = preferredSideBySideGroupDirection(configurationService); - const targetGroup = editorGroupsService.findGroup({ direction }, startingGroup.id); - return targetGroup ?? editorGroupsService.addGroup(startingGroup, direction); - } - return startingGroup; -} - -/** - * Get a list of all available editors, including the default text editor. - */ -export function getAllAvailableEditors( - resource: URI, - id: string | undefined, - options: IEditorOptions | ITextEditorOptions | undefined, - group: IEditorGroup, - editorService: IEditorService -): Array<[IOpenEditorOverrideHandler, IOpenEditorOverrideEntry]> { - const fileEditorInputFactory = Registry.as(EditorExtensions.EditorInputFactories).getFileEditorInputFactory(); - const overrides = editorService.getEditorOverrides(resource, options, group); - if (!overrides.some(([_, entry]) => entry.id === DEFAULT_EDITOR_ID)) { - overrides.unshift([ - { - open: (input: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup) => { - const resource = EditorResourceAccessor.getOriginalUri(input); - if (!resource) { - return; - } - - const fileEditorInput = editorService.createEditorInput({ resource, forceFile: true }); - const textOptions: IEditorOptions | ITextEditorOptions = options ? { ...options, override: false } : { override: false }; - return { - override: (async () => { - // Try to replace existing editors for resource - const existingEditor = firstOrDefault(editorService.findEditors(resource, group)); - if (existingEditor && !fileEditorInput.matches(existingEditor)) { - await editorService.replaceEditors([{ - editor: existingEditor, - replacement: fileEditorInput, - options: options ? EditorOptions.create(options) : undefined, - }], group); - } - - return editorService.openEditor(fileEditorInput, textOptions, group); - })() - }; - } - }, - { - ...defaultEditorOverrideEntry, - active: fileEditorInputFactory.isFileEditorInput(editorService.activeEditor) && isEqual(editorService.activeEditor.resource, resource), - }]); - } - - return overrides; -} - -export const customEditorsAssociationsSettingId = 'workbench.editorAssociations'; - -export const viewTypeSchemaAddition: IJSONSchema = { - type: 'string', - enum: [] -}; - -export type CustomEditorAssociation = { - readonly viewType: string; - readonly filenamePattern?: string; -}; - -export type CustomEditorsAssociations = readonly CustomEditorAssociation[]; - -export const editorAssociationsConfigurationNode: IConfigurationNode = { - ...workbenchConfigurationNodeBase, - properties: { - [customEditorsAssociationsSettingId]: { - type: 'array', - markdownDescription: nls.localize('editor.editorAssociations', "Configure which editor to use for specific file types."), - items: { - type: 'object', - defaultSnippets: [{ - body: { - 'viewType': '$1', - 'filenamePattern': '$2' - } - }], - properties: { - 'viewType': { - anyOf: [ - { - type: 'string', - description: nls.localize('editor.editorAssociations.viewType', "The unique id of the editor to use."), - }, - viewTypeSchemaAddition - ] - }, - 'filenamePattern': { - type: 'string', - description: nls.localize('editor.editorAssociations.filenamePattern', "Glob pattern specifying which files the editor should be used for."), - } - } - } - } - } -}; - -export const DEFAULT_CUSTOM_EDITOR: ICustomEditorInfo = { - id: 'default', - displayName: nls.localize('promptOpenWith.defaultEditor.displayName', "Text Editor"), - providerDisplayName: builtinProviderDisplayName -}; - -export function updateViewTypeSchema(enumValues: string[], enumDescriptions: string[]): void { - viewTypeSchemaAddition.enum = enumValues; - viewTypeSchemaAddition.enumDescriptions = enumDescriptions; - - Registry.as(Extensions.Configuration) - .notifyConfigurationSchemaUpdated(editorAssociationsConfigurationNode); -} diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index e2d267e6704d8..f8b6cc96d5f8d 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -82,7 +82,7 @@ import { BrowserTextFileService } from 'vs/workbench/services/textfile/browser/b import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; -import { Direction } from 'vs/base/browser/ui/grid/grid'; +import { Direction, LayoutPriority } from 'vs/base/browser/ui/grid/grid'; import { IProgressService, IProgressOptions, IProgressWindowOptions, IProgressNotificationOptions, IProgressCompositeOptions, IProgress, IProgressStep, Progress } from 'vs/platform/progress/common/progress'; import { IWorkingCopyFileService, WorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService'; import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; @@ -631,6 +631,13 @@ export class TestEditorGroupsService implements IEditorGroupsService { export class TestEditorGroupView implements IEditorGroupView { constructor(public id: number) { } + preferredHeight?: number | undefined; + preferredWidth?: number | undefined; + priority?: LayoutPriority | undefined; + snap?: boolean | undefined; + openEditorWith(editor: IEditorInput, id: string | undefined, options: ITextEditorOptions | IEditorOptions | undefined): Promise { + throw new Error('Method not implemented.'); + } get group(): EditorGroup { throw new Error('not implemented'); } activeEditorPane!: IVisibleEditorPane;