Skip to content

Commit

Permalink
Added a way to unregister keybindings for a command
Browse files Browse the repository at this point in the history
fixes: eclipse-theia#8209
Signed-off-by: Jonas Helming <jhelming@eclipsesource.com>
  • Loading branch information
JonasHelming authored and kittaakos committed Aug 31, 2020
1 parent e36195e commit 10e16fe
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 12 deletions.
117 changes: 117 additions & 0 deletions packages/core/src/browser/keybinding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,108 @@ describe('keybindings', () => {
}
});

it('should register a keybinding', () => {
const keybinding: Keybinding = {
command: TEST_COMMAND2.id,
keybinding: 'F5'
};
expect(isKeyBindingRegistered(keybinding)).to.be.false;

keybindingRegistry.registerKeybinding(keybinding);

expect(isKeyBindingRegistered(keybinding)).to.be.true;
}
);

it('should unregister all keybindings from a specific command', () => {
const otherKeybinding: Keybinding = {
command: TEST_COMMAND.id,
keybinding: 'F4'
};
keybindingRegistry.registerKeybinding(otherKeybinding);
expect(isKeyBindingRegistered(otherKeybinding)).to.be.true;

const keybinding: Keybinding = {
command: TEST_COMMAND2.id,
keybinding: 'F5'
};
const keybinding2: Keybinding = {
command: TEST_COMMAND2.id,
keybinding: 'F6'
};

keybindingRegistry.registerKeybinding(keybinding);
keybindingRegistry.registerKeybinding(keybinding2);
expect(isKeyBindingRegistered(keybinding)).to.be.true;
expect(isKeyBindingRegistered(keybinding2)).to.be.true;

keybindingRegistry.unregisterKeybinding(TEST_COMMAND2);

expect(isKeyBindingRegistered(keybinding)).to.be.false;
expect(isKeyBindingRegistered(keybinding2)).to.be.false;
const bindingsAfterUnregister = keybindingRegistry.getKeybindingsForCommand(TEST_COMMAND2.id);
expect(bindingsAfterUnregister).not.to.be.undefined;
expect(bindingsAfterUnregister.length).to.be.equal(0);
expect(isKeyBindingRegistered(otherKeybinding)).to.be.true;
});

it('should unregister a specific keybinding', () => {
const otherKeybinding: Keybinding = {
command: TEST_COMMAND2.id,
keybinding: 'F4'
};

keybindingRegistry.registerKeybinding(otherKeybinding);
const keybinding: Keybinding = {
command: TEST_COMMAND2.id,
keybinding: 'F5'
};

keybindingRegistry.registerKeybinding(keybinding);

expect(isKeyBindingRegistered(otherKeybinding)).to.be.true;
expect(isKeyBindingRegistered(keybinding)).to.be.true;

keybindingRegistry.unregisterKeybinding(keybinding);

expect(isKeyBindingRegistered(keybinding)).to.be.false;
expect(isKeyBindingRegistered(otherKeybinding)).to.be.true;
}
);

it('should unregister a specific key', () => {
const otherKeybinding: Keybinding = {
command: TEST_COMMAND.id,
keybinding: 'F4'
};

keybindingRegistry.registerKeybinding(otherKeybinding);
const testKey = 'F5';
const keybinding: Keybinding = {
command: TEST_COMMAND2.id,
keybinding: testKey
};

const keybinding2: Keybinding = {
command: TEST_COMMAND.id,
keybinding: testKey
};

keybindingRegistry.registerKeybinding(keybinding);
keybindingRegistry.registerKeybinding(keybinding2);

expect(isKeyBindingRegistered(otherKeybinding)).to.be.true;
expect(isKeyBindingRegistered(keybinding)).to.be.true;
expect(isKeyBindingRegistered(keybinding2)).to.be.true;

keybindingRegistry.unregisterKeybinding(testKey);

expect(isKeyBindingRegistered(otherKeybinding)).to.be.true;
expect(isKeyBindingRegistered(keybinding)).to.be.false;
expect(isKeyBindingRegistered(keybinding2)).to.be.false;
}
);

it('should register a correct keybinding, then default back to the original for a wrong one after', () => {
let keybindings: Keybinding[] = [{
command: TEST_COMMAND.id,
Expand Down Expand Up @@ -418,3 +520,18 @@ class TestContribution implements CommandContribution, KeybindingContribution {
}

}

function isKeyBindingRegistered(keybinding: Keybinding): boolean {
const bindings = keybindingRegistry.getKeybindingsForCommand(keybinding.command);
expect(bindings).not.to.be.undefined;
let keyBindingFound = false;
bindings.forEach(
(value: Keybinding) => {
if (value.command === keybinding.command && value.keybinding === keybinding.keybinding) {
keyBindingFound = true;
}
}
);
return keyBindingFound;
}

32 changes: 20 additions & 12 deletions packages/core/src/browser/keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import { injectable, inject, named } from 'inversify';
import { isOSX } from '../common/os';
import { Emitter, Event } from '../common/event';
import { CommandRegistry } from '../common/command';
import { CommandRegistry, Command } from '../common/command';
import { Disposable, DisposableCollection } from '../common/disposable';
import { KeyCode, KeySequence, Key } from './keyboard/keys';
import { KeyboardLayoutService } from './keyboard/keyboard-layout-service';
Expand Down Expand Up @@ -184,28 +184,36 @@ export class KeybindingRegistry {
}

/**
* Unregister keybinding from the registry
* Unregister keybindings from the registry using the key of the given keybinging
*
* @param binding
* @param binding a Keybinding specifying the key to be unregistered
*/
unregisterKeybinding(binding: common.Keybinding): void;
/**
* Unregister keybinding from the registry
* Unregister keybindings with the given key from the registry
*
* @param key
* @param key a key to be unregistered
*/
unregisterKeybinding(key: string): void;
unregisterKeybinding(keyOrBinding: common.Keybinding | string): void {
const key = common.Keybinding.is(keyOrBinding) ? keyOrBinding.keybinding : keyOrBinding;
const keymap = this.keymaps[KeybindingScope.DEFAULT];
const bindings = keymap.filter(el => el.keybinding === key);
/**
* Unregister all existing keybindings for the given command
* @param command the command to unregister keybindings for
*/
unregisterKeybinding(command: Command): void;

bindings.forEach(binding => {
unregisterKeybinding(arg: common.Keybinding | string | Command): void {
const keymap = this.keymaps[KeybindingScope.DEFAULT];
const filter = Command.is(arg)
? ({ command }: common.Keybinding) => command === arg.id
: ({ keybinding }: common.Keybinding) => Keybinding.is(arg)
? keybinding === arg.keybinding
: keybinding === arg;
for (const binding of keymap.filter(filter)) {
const idx = keymap.indexOf(binding);
if (idx >= 0) {
if (idx !== -1) {
keymap.splice(idx, 1);
}
});
}
}

protected doRegisterKeybindings(bindings: common.Keybinding[], scope: KeybindingScope = KeybindingScope.DEFAULT): Disposable {
Expand Down

0 comments on commit 10e16fe

Please sign in to comment.