diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 29b532253ec..3865ff60cb1 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -21,7 +21,7 @@ import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } fr import { IEditorInput } from 'vs/workbench/common/editor'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { CustomFileEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput'; -import { CustomEditorModel } from 'vs/workbench/contrib/customEditor/browser/customEditorModel'; +import { CustomEditorModel } from 'vs/workbench/contrib/customEditor/common/customEditorModel'; import { WebviewExtensionDescription } from 'vs/workbench/contrib/webview/browser/webview'; import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput'; import { ICreateWebViewShowOptions, IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService'; diff --git a/src/vs/workbench/contrib/customEditor/browser/commands.ts b/src/vs/workbench/contrib/customEditor/browser/commands.ts index 996aa3ceb7e..5aefbd36ca8 100644 --- a/src/vs/workbench/contrib/customEditor/browser/commands.ts +++ b/src/vs/workbench/contrib/customEditor/browser/commands.ts @@ -4,15 +4,19 @@ *--------------------------------------------------------------------------------------------*/ import { firstOrDefault } from 'vs/base/common/arrays'; +import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { URI } from 'vs/base/common/uri'; +import { Command } from 'vs/editor/browser/editorExtensions'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import * as nls from 'vs/nls'; import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; +import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; +import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IListService } from 'vs/platform/list/browser/listService'; import { IEditorCommandsContext } from 'vs/workbench/common/editor'; -import { ICustomEditorService, CONTEXT_HAS_CUSTOM_EDITORS } from 'vs/workbench/contrib/customEditor/common/customEditor'; +import { CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE, CONTEXT_HAS_CUSTOM_EDITORS, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { getMultiSelectedResources } from 'vs/workbench/contrib/files/browser/files'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -98,3 +102,52 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, { }); // #endregion + + +(new class UndoCustomEditorCommand extends Command { + public static readonly ID = 'editor.action.customEditor.undo'; + + constructor() { + super({ + id: UndoCustomEditorCommand.ID, + precondition: ContextKeyExpr.and( + CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE, + ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_Z, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public runCommand(accessor: ServicesAccessor, _args: any): void { + const customEditorService = accessor.get(ICustomEditorService); + if (!customEditorService.activeCustomEditor) { + return; + } + console.log(customEditorService.activeCustomEditor); + } +}).register(); + +(new class RedoWebviewEditorCommand extends Command { + public static readonly ID = 'editor.action.customEditor.redo'; + + constructor() { + super({ + id: RedoWebviewEditorCommand.ID, + precondition: ContextKeyExpr.and( + CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE, + ContextKeyExpr.not(InputFocusedContextKey)), + kbOpts: { + primary: KeyMod.CtrlCmd | KeyCode.KEY_Y, + secondary: [KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z], + mac: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z }, + weight: KeybindingWeight.EditorContrib + } + }); + } + + public runCommand(_accessor: ServicesAccessor, args: any): void { + console.log('redo', args); + } +}).register(); diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts index d100c41d38e..376cfce5686 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditorInput.ts @@ -15,7 +15,7 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IEditorInput, Verbosity } from 'vs/workbench/common/editor'; import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/webview'; import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService'; -import { CustomEditorModel } from './customEditorModel'; +import { CustomEditorModel } from '../common/customEditorModel'; import { ISaveOptions, IRevertOptions } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export class CustomFileEditorInput extends LazilyResolvedWebviewEditorInput { diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditors.ts b/src/vs/workbench/contrib/customEditor/browser/customEditors.ts index 5a0b6a47e3b..e6ee2764843 100644 --- a/src/vs/workbench/contrib/customEditor/browser/customEditors.ts +++ b/src/vs/workbench/contrib/customEditor/browser/customEditors.ts @@ -21,7 +21,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { EditorInput, EditorOptions, IEditor, IEditorInput } from 'vs/workbench/common/editor'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { webviewEditorsExtensionPoint } from 'vs/workbench/contrib/customEditor/browser/extensionPoint'; -import { CustomEditorPriority, CustomEditorInfo, CustomEditorSelector, ICustomEditorService, CONTEXT_HAS_CUSTOM_EDITORS } from 'vs/workbench/contrib/customEditor/common/customEditor'; +import { CustomEditorPriority, CustomEditorInfo, CustomEditorSelector, ICustomEditorService, CONTEXT_HAS_CUSTOM_EDITORS, CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE, ICustomEditor } from 'vs/workbench/contrib/customEditor/common/customEditor'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -41,7 +41,7 @@ const defaultEditorInfo: CustomEditorInfo = { priority: CustomEditorPriority.default, }; -export class CustomEditorStore { +export class CustomEditorInfoStore { private readonly contributedEditors = new Map(); public clear() { @@ -71,8 +71,10 @@ export class CustomEditorStore { export class CustomEditorService extends Disposable implements ICustomEditorService { _serviceBrand: any; - private readonly editors = new CustomEditorStore(); + private readonly _editorInfoStore = new CustomEditorInfoStore(); + private readonly _hasCustomEditor: IContextKey; + private readonly _focusedCustomEditorIsEditable: IContextKey; constructor( @IContextKeyService contextKeyService: IContextKeyService, @@ -85,11 +87,11 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ super(); webviewEditorsExtensionPoint.setHandler(extensions => { - this.editors.clear(); + this._editorInfoStore.clear(); for (const extension of extensions) { for (const webviewEditorContribution of extension.value) { - this.editors.add({ + this._editorInfoStore.add({ id: webviewEditorContribution.viewType, displayName: webviewEditorContribution.displayName, selector: webviewEditorContribution.selector || [], @@ -97,24 +99,37 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ }); } } - this.updateContext(); + this.updateContexts(); }); this._hasCustomEditor = CONTEXT_HAS_CUSTOM_EDITORS.bindTo(contextKeyService); + this._focusedCustomEditorIsEditable = CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE.bindTo(contextKeyService); - this._register(this.editorService.onDidActiveEditorChange(() => this.updateContext())); - this.updateContext(); + this._register(this.editorService.onDidActiveEditorChange(() => this.updateContexts())); + this.updateContexts(); + } + + public get activeCustomEditor(): ICustomEditor | undefined { + const activeInput = this.editorService.activeControl?.input; + if (!(activeInput instanceof CustomFileEditorInput)) { + return undefined; + } + + return { + resource: activeInput.getResource(), + model: undefined, + }; } public getContributedCustomEditors(resource: URI): readonly CustomEditorInfo[] { - return this.editors.getContributedEditors(resource); + return this._editorInfoStore.getContributedEditors(resource); } public getUserConfiguredCustomEditors(resource: URI): readonly CustomEditorInfo[] { const rawAssociations = this.configurationService.getValue(customEditorsAssociationsKey) || []; return coalesce(rawAssociations .filter(association => matches(association, resource)) - .map(association => this.editors.get(association.viewType))); + .map(association => this._editorInfoStore.get(association.viewType))); } public async promptOpenWith( @@ -164,7 +179,7 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ return this.openEditorForResource(resource, fileInput, { ...options, ignoreOverrides: true }, group); } - if (!this.editors.get(viewType)) { + if (!this._editorInfoStore.get(viewType)) { return this.promptOpenWith(resource, options, group); } @@ -215,22 +230,21 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ return this.editorService.openEditor(input, options, group); } - private updateContext() { + private updateContexts() { const activeControl = this.editorService.activeControl; - if (!activeControl) { - this._hasCustomEditor.reset(); - return; - } - const resource = activeControl.input.getResource(); + const resource = activeControl?.input.getResource(); if (!resource) { this._hasCustomEditor.reset(); + this._focusedCustomEditorIsEditable.reset(); return; } + const possibleEditors = [ ...this.getContributedCustomEditors(resource), ...this.getUserConfiguredCustomEditors(resource), ]; this._hasCustomEditor.set(possibleEditors.length > 0); + this._focusedCustomEditorIsEditable.set(activeControl?.input instanceof CustomFileEditorInput); } } diff --git a/src/vs/workbench/contrib/customEditor/browser/webviewEditor.contribution.ts b/src/vs/workbench/contrib/customEditor/browser/webviewEditor.contribution.ts index c5aa8b431bb..cfd19134b04 100644 --- a/src/vs/workbench/contrib/customEditor/browser/webviewEditor.contribution.ts +++ b/src/vs/workbench/contrib/customEditor/browser/webviewEditor.contribution.ts @@ -10,6 +10,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } from 'vs/workbench/browser/editor'; +import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor'; import { CustomEditoInputFactory } from 'vs/workbench/contrib/customEditor/browser/customEditorInputFactory'; @@ -18,7 +19,6 @@ import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEdito import './commands'; import { CustomFileEditorInput } from './customEditorInput'; import { CustomEditorContribution, customEditorsAssociationsKey, CustomEditorService } from './customEditors'; -import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration'; registerSingleton(ICustomEditorService, CustomEditorService); diff --git a/src/vs/workbench/contrib/customEditor/common/customEditor.ts b/src/vs/workbench/contrib/customEditor/common/customEditor.ts index a0bda2e0764..408c09a0f71 100644 --- a/src/vs/workbench/contrib/customEditor/common/customEditor.ts +++ b/src/vs/workbench/contrib/customEditor/common/customEditor.ts @@ -4,19 +4,28 @@ *--------------------------------------------------------------------------------------------*/ import { URI } from 'vs/base/common/uri'; +import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { EditorInput, IEditor } from 'vs/workbench/common/editor'; +import { CustomEditorModel } from 'vs/workbench/contrib/customEditor/common/customEditorModel'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; -import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; export const ICustomEditorService = createDecorator('customEditorService'); export const CONTEXT_HAS_CUSTOM_EDITORS = new RawContextKey('hasCustomEditors', false); +export const CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE = new RawContextKey('focusedCustomEditorIsEditable', false); + +export interface ICustomEditor { + readonly resource: URI; + readonly model: CustomEditorModel | undefined; +} export interface ICustomEditorService { _serviceBrand: any; + readonly activeCustomEditor: ICustomEditor | undefined; + getContributedCustomEditors(resource: URI): readonly CustomEditorInfo[]; getUserConfiguredCustomEditors(resource: URI): readonly CustomEditorInfo[]; diff --git a/src/vs/workbench/contrib/customEditor/browser/customEditorModel.ts b/src/vs/workbench/contrib/customEditor/common/customEditorModel.ts similarity index 100% rename from src/vs/workbench/contrib/customEditor/browser/customEditorModel.ts rename to src/vs/workbench/contrib/customEditor/common/customEditorModel.ts diff --git a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts index a0d0997b5eb..634dedfcce8 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts @@ -38,4 +38,4 @@ function registerWebViewCommands(editorId: string): void { } } -registerWebViewCommands(WebviewEditor.WebviewEditorID); +registerWebViewCommands(WebviewEditor.ID);