Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scope custom editor and webview context keys to editor groups and global context #213398

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 32 additions & 20 deletions src/vs/workbench/contrib/customEditor/browser/customEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { extname, isEqual } from 'vs/base/common/resources';
import { assertIsDefined } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { RedoCommand, UndoCommand } from 'vs/editor/browser/editorExtensions';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
import { FileOperation, IFileService } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
Expand All @@ -24,7 +23,7 @@ import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { CONTEXT_ACTIVE_CUSTOM_EDITOR_ID, CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE, CustomEditorCapabilities, CustomEditorInfo, CustomEditorInfoCollection, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
import { CustomEditorModelManager } from 'vs/workbench/contrib/customEditor/common/customEditorModelManager';
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroup, IEditorGroupContextKeyProvider, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorResolverService, IEditorType, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ContributedCustomEditors } from '../common/contributedCustomEditors';
Expand All @@ -40,16 +39,12 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ

private readonly _models = new CustomEditorModelManager();

private readonly _activeCustomEditorId: IContextKey<string>;
private readonly _focusedCustomEditorIsEditable: IContextKey<boolean>;

private readonly _onDidChangeEditorTypes = this._register(new Emitter<void>());
public readonly onDidChangeEditorTypes: Event<void> = this._onDidChangeEditorTypes.event;

private readonly _fileEditorFactory = Registry.as<IEditorFactoryRegistry>(EditorExtensions.EditorFactory).getFileEditorFactory();

constructor(
@IContextKeyService contextKeyService: IContextKeyService,
@IFileService fileService: IFileService,
@IStorageService storageService: IStorageService,
@IEditorService private readonly editorService: IEditorService,
Expand All @@ -60,20 +55,32 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ
) {
super();

this._activeCustomEditorId = CONTEXT_ACTIVE_CUSTOM_EDITOR_ID.bindTo(contextKeyService);
this._focusedCustomEditorIsEditable = CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE.bindTo(contextKeyService);

this._contributedEditors = this._register(new ContributedCustomEditors(storageService));
// Register the contribution points only emitting one change from the resolver
this.editorResolverService.bufferChangeEvents(this.registerContributionPoints.bind(this));

this._register(this._contributedEditors.onChange(() => {
// Register the contribution points only emitting one change from the resolver
this.editorResolverService.bufferChangeEvents(this.registerContributionPoints.bind(this));
this.updateContexts();
this._onDidChangeEditorTypes.fire();
}));
this._register(this.editorService.onDidActiveEditorChange(() => this.updateContexts()));

// Register group context key providers.
// These set the context keys for each editor group and the global context
const activeCustomEditorContextKeyProvider: IEditorGroupContextKeyProvider<string> = {
contextKey: CONTEXT_ACTIVE_CUSTOM_EDITOR_ID,
getGroupContextKeyValue: group => this.getActiveCustomEditorId(group),
onDidChange: this.onDidChangeEditorTypes
};

const customEditorIsEditableContextKeyProvider: IEditorGroupContextKeyProvider<boolean> = {
contextKey: CONTEXT_FOCUSED_CUSTOM_EDITOR_IS_EDITABLE,
getGroupContextKeyValue: group => this.getCustomEditorIsEditable(group),
onDidChange: this.onDidChangeEditorTypes
};

this._register(this.editorGroupService.registerContextKeyProvider(activeCustomEditorContextKeyProvider));
this._register(this.editorGroupService.registerContextKeyProvider(customEditorIsEditableContextKeyProvider));

this._register(fileService.onDidRunOperation(e => {
if (e.isOperation(FileOperation.MOVE)) {
Expand All @@ -88,8 +95,6 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ
this._register(RedoCommand.addImplementation(PRIORITY, 'custom-editor', () => {
return this.withActiveCustomEditor(editor => editor.redo());
}));

this.updateContexts();
}

getEditorTypes(): IEditorType[] {
Expand Down Expand Up @@ -193,17 +198,24 @@ export class CustomEditorService extends Disposable implements ICustomEditorServ
return this._editorCapabilities.get(viewType);
}

private updateContexts() {
const activeEditorPane = this.editorService.activeEditorPane;
private getActiveCustomEditorId(group: IEditorGroup): string {
const activeEditorPane = group.activeEditorPane;
const resource = activeEditorPane?.input?.resource;
if (!resource) {
this._activeCustomEditorId.reset();
this._focusedCustomEditorIsEditable.reset();
return;
return '';
}

return activeEditorPane?.input instanceof CustomEditorInput ? activeEditorPane.input.viewType : '';
}

private getCustomEditorIsEditable(group: IEditorGroup): boolean {
const activeEditorPane = group.activeEditorPane;
const resource = activeEditorPane?.input?.resource;
if (!resource) {
return false;
}

this._activeCustomEditorId.set(activeEditorPane?.input instanceof CustomEditorInput ? activeEditorPane.input.viewType : '');
this._focusedCustomEditorIsEditable.set(activeEditorPane?.input instanceof CustomEditorInput);
return activeEditorPane?.input instanceof CustomEditorInput;
}

private async handleMovedFileInOpenedFileEditors(oldResource: URI, newResource: URI): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { isCancellationError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { Iterable } from 'vs/base/common/iterator';
import { combinedDisposable, Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { EditorActivation } from 'vs/platform/editor/common/editor';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { GroupIdentifier } from 'vs/workbench/common/editor';
Expand All @@ -19,7 +18,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { IOverlayWebview, IWebviewService, WebviewInitInfo } from 'vs/workbench/contrib/webview/browser/webview';
import { CONTEXT_ACTIVE_WEBVIEW_PANEL_ID } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditor';
import { WebviewIconManager, WebviewIcons } from 'vs/workbench/contrib/webviewPanel/browser/webviewIconManager';
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
import { WebviewInput, WebviewInputInitInfo } from './webviewEditorInput';

Expand Down Expand Up @@ -213,20 +212,21 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc

private readonly _iconManager: WebviewIconManager;

private readonly _activeWebviewPanelIdContext: IContextKey<string>;

constructor(
@IContextKeyService contextKeyService: IContextKeyService,
@IEditorGroupsService editorGroupsService: IEditorGroupsService,
@IEditorService private readonly _editorService: IEditorService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IWebviewService private readonly _webviewService: IWebviewService,
) {
super();

this._activeWebviewPanelIdContext = CONTEXT_ACTIVE_WEBVIEW_PANEL_ID.bindTo(contextKeyService);

this._iconManager = this._register(this._instantiationService.createInstance(WebviewIconManager));

this._register(editorGroupsService.registerContextKeyProvider({
contextKey: CONTEXT_ACTIVE_WEBVIEW_PANEL_ID,
getGroupContextKeyValue: (group) => this.getWebviewId(group.activeEditor),
}));

this._register(_editorService.onDidActiveEditorChange(() => {
this.updateActiveWebview();
}));
Expand All @@ -248,6 +248,21 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc
private readonly _onDidChangeActiveWebviewEditor = this._register(new Emitter<WebviewInput | undefined>());
public readonly onDidChangeActiveWebviewEditor = this._onDidChangeActiveWebviewEditor.event;

private getWebviewId(input: EditorInput | null): string {
let webviewInput: WebviewInput | undefined;
if (input instanceof WebviewInput) {
webviewInput = input;
} else if (input instanceof DiffEditorInput) {
if (input.primary instanceof WebviewInput) {
webviewInput = input.primary;
} else if (input.secondary instanceof WebviewInput) {
webviewInput = input.secondary;
}
}

return webviewInput?.webview.providedViewType ?? '';
}

private updateActiveWebview() {
const activeInput = this._editorService.activeEditor;

Expand All @@ -261,13 +276,6 @@ export class WebviewEditorService extends Disposable implements IWebviewWorkbenc
newActiveWebview = activeInput.secondary;
}
}

if (newActiveWebview) {
this._activeWebviewPanelIdContext.set(newActiveWebview.webview.providedViewType ?? '');
} else {
this._activeWebviewPanelIdContext.reset();
}

if (newActiveWebview !== this._activeWebview) {
this._activeWebview = newActiveWebview;
this._onDidChangeActiveWebviewEditor.fire(newActiveWebview);
Expand Down
Loading