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

Allow unregistering registerSchemaContribution #233733

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions src/vs/editor/standalone/browser/standaloneServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,8 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
return '';
}

public registerSchemaContribution(contribution: KeybindingsSchemaContribution): void {
// noop
public registerSchemaContribution(contribution: KeybindingsSchemaContribution): IDisposable {
return Disposable.None;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
public abstract resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[];
public abstract resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding;
public abstract resolveUserBinding(userBinding: string): ResolvedKeybinding[];
public abstract registerSchemaContribution(contribution: KeybindingsSchemaContribution): void;
public abstract registerSchemaContribution(contribution: KeybindingsSchemaContribution): IDisposable;
public abstract _dumpDebugInfo(): string;
public abstract _dumpDebugInfoJSON(): string;

Expand Down
3 changes: 2 additions & 1 deletion src/vs/platform/keybinding/common/keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Event } from '../../../base/common/event.js';
import { IJSONSchema } from '../../../base/common/jsonSchema.js';
import { KeyCode } from '../../../base/common/keyCodes.js';
import { ResolvedKeybinding, Keybinding } from '../../../base/common/keybindings.js';
import { IDisposable } from '../../../base/common/lifecycle.js';
import { IContextKeyService, IContextKeyServiceTarget } from '../../contextkey/common/contextkey.js';
import { createDecorator } from '../../instantiation/common/instantiation.js';
import { ResolutionResult } from './keybindingResolver.js';
Expand Down Expand Up @@ -101,7 +102,7 @@ export interface IKeybindingService {
*/
mightProducePrintableCharacter(event: IKeyboardEvent): boolean;

registerSchemaContribution(contribution: KeybindingsSchemaContribution): void;
registerSchemaContribution(contribution: KeybindingsSchemaContribution): IDisposable;

toggleLogging(): boolean;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import assert from 'assert';
import { KeyChord, KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';
import { createSimpleKeybinding, ResolvedKeybinding, KeyCodeChord, Keybinding } from '../../../../base/common/keybindings.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js';
import { OS } from '../../../../base/common/platform.js';
import Severity from '../../../../base/common/severity.js';
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';
Expand Down Expand Up @@ -93,8 +93,8 @@ suite('AbstractKeybindingService', () => {
return '';
}

public registerSchemaContribution() {
// noop
public registerSchemaContribution(): IDisposable {
return Disposable.None;
}

public enableKeybindingHoldMode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/

import { Event } from '../../../../base/common/event.js';
import { ResolvedKeybinding, KeyCodeChord, Keybinding } from '../../../../base/common/keybindings.js';
import { KeyCodeChord, Keybinding, ResolvedKeybinding } from '../../../../base/common/keybindings.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { OS } from '../../../../base/common/platform.js';
import { ContextKeyExpression, ContextKeyValue, IContextKey, IContextKeyChangeEvent, IContextKeyService, IContextKeyServiceTarget, IScopedContextKeyService } from '../../../contextkey/common/contextkey.js';
import { IKeybindingService, IKeyboardEvent } from '../../common/keybinding.js';
Expand Down Expand Up @@ -168,6 +169,6 @@ export class MockKeybindingService implements IKeybindingService {
}

public registerSchemaContribution() {
// noop
return Disposable.None;
}
}
41 changes: 29 additions & 12 deletions src/vs/workbench/services/keybinding/browser/keybindingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import * as browser from '../../../../base/browser/browser.js';
import { BrowserFeatures, KeyboardSupport } from '../../../../base/browser/canIUse.js';
import * as dom from '../../../../base/browser/dom.js';
import { printKeyboardEvent, printStandardKeyboardEvent, StandardKeyboardEvent } from '../../../../base/browser/keyboardEvent.js';
import { mainWindow } from '../../../../base/browser/window.js';
import { DeferredPromise, RunOnceScheduler } from '../../../../base/common/async.js';
import { Emitter, Event } from '../../../../base/common/event.js';
import { parse } from '../../../../base/common/json.js';
Expand All @@ -18,13 +19,13 @@ import { UserSettingsLabelProvider } from '../../../../base/common/keybindingLab
import { KeybindingParser } from '../../../../base/common/keybindingParser.js';
import { Keybinding, KeyCodeChord, ResolvedKeybinding, ScanCodeChord } from '../../../../base/common/keybindings.js';
import { IMMUTABLE_CODE_TO_KEY_CODE, KeyCode, KeyCodeUtils, KeyMod, ScanCode, ScanCodeUtils } from '../../../../base/common/keyCodes.js';
import { Disposable, DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js';
import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../../../base/common/lifecycle.js';
import * as objects from '../../../../base/common/objects.js';
import { isMacintosh, OperatingSystem, OS } from '../../../../base/common/platform.js';
import { dirname } from '../../../../base/common/resources.js';
import { mainWindow } from '../../../../base/browser/window.js';

// platform
import { ILocalizedString, isLocalizedString } from '../../../../platform/action/common/action.js';
import { MenuRegistry } from '../../../../platform/actions/common/actions.js';
import { CommandsRegistry, ICommandService } from '../../../../platform/commands/common/commands.js';
import { ContextKeyExpr, ContextKeyExpression, IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
Expand All @@ -44,17 +45,17 @@ import { INotificationService } from '../../../../platform/notification/common/n
import { Registry } from '../../../../platform/registry/common/platform.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
import { ILocalizedString, isLocalizedString } from '../../../../platform/action/common/action.js';

// workbench
import { remove } from '../../../../base/common/arrays.js';
import { commandsExtensionPoint } from '../../actions/common/menusExtensionPoint.js';
import { IExtensionService } from '../../extensions/common/extensions.js';
import { ExtensionMessageCollector, ExtensionsRegistry } from '../../extensions/common/extensionsRegistry.js';
import { IHostService } from '../../host/browser/host.js';
import { IUserDataProfileService } from '../../userDataProfile/common/userDataProfile.js';
import { IUserKeybindingItem, KeybindingIO, OutputBuilder } from '../common/keybindingIO.js';
import { IKeyboard, INavigatorWithKeyboard } from './navigatorKeyboard.js';
import { getAllUnboundCommands } from './unboundCommands.js';
import { IUserKeybindingItem, KeybindingIO, OutputBuilder } from '../common/keybindingIO.js';
import { IUserDataProfileService } from '../../userDataProfile/common/userDataProfile.js';

interface ContributedKeyBinding {
command: string;
Expand Down Expand Up @@ -184,7 +185,10 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
private userKeybindings: UserKeybindings;
private isComposingGlobalContextKey: IContextKey<boolean>;
private _keybindingHoldMode: DeferredPromise<void> | null;
private readonly _contributions: KeybindingsSchemaContribution[] = [];
private readonly _contributions: Array<{
readonly listener?: IDisposable;
readonly contribution: KeybindingsSchemaContribution;
}> = [];
private readonly kbsJsonSchema: KeybindingsJsonSchema;

constructor(
Expand Down Expand Up @@ -266,6 +270,13 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
}));
}

public override dispose(): void {
this._contributions.forEach(c => c.listener?.dispose());
this._contributions.length = 0;

super.dispose();
}

private _registerKeyListeners(window: Window): IDisposable {
const disposables = new DisposableStore();

Expand Down Expand Up @@ -300,16 +311,22 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
return disposables;
}

public registerSchemaContribution(contribution: KeybindingsSchemaContribution): void {
this._contributions.push(contribution);
if (contribution.onDidChange) {
this._register(contribution.onDidChange(() => this.updateKeybindingsJsonSchema()));
}
public registerSchemaContribution(contribution: KeybindingsSchemaContribution): IDisposable {
const listener = contribution.onDidChange?.(() => this.updateKeybindingsJsonSchema());
const entry = { listener, contribution };
this._contributions.push(entry);

this.updateKeybindingsJsonSchema();

return toDisposable(() => {
listener?.dispose();
remove(this._contributions, entry);
this.updateKeybindingsJsonSchema();
});
}

private updateKeybindingsJsonSchema() {
this.kbsJsonSchema.updateSchema(this._contributions.flatMap(x => x.getSchemaAdditions()));
this.kbsJsonSchema.updateSchema(this._contributions.flatMap(x => x.contribution.getSchemaAdditions()));
}

private _printKeybinding(keybinding: Keybinding): string {
Expand Down
Loading