From a3dba6ed08e32f175ca0e55fc667bd8c7a861e00 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Fri, 17 Mar 2017 18:19:30 +0100 Subject: [PATCH] Adopt RuntimeKeybinding --- build/monaco/monaco.d.ts.recipe | 1 - src/vs/base/browser/keyboardEvent.ts | 29 +++- src/vs/base/common/keyCodes.ts | 128 +++------------- .../base/parts/tree/browser/treeDefaults.ts | 12 +- src/vs/base/test/common/keyCodes.test.ts | 144 ++++++++++-------- .../browser/standalone/simpleServices.ts | 2 +- .../common/standalone/standaloneBase.ts | 3 +- .../editor/contrib/find/browser/findWidget.ts | 89 ++++++----- .../browser/standalone/simpleServices.test.ts | 6 +- src/vs/monaco.d.ts | 12 -- .../common/abstractKeybindingService.ts | 15 +- .../platform/keybinding/common/keybinding.ts | 6 +- .../common/abstractKeybindingService.test.ts | 28 ++-- .../test/common/mockKeybindingService.ts | 8 +- .../extensions/browser/extensionEditor.ts | 4 +- .../preferences/browser/keybindingWidgets.ts | 16 +- .../browser/keybindingsEditorContribution.ts | 8 +- .../parts/search/browser/searchActions.ts | 5 +- .../search/test/browser/searchActions.test.ts | 3 +- .../electron-browser/terminalInstance.ts | 2 +- .../parts/update/electron-browser/update.ts | 4 +- .../keybinding/common/keyboardMapper.ts | 43 ++---- .../electron-browser/keybindingService.ts | 2 +- .../keybinding/test/keyboardMapper.test.ts | 20 +-- 24 files changed, 263 insertions(+), 327 deletions(-) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index 833c2e30aad..9f94b8ab27d 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -40,7 +40,6 @@ declare module monaco { #include(vs/base/common/cancellation): CancellationTokenSource, CancellationToken #include(vs/base/common/uri): URI #include(vs/editor/common/standalone/standaloneBase): KeyCode, KeyMod -#include(vs/base/common/keyCodes): SimpleKeybinding #include(vs/base/common/htmlContent): MarkedString #include(vs/base/browser/keyboardEvent): IKeyboardEvent #include(vs/base/browser/mouseEvent): IMouseEvent diff --git a/src/vs/base/browser/keyboardEvent.ts b/src/vs/base/browser/keyboardEvent.ts index 8423cacd5ae..cacfffa9955 100644 --- a/src/vs/base/browser/keyboardEvent.ts +++ b/src/vs/base/browser/keyboardEvent.ts @@ -5,7 +5,7 @@ 'use strict'; -import { SimpleKeybinding, KeyCode, KeyCodeUtils, KeyMod } from 'vs/base/common/keyCodes'; +import { KeyCode, KeyCodeUtils, KeyMod, SimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import * as browser from 'vs/base/browser/browser'; @@ -175,7 +175,10 @@ export interface IKeyboardEvent { readonly metaKey: boolean; readonly keyCode: KeyCode; - toKeybinding(): SimpleKeybinding; + /** + * @internal + */ + toRuntimeKeybinding(): SimpleRuntimeKeybinding; equals(keybinding: number): boolean; preventDefault(): void; @@ -198,7 +201,8 @@ export class StandardKeyboardEvent implements IKeyboardEvent { public readonly metaKey: boolean; public readonly keyCode: KeyCode; - private _asKeybinding: SimpleKeybinding; + private _asKeybinding: number; + private _asRuntimeKeybinding: SimpleRuntimeKeybinding; constructor(source: KeyboardEvent) { let e = source; @@ -220,6 +224,7 @@ export class StandardKeyboardEvent implements IKeyboardEvent { this.metaKey = this.metaKey || this.keyCode === KeyCode.Meta; this._asKeybinding = this._computeKeybinding(); + this._asRuntimeKeybinding = this._computeRuntimeKeybinding(); // console.log(`code: ${e.code}, keyCode: ${e.keyCode}, key: ${e.key}`); } @@ -236,15 +241,15 @@ export class StandardKeyboardEvent implements IKeyboardEvent { } } - public toKeybinding(): SimpleKeybinding { - return this._asKeybinding; + public toRuntimeKeybinding(): SimpleRuntimeKeybinding { + return this._asRuntimeKeybinding; } public equals(other: number): boolean { - return this._asKeybinding.value === other; + return this._asKeybinding === other; } - private _computeKeybinding(): SimpleKeybinding { + private _computeKeybinding(): number { let key = KeyCode.Unknown; if (this.keyCode !== KeyCode.Ctrl && this.keyCode !== KeyCode.Shift && this.keyCode !== KeyCode.Alt && this.keyCode !== KeyCode.Meta) { key = this.keyCode; @@ -265,6 +270,14 @@ export class StandardKeyboardEvent implements IKeyboardEvent { } result |= key; - return new SimpleKeybinding(result); + return result; + } + + private _computeRuntimeKeybinding(): SimpleRuntimeKeybinding { + let key = KeyCode.Unknown; + if (this.keyCode !== KeyCode.Ctrl && this.keyCode !== KeyCode.Shift && this.keyCode !== KeyCode.Alt && this.keyCode !== KeyCode.Meta) { + key = this.keyCode; + } + return new SimpleRuntimeKeybinding(this.ctrlKey, this.shiftKey, this.altKey, this.metaKey, key); } } diff --git a/src/vs/base/common/keyCodes.ts b/src/vs/base/common/keyCodes.ts index 8134633ce0b..b456b1a474f 100644 --- a/src/vs/base/common/keyCodes.ts +++ b/src/vs/base/common/keyCodes.ts @@ -489,109 +489,6 @@ class BinaryKeybindings { } } -export function createKeybinding(keybinding: number): Keybinding { - if (BinaryKeybindings.hasChord(keybinding)) { - return new ChordKeybinding(keybinding); - } - return new SimpleKeybinding(keybinding); -} - -export class SimpleKeybinding { - public readonly value: number; - - constructor(keybinding: number) { - this.value = keybinding; - } - - /** - * @internal - */ - public isChord(): this is ChordKeybinding { - return false; - } - - /** - * @internal - */ - public equals(other: Keybinding): boolean { - return (other && this.value === other.value); - } - - public hasCtrlCmd(): boolean { - return BinaryKeybindings.hasCtrlCmd(this.value); - } - - public hasShift(): boolean { - return BinaryKeybindings.hasShift(this.value); - } - - public hasAlt(): boolean { - return BinaryKeybindings.hasAlt(this.value); - } - - public hasWinCtrl(): boolean { - return BinaryKeybindings.hasWinCtrl(this.value); - } - - public isModifierKey(): boolean { - return BinaryKeybindings.isModifierKey(this.value); - } - - public getKeyCode(): KeyCode { - return BinaryKeybindings.extractKeyCode(this.value); - } -} - -export class ChordKeybinding { - public readonly value: number; - - constructor(keybinding: number) { - this.value = keybinding; - } - - public isChord(): this is ChordKeybinding { - return true; - } - - public equals(other: Keybinding): boolean { - return (other && this.value === other.value); - } - - public extractFirstPart(): SimpleKeybinding { - return new SimpleKeybinding(BinaryKeybindings.extractFirstPart(this.value)); - } - - public extractChordPart(): SimpleKeybinding { - return new SimpleKeybinding(BinaryKeybindings.extractChordPart(this.value)); - } -} - -export type Keybinding = SimpleKeybinding | ChordKeybinding; - -export function _createRuntimeKeybinding(keybinding: Keybinding, OS: OperatingSystem): RuntimeKeybinding { - if (keybinding.isChord()) { - return new ChordRuntimeKeybinding( - _createSimpleRuntimeKeybinding(keybinding.extractFirstPart(), OS), - _createSimpleRuntimeKeybinding(keybinding.extractChordPart(), OS), - ); - } - return _createSimpleRuntimeKeybinding(keybinding, OS); -} - -function _createSimpleRuntimeKeybinding(keybinding: SimpleKeybinding, OS: OperatingSystem): SimpleRuntimeKeybinding { - const ctrlCmd = keybinding.hasCtrlCmd(); - const winCtrl = keybinding.hasWinCtrl(); - const ctrlKey = (OS === OperatingSystem.Macintosh ? winCtrl : ctrlCmd); - const metaKey = (OS === OperatingSystem.Macintosh ? ctrlCmd : winCtrl); - - const shiftKey = keybinding.hasShift(); - const altKey = keybinding.hasAlt(); - - const keyCode = keybinding.getKeyCode(); - - return new SimpleRuntimeKeybinding(ctrlKey, shiftKey, altKey, metaKey, keyCode); -} - export function createRuntimeKeybinding(keybinding: number, OS: OperatingSystem): RuntimeKeybinding { if (keybinding === 0) { return null; @@ -605,7 +502,7 @@ export function createRuntimeKeybinding(keybinding: number, OS: OperatingSystem) return createSimpleRuntimeKeybinding(keybinding, OS); } -function createSimpleRuntimeKeybinding(keybinding: number, OS: OperatingSystem): SimpleRuntimeKeybinding { +export function createSimpleRuntimeKeybinding(keybinding: number, OS: OperatingSystem): SimpleRuntimeKeybinding { const ctrlCmd = BinaryKeybindings.hasCtrlCmd(keybinding); const winCtrl = BinaryKeybindings.hasWinCtrl(keybinding); @@ -641,6 +538,29 @@ export class SimpleRuntimeKeybinding { this.metaKey = metaKey; this.keyCode = keyCode; } + + public equals(other: RuntimeKeybinding): boolean { + if (other.type !== RuntimeKeybindingType.Simple) { + return false; + } + return ( + this.ctrlKey === other.ctrlKey + && this.shiftKey === other.shiftKey + && this.altKey === other.altKey + && this.metaKey === other.metaKey + && this.keyCode === other.keyCode + ); + } + + public isModifierKey(): boolean { + return ( + this.keyCode === KeyCode.Unknown + || this.keyCode === KeyCode.Ctrl + || this.keyCode === KeyCode.Meta + || this.keyCode === KeyCode.Alt + || this.keyCode === KeyCode.Shift + ); + } } export class ChordRuntimeKeybinding { diff --git a/src/vs/base/parts/tree/browser/treeDefaults.ts b/src/vs/base/parts/tree/browser/treeDefaults.ts index 8bf859e3b5d..f44f4043ca2 100644 --- a/src/vs/base/parts/tree/browser/treeDefaults.ts +++ b/src/vs/base/parts/tree/browser/treeDefaults.ts @@ -14,7 +14,7 @@ import dom = require('vs/base/browser/dom'); import mouse = require('vs/base/browser/mouseEvent'); import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import _ = require('vs/base/parts/tree/browser/tree'); -import { Keybinding, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { KeyCode, KeyMod, RuntimeKeybinding, createRuntimeKeybinding, SimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; export interface ILegacyTemplateData { root: HTMLElement; @@ -97,7 +97,7 @@ export interface IControllerOptions { } interface IKeybindingDispatcherItem { - keybinding: number; + keybinding: RuntimeKeybinding; callback: IKeyBindingCallback; } @@ -111,16 +111,16 @@ export class KeybindingDispatcher { public set(keybinding: number, callback: IKeyBindingCallback) { this._arr.push({ - keybinding: keybinding, + keybinding: createRuntimeKeybinding(keybinding, platform.OS), callback: callback }); } - public dispatch(keybinding: Keybinding): IKeyBindingCallback { + public dispatch(keybinding: SimpleRuntimeKeybinding): IKeyBindingCallback { // Loop from the last to the first to handle overwrites for (let i = this._arr.length - 1; i >= 0; i--) { let item = this._arr[i]; - if (keybinding.value === item.keybinding) { + if (keybinding.equals(item.keybinding)) { return item.callback; } } @@ -264,7 +264,7 @@ export class DefaultController implements _.IController { } private onKey(bindings: KeybindingDispatcher, tree: _.ITree, event: IKeyboardEvent): boolean { - var handler = bindings.dispatch(event.toKeybinding()); + var handler = bindings.dispatch(event.toRuntimeKeybinding()); if (handler) { if (handler(tree, event)) { event.preventDefault(); diff --git a/src/vs/base/test/common/keyCodes.test.ts b/src/vs/base/test/common/keyCodes.test.ts index 733bab68eee..82011e16af8 100644 --- a/src/vs/base/test/common/keyCodes.test.ts +++ b/src/vs/base/test/common/keyCodes.test.ts @@ -5,74 +5,96 @@ 'use strict'; import * as assert from 'assert'; -import { KeyCode, KeyMod, KeyChord, createKeybinding, SimpleKeybinding } from 'vs/base/common/keyCodes'; - -interface ITestKeybinding { - ctrlCmd: boolean; - shift: boolean; - alt: boolean; - winCtrl: boolean; - key: KeyCode; - chord?: ITestKeybinding; -} - -function decodeSimpleKeybinding(kb: SimpleKeybinding): ITestKeybinding { - return { - ctrlCmd: kb.hasCtrlCmd(), - shift: kb.hasShift(), - alt: kb.hasAlt(), - winCtrl: kb.hasWinCtrl(), - key: kb.getKeyCode() - }; -} - -function decodeBinaryKeybinding(k: number): ITestKeybinding { - let kb = createKeybinding(k); - if (kb.isChord()) { - let result = decodeSimpleKeybinding(kb.extractFirstPart()); - result.chord = decodeSimpleKeybinding(kb.extractChordPart()); - return result; - } - return decodeSimpleKeybinding(kb); -} +import { KeyCode, KeyMod, KeyChord, RuntimeKeybinding, createRuntimeKeybinding, SimpleRuntimeKeybinding, ChordRuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { OperatingSystem } from 'vs/base/common/platform'; suite('keyCodes', () => { - test('binary encoding', () => { - function test(keybinding: ITestKeybinding, k: number): void { - keybinding = keybinding || { ctrlCmd: false, shift: false, alt: false, winCtrl: false, key: KeyCode.Unknown }; - assert.deepEqual(decodeBinaryKeybinding(k), keybinding); + function testBinaryEncoding(expected: RuntimeKeybinding, k: number, OS: OperatingSystem): void { + assert.deepEqual(createRuntimeKeybinding(k, OS), expected); + } + + test('MAC binary encoding', () => { + + function test(expected: RuntimeKeybinding, k: number): void { + testBinaryEncoding(expected, k, OperatingSystem.Macintosh); } test(null, 0); - test({ ctrlCmd: false, shift: false, alt: false, winCtrl: false, key: KeyCode.Enter }, KeyCode.Enter); - test({ ctrlCmd: false, shift: false, alt: false, winCtrl: false, key: KeyCode.Enter, chord: { ctrlCmd: false, shift: false, alt: false, winCtrl: false, key: KeyCode.Tab } }, KeyChord(KeyCode.Enter, KeyCode.Tab)); - test({ ctrlCmd: false, shift: false, alt: false, winCtrl: false, key: KeyCode.Enter }, KeyCode.Enter); - test({ ctrlCmd: false, shift: false, alt: false, winCtrl: true, key: KeyCode.Enter }, KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: false, shift: false, alt: true, winCtrl: false, key: KeyCode.Enter }, KeyMod.Alt | KeyCode.Enter); - test({ ctrlCmd: false, shift: false, alt: true, winCtrl: true, key: KeyCode.Enter }, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: false, shift: true, alt: false, winCtrl: false, key: KeyCode.Enter }, KeyMod.Shift | KeyCode.Enter); - test({ ctrlCmd: false, shift: true, alt: false, winCtrl: true, key: KeyCode.Enter }, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: false, shift: true, alt: true, winCtrl: false, key: KeyCode.Enter }, KeyMod.Shift | KeyMod.Alt | KeyCode.Enter); - test({ ctrlCmd: false, shift: true, alt: true, winCtrl: true, key: KeyCode.Enter }, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: true, shift: false, alt: false, winCtrl: false, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyCode.Enter); - test({ ctrlCmd: true, shift: false, alt: false, winCtrl: true, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: true, shift: false, alt: true, winCtrl: false, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter); - test({ ctrlCmd: true, shift: false, alt: true, winCtrl: true, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: true, shift: true, alt: false, winCtrl: false, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter); - test({ ctrlCmd: true, shift: true, alt: false, winCtrl: true, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter); - test({ ctrlCmd: true, shift: true, alt: true, winCtrl: false, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter); - test({ ctrlCmd: true, shift: true, alt: true, winCtrl: true, key: KeyCode.Enter }, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); - let encoded = KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z); - let kb = createKeybinding(encoded); + test( + new ChordRuntimeKeybinding( + new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.Enter), + new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.Tab) + ), + KeyChord(KeyCode.Enter, KeyCode.Tab) + ); + test( + new ChordRuntimeKeybinding( + new SimpleRuntimeKeybinding(false, false, false, true, KeyCode.KEY_Y), + new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.KEY_Z) + ), + KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z) + ); + }); - assert.equal(kb.isChord(), true, 'isCord'); - if (kb.isChord()) { - let firstPart = kb.extractFirstPart(); - let chordPart = kb.extractChordPart(); - assert.equal(firstPart.value, KeyMod.CtrlCmd | KeyCode.KEY_Y, 'first part'); - assert.equal(chordPart.value, KeyCode.KEY_Z, 'chord part'); - } + test('WINDOWS & LINUX binary encoding', () => { + + [OperatingSystem.Linux, OperatingSystem.Windows].forEach((OS) => { + + function test(expected: RuntimeKeybinding, k: number): void { + testBinaryEncoding(expected, k, OS); + } + + test(null, 0); + test(new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter); + test(new SimpleRuntimeKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter); + + test( + new ChordRuntimeKeybinding( + new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.Enter), + new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.Tab) + ), + KeyChord(KeyCode.Enter, KeyCode.Tab) + ); + test( + new ChordRuntimeKeybinding( + new SimpleRuntimeKeybinding(true, false, false, false, KeyCode.KEY_Y), + new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.KEY_Z) + ), + KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z) + ); + + }); }); }); diff --git a/src/vs/editor/browser/standalone/simpleServices.ts b/src/vs/editor/browser/standalone/simpleServices.ts index e840c17663f..faf903579c1 100644 --- a/src/vs/editor/browser/standalone/simpleServices.ts +++ b/src/vs/editor/browser/standalone/simpleServices.ts @@ -323,7 +323,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService { this.toDispose.push(dom.addDisposableListener(domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => { let keyEvent = new StandardKeyboardEvent(e); - let shouldPreventDefault = this._dispatch(keyEvent.toKeybinding(), keyEvent.target); + let shouldPreventDefault = this._dispatch(keyEvent.toRuntimeKeybinding(), keyEvent.target); if (shouldPreventDefault) { keyEvent.preventDefault(); } diff --git a/src/vs/editor/common/standalone/standaloneBase.ts b/src/vs/editor/common/standalone/standaloneBase.ts index 36311b9242e..c283f982261 100644 --- a/src/vs/editor/common/standalone/standaloneBase.ts +++ b/src/vs/editor/common/standalone/standaloneBase.ts @@ -5,7 +5,7 @@ 'use strict'; import { Emitter } from 'vs/base/common/event'; -import { SimpleKeybinding, KeyMod as ConstKeyMod, KeyChord } from 'vs/base/common/keyCodes'; +import { KeyMod as ConstKeyMod, KeyChord } from 'vs/base/common/keyCodes'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { Selection, SelectionDirection } from 'vs/editor/common/core/selection'; @@ -224,7 +224,6 @@ export function createMonacoBaseAPI(): typeof monaco { Emitter: Emitter, KeyCode: KeyCode, KeyMod: KeyMod, - SimpleKeybinding: SimpleKeybinding, Position: Position, Range: Range, Selection: Selection, diff --git a/src/vs/editor/contrib/find/browser/findWidget.ts b/src/vs/editor/contrib/find/browser/findWidget.ts index 7eea9113239..5dc01c2872b 100644 --- a/src/vs/editor/contrib/find/browser/findWidget.ts +++ b/src/vs/editor/contrib/find/browser/findWidget.ts @@ -364,60 +364,65 @@ export class FindWidget extends Widget implements IOverlayWidget { private _onFindInputKeyDown(e: IKeyboardEvent): void { - switch (e.toKeybinding().value) { - case KeyCode.Enter: - this._codeEditor.getAction(FIND_IDS.NextMatchFindAction).run().done(null, onUnexpectedError); - e.preventDefault(); - return; + if (e.equals(KeyCode.Enter)) { + this._codeEditor.getAction(FIND_IDS.NextMatchFindAction).run().done(null, onUnexpectedError); + e.preventDefault(); + return; + } - case KeyMod.Shift | KeyCode.Enter: - this._codeEditor.getAction(FIND_IDS.PreviousMatchFindAction).run().done(null, onUnexpectedError); - e.preventDefault(); - return; + if (e.equals(KeyMod.Shift | KeyCode.Enter)) { + this._codeEditor.getAction(FIND_IDS.PreviousMatchFindAction).run().done(null, onUnexpectedError); + e.preventDefault(); + return; + } - case KeyCode.Tab: - if (this._isReplaceVisible) { - this._replaceInputBox.focus(); - } else { - this._findInput.focusOnCaseSensitive(); - } - e.preventDefault(); - return; + if (e.equals(KeyCode.Tab)) { + if (this._isReplaceVisible) { + this._replaceInputBox.focus(); + } else { + this._findInput.focusOnCaseSensitive(); + } + e.preventDefault(); + return; + } - case KeyMod.CtrlCmd | KeyCode.DownArrow: - this._codeEditor.focus(); - e.preventDefault(); - return; + if (e.equals(KeyMod.CtrlCmd | KeyCode.DownArrow)) { + this._codeEditor.focus(); + e.preventDefault(); + return; } } private _onReplaceInputKeyDown(e: IKeyboardEvent): void { - switch (e.toKeybinding().value) { - case KeyCode.Enter: - this._controller.replace(); - e.preventDefault(); - return; + if (e.equals(KeyCode.Enter)) { + this._controller.replace(); + e.preventDefault(); + return; + } - case KeyMod.CtrlCmd | KeyCode.Enter: - this._controller.replaceAll(); - e.preventDefault(); - return; + if (e.equals(KeyMod.CtrlCmd | KeyCode.Enter)) { + this._controller.replaceAll(); + e.preventDefault(); + return; + } - case KeyCode.Tab: - this._findInput.focusOnCaseSensitive(); - e.preventDefault(); - return; + if (e.equals(KeyCode.Tab)) { + this._findInput.focusOnCaseSensitive(); + e.preventDefault(); + return; + } - case KeyMod.Shift | KeyCode.Tab: - this._findInput.focus(); - e.preventDefault(); - return; + if (e.equals(KeyMod.Shift | KeyCode.Tab)) { + this._findInput.focus(); + e.preventDefault(); + return; + } - case KeyMod.CtrlCmd | KeyCode.DownArrow: - this._codeEditor.focus(); - e.preventDefault(); - return; + if (e.equals(KeyMod.CtrlCmd | KeyCode.DownArrow)) { + this._codeEditor.focus(); + e.preventDefault(); + return; } } diff --git a/src/vs/editor/test/browser/standalone/simpleServices.test.ts b/src/vs/editor/test/browser/standalone/simpleServices.test.ts index cbbd37c492e..68e4ac25b9b 100644 --- a/src/vs/editor/test/browser/standalone/simpleServices.test.ts +++ b/src/vs/editor/test/browser/standalone/simpleServices.test.ts @@ -9,14 +9,14 @@ import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyServ import { SimpleConfigurationService, SimpleMessageService, StandaloneKeybindingService, StandaloneCommandService } from 'vs/editor/browser/standalone/simpleServices'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes'; +import { KeyCode, SimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; suite('StandaloneKeybindingService', () => { class TestStandaloneKeybindingService extends StandaloneKeybindingService { public dispatch(e: IKeyboardEvent): void { - let shouldPreventDefault = super._dispatch(e.toKeybinding(), e.target); + let shouldPreventDefault = super._dispatch(e.toRuntimeKeybinding(), e.target); if (shouldPreventDefault) { e.preventDefault(); } @@ -46,7 +46,7 @@ suite('StandaloneKeybindingService', () => { }, null); keybindingService.dispatch({ - toKeybinding: () => new SimpleKeybinding(KeyCode.F9), + toRuntimeKeybinding: () => new SimpleRuntimeKeybinding(false, false, false, false, KeyCode.F9), preventDefault: () => { } }); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index faf8b9aebe1..f28572e45dd 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -362,17 +362,6 @@ declare module monaco { static readonly WinCtrl: number; static chord(firstPart: number, secondPart: number): number; } - - export class SimpleKeybinding { - readonly value: number; - constructor(keybinding: number); - hasCtrlCmd(): boolean; - hasShift(): boolean; - hasAlt(): boolean; - hasWinCtrl(): boolean; - isModifierKey(): boolean; - getKeyCode(): KeyCode; - } /** * MarkedString can be used to render human readable text. It is either a markdown string * or a code-block that provides a language and a code snippet. Note that @@ -391,7 +380,6 @@ declare module monaco { readonly altKey: boolean; readonly metaKey: boolean; readonly keyCode: KeyCode; - toKeybinding(): SimpleKeybinding; equals(keybinding: number): boolean; preventDefault(): void; stopPropagation(): void; diff --git a/src/vs/platform/keybinding/common/abstractKeybindingService.ts b/src/vs/platform/keybinding/common/abstractKeybindingService.ts index 73986a89e78..3dbdf545f09 100644 --- a/src/vs/platform/keybinding/common/abstractKeybindingService.ts +++ b/src/vs/platform/keybinding/common/abstractKeybindingService.ts @@ -5,7 +5,7 @@ 'use strict'; import * as nls from 'vs/nls'; -import { ResolvedKeybinding, SimpleKeybinding, Keybinding, RuntimeKeybinding, _createRuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, RuntimeKeybinding, SimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import Severity from 'vs/base/common/severity'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -15,7 +15,6 @@ import { IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contex import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; import { IMessageService } from 'vs/platform/message/common/message'; import Event, { Emitter } from 'vs/base/common/event'; -import { OS } from 'vs/base/common/platform'; interface CurrentChord { keypress: string; @@ -64,8 +63,8 @@ export abstract class AbstractKeybindingService implements IKeybindingService { return this._onDidUpdateKeybindings ? this._onDidUpdateKeybindings.event : Event.None; // Sinon stubbing walks properties on prototype } - public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding { - return this._createResolvedKeybinding(_createRuntimeKeybinding(keybinding, OS)); + public resolveKeybinding(keybinding: RuntimeKeybinding): ResolvedKeybinding { + return this._createResolvedKeybinding(keybinding); } public getDefaultKeybindings(): string { @@ -97,20 +96,20 @@ export abstract class AbstractKeybindingService implements IKeybindingService { return result.resolvedKeybinding; } - public resolve(keybinding: SimpleKeybinding, target: IContextKeyServiceTarget): IResolveResult { + public resolve(keybinding: SimpleRuntimeKeybinding, target: IContextKeyServiceTarget): IResolveResult { if (keybinding.isModifierKey()) { return null; } const contextValue = this._contextKeyService.getContextValue(target); const currentChord = this._currentChord ? this._currentChord.keypress : null; - const resolvedKeybinding = this._createResolvedKeybinding(_createRuntimeKeybinding(keybinding, OS)); + const resolvedKeybinding = this._createResolvedKeybinding(keybinding); const [firstPart,] = resolvedKeybinding.getDispatchParts(); // We know for a fact the chordPart is null since we're using a single keypress return this._getResolver().resolve(contextValue, currentChord, firstPart); } - protected _dispatch(keybinding: SimpleKeybinding, target: IContextKeyServiceTarget): boolean { + protected _dispatch(keybinding: SimpleRuntimeKeybinding, target: IContextKeyServiceTarget): boolean { // Check modifier key here and cancel early, it's also checked in resolve as the function // is used externally. let shouldPreventDefault = false; @@ -120,7 +119,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService { const contextValue = this._contextKeyService.getContextValue(target); const currentChord = this._currentChord ? this._currentChord.keypress : null; - const resolvedKeybinding = this._createResolvedKeybinding(_createRuntimeKeybinding(keybinding, OS)); + const resolvedKeybinding = this._createResolvedKeybinding(keybinding); const [firstPart,] = resolvedKeybinding.getDispatchParts(); const keypressLabel = resolvedKeybinding.getLabel(); const resolveResult = this._getResolver().resolve(contextValue, currentChord, firstPart); diff --git a/src/vs/platform/keybinding/common/keybinding.ts b/src/vs/platform/keybinding/common/keybinding.ts index a3e455165e9..b01f191bb5c 100644 --- a/src/vs/platform/keybinding/common/keybinding.ts +++ b/src/vs/platform/keybinding/common/keybinding.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ResolvedKeybinding, SimpleKeybinding, Keybinding, RuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, RuntimeKeybinding, SimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ContextKeyExpr, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey'; import { IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver'; @@ -67,7 +67,7 @@ export interface IKeybindingService { onDidUpdateKeybindings: Event; - resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding; + resolveKeybinding(keybinding: RuntimeKeybinding): ResolvedKeybinding; getDefaultKeybindings(): string; @@ -87,6 +87,6 @@ export interface IKeybindingService { customKeybindingsCount(): number; - resolve(keybinding: SimpleKeybinding, target: IContextKeyServiceTarget): IResolveResult; + resolve(keybinding: SimpleRuntimeKeybinding, target: IContextKeyServiceTarget): IResolveResult; } diff --git a/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts b/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts index 1b865faef68..79234978b3c 100644 --- a/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts +++ b/src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { ResolvedKeybinding, SimpleKeybinding, KeyCode, KeyMod, KeyChord, RuntimeKeybinding, createRuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, KeyCode, KeyMod, KeyChord, RuntimeKeybinding, createRuntimeKeybinding, createSimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -43,8 +43,8 @@ suite('AbstractKeybindingService', () => { return new USLayoutResolvedKeybinding(kb, OS); } - public dispatch(keybinding: SimpleKeybinding): boolean { - return this._dispatch(keybinding, null); + public dispatch(keybinding: number): boolean { + return this._dispatch(createSimpleRuntimeKeybinding(keybinding, OS), null); } } @@ -153,7 +153,7 @@ suite('AbstractKeybindingService', () => { ]); // send Ctrl/Cmd + K - let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K)); + let shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_K); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, []); assert.deepEqual(showMessageCalls, []); @@ -167,7 +167,7 @@ suite('AbstractKeybindingService', () => { statusMessageCallsDisposed = []; // send backspace - shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyCode.Backspace)); + shouldPreventDefault = kbService.dispatch(KeyCode.Backspace); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, []); assert.deepEqual(showMessageCalls, []); @@ -183,7 +183,7 @@ suite('AbstractKeybindingService', () => { statusMessageCallsDisposed = []; // send backspace - shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyCode.Backspace)); + shouldPreventDefault = kbService.dispatch(KeyCode.Backspace); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, [{ commandId: 'simpleCommand', @@ -215,7 +215,7 @@ suite('AbstractKeybindingService', () => { ]); function assertIsIgnored(keybinding: number): void { - let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(keybinding)); + let shouldPreventDefault = kbService.dispatch(keybinding); assert.equal(shouldPreventDefault, false); assert.deepEqual(executeCommandCalls, []); assert.deepEqual(showMessageCalls, []); @@ -252,7 +252,7 @@ suite('AbstractKeybindingService', () => { currentContextValue = { key1: true }; - let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K)); + let shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_K); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, [{ commandId: 'simpleCommand', @@ -268,7 +268,7 @@ suite('AbstractKeybindingService', () => { // send Ctrl/Cmd + K currentContextValue = {}; - shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K)); + shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_K); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, []); assert.deepEqual(showMessageCalls, []); @@ -283,7 +283,7 @@ suite('AbstractKeybindingService', () => { // send Ctrl/Cmd + X currentContextValue = {}; - shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_X)); + shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_X); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, [{ commandId: 'chordCommand', @@ -312,7 +312,7 @@ suite('AbstractKeybindingService', () => { // send Ctrl/Cmd + K currentContextValue = {}; - let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K)); + let shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_K); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, [{ commandId: 'simpleCommand', @@ -330,7 +330,7 @@ suite('AbstractKeybindingService', () => { currentContextValue = { key1: true }; - shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K)); + shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_K); assert.equal(shouldPreventDefault, true); assert.deepEqual(executeCommandCalls, [{ commandId: 'simpleCommand', @@ -348,7 +348,7 @@ suite('AbstractKeybindingService', () => { currentContextValue = { key1: true }; - shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_X)); + shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_X); assert.equal(shouldPreventDefault, false); assert.deepEqual(executeCommandCalls, []); assert.deepEqual(showMessageCalls, []); @@ -370,7 +370,7 @@ suite('AbstractKeybindingService', () => { // send Ctrl/Cmd + K currentContextValue = {}; - let shouldPreventDefault = kbService.dispatch(new SimpleKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K)); + let shouldPreventDefault = kbService.dispatch(KeyMod.CtrlCmd | KeyCode.KEY_K); assert.equal(shouldPreventDefault, false); assert.deepEqual(executeCommandCalls, [{ commandId: 'simpleCommand', diff --git a/src/vs/platform/keybinding/test/common/mockKeybindingService.ts b/src/vs/platform/keybinding/test/common/mockKeybindingService.ts index e2ae9b11382..55751e26077 100644 --- a/src/vs/platform/keybinding/test/common/mockKeybindingService.ts +++ b/src/vs/platform/keybinding/test/common/mockKeybindingService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { ResolvedKeybinding, Keybinding, _createRuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, RuntimeKeybinding, SimpleRuntimeKeybinding } from 'vs/base/common/keyCodes'; import Event from 'vs/base/common/event'; import { IKeybindingService, IKeybindingEvent, IKeybindingItem2 } from 'vs/platform/keybinding/common/keybinding'; import { IContextKey, IContextKeyService, IContextKeyServiceTarget, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; @@ -76,8 +76,8 @@ export class MockKeybindingService2 implements IKeybindingService { return []; } - public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding { - return new USLayoutResolvedKeybinding(_createRuntimeKeybinding(keybinding, OS), OS); + public resolveKeybinding(keybinding: RuntimeKeybinding): ResolvedKeybinding { + return new USLayoutResolvedKeybinding(keybinding, OS); } public lookupKeybindings(commandId: string): ResolvedKeybinding[] { @@ -92,7 +92,7 @@ export class MockKeybindingService2 implements IKeybindingService { return 0; } - public resolve(keybinding: Keybinding, target: IContextKeyServiceTarget): IResolveResult { + public resolve(keybinding: SimpleRuntimeKeybinding, target: IContextKeyServiceTarget): IResolveResult { return null; } } diff --git a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts index 9aad08f8691..397ca300e8a 100644 --- a/src/vs/workbench/parts/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/parts/extensions/browser/extensionEditor.ts @@ -36,7 +36,7 @@ import { EditorOptions } from 'vs/workbench/common/editor'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { CombinedInstallAction, UpdateAction, EnableAction, DisableAction, BuiltinStatusLabelAction, ReloadAction } from 'vs/workbench/parts/extensions/browser/extensionsActions'; import WebView from 'vs/workbench/parts/html/browser/webview'; -import { createKeybinding } from 'vs/base/common/keyCodes'; +import { createRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; @@ -668,7 +668,7 @@ export class ExtensionEditor extends BaseEditor { case 'darwin': key = rawKeyBinding.mac; break; } - const keyBinding = createKeybinding(KeybindingIO.readKeybinding(key || rawKeyBinding.key, OS)); + const keyBinding = createRuntimeKeybinding(KeybindingIO.readKeybinding(key || rawKeyBinding.key, OS), OS); const resolvedKeybinding = this.keybindingService.resolveKeybinding(keyBinding); const result = resolvedKeybinding.getLabel(); return result === 'unknown' ? null : result; diff --git a/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts b/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts index 6318a2b3af1..9aa2f4ddad8 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingWidgets.ts @@ -46,19 +46,19 @@ class KeybindingInputWidget extends Widget { private onKeyDown(keyboardEvent: IKeyboardEvent): void { keyboardEvent.preventDefault(); keyboardEvent.stopPropagation(); - switch (keyboardEvent.toKeybinding().value) { - case KeyCode.Enter: - this._onEnter.fire(); - return; - case KeyCode.Escape: - this._onEscape.fire(); - return; + if (keyboardEvent.equals(KeyCode.Enter)) { + this._onEnter.fire(); + return; + } + if (keyboardEvent.equals(KeyCode.Escape)) { + this._onEscape.fire(); + return; } this.printKeybinding(keyboardEvent); } private printKeybinding(keyboardEvent: IKeyboardEvent): void { - const keybinding = this.keybindingService.resolveKeybinding(keyboardEvent.toKeybinding()); + const keybinding = this.keybindingService.resolveKeybinding(keyboardEvent.toRuntimeKeybinding()); this.inputBox.value = keybinding.getUserSettingsLabel().toLowerCase(); this.inputBox.inputElement.title = 'keyCode: ' + keyboardEvent.browserEvent.keyCode; this._onKeybinding.fire(keybinding); diff --git a/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts b/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts index c918f284e6c..f0e36956c3c 100644 --- a/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts +++ b/src/vs/workbench/parts/preferences/browser/keybindingsEditorContribution.ts @@ -9,7 +9,7 @@ import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; import { RunOnceScheduler } from 'vs/base/common/async'; import { MarkedString } from 'vs/base/common/htmlContent'; -import { createKeybinding, KeyCode, KeyMod, KeyChord, _createRuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { KeyCode, KeyMod, KeyChord, createRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; @@ -167,13 +167,11 @@ export class DefineKeybindingController implements editorCommon.IEditorContribut let numKeybinding = KeybindingIO.readKeybinding(strKeybinding, OS); - let keybinding = createKeybinding(numKeybinding); + let keybinding = createRuntimeKeybinding(numKeybinding, OS); let resolvedKeybinding = this._keybindingService.resolveKeybinding(keybinding); - const usResolvedKeybinding = new USLayoutResolvedKeybinding(_createRuntimeKeybinding(keybinding, OS), OS); + const usResolvedKeybinding = new USLayoutResolvedKeybinding(keybinding, OS); return { - strKeybinding: strKeybinding, - keybinding: keybinding, usLabel: usResolvedKeybinding.getLabel(), label: resolvedKeybinding.getLabel(), range: range diff --git a/src/vs/workbench/parts/search/browser/searchActions.ts b/src/vs/workbench/parts/search/browser/searchActions.ts index 91a538c654f..1c344531197 100644 --- a/src/vs/workbench/parts/search/browser/searchActions.ts +++ b/src/vs/workbench/parts/search/browser/searchActions.ts @@ -22,7 +22,7 @@ import { CollapseAllAction as TreeCollapseAction } from 'vs/base/parts/tree/brow import { IPreferencesService } from 'vs/workbench/parts/preferences/common/preferences'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { createKeybinding, ResolvedKeybinding, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { ResolvedKeybinding, KeyCode, KeyMod, createRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { toResource } from 'vs/workbench/common/editor'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -30,6 +30,7 @@ import { IListService } from 'vs/platform/list/browser/listService'; import { explorerItemToFileResource } from 'vs/workbench/parts/files/common/files'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { isEqual } from 'vs/platform/files/common/files'; +import { OS } from 'vs/base/common/platform'; export function isSearchViewletFocussed(viewletService: IViewletService): boolean { let activeViewlet = viewletService.getActiveViewlet(); @@ -40,7 +41,7 @@ export function isSearchViewletFocussed(viewletService: IViewletService): boolea export function appendKeyBindingLabel(label: string, keyBinding: number | ResolvedKeybinding, keyBindingService2: IKeybindingService): string { let resolvedKb: ResolvedKeybinding; if (typeof keyBinding === 'number') { - resolvedKb = keyBindingService2.resolveKeybinding(createKeybinding(keyBinding)); + resolvedKb = keyBindingService2.resolveKeybinding(createRuntimeKeybinding(keyBinding, OS)); } else { resolvedKb = keyBinding; } diff --git a/src/vs/workbench/parts/search/test/browser/searchActions.test.ts b/src/vs/workbench/parts/search/test/browser/searchActions.test.ts index c698ed4699e..ef7de8e70e6 100644 --- a/src/vs/workbench/parts/search/test/browser/searchActions.test.ts +++ b/src/vs/workbench/parts/search/test/browser/searchActions.test.ts @@ -19,6 +19,7 @@ import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding'; import { OS } from 'vs/base/common/platform'; +import { RuntimeKeybinding } from "vs/base/common/keyCodes"; suite('Search Actions', () => { @@ -29,7 +30,7 @@ suite('Search Actions', () => { instantiationService = new TestInstantiationService(); instantiationService.stub(IModelService, stubModelService(instantiationService)); instantiationService.stub(IKeybindingService, {}); - instantiationService.stub(IKeybindingService, 'resolveKeybinding', (keybinding) => new USLayoutResolvedKeybinding(keybinding, OS)); + instantiationService.stub(IKeybindingService, 'resolveKeybinding', (keybinding: RuntimeKeybinding) => new USLayoutResolvedKeybinding(keybinding, OS)); counter = 0; }); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts index 439ed34f5b4..b33ed71ab2f 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalInstance.ts @@ -227,7 +227,7 @@ export class TerminalInstance implements ITerminalInstance { // Skip processing by xterm.js of keyboard events that resolve to commands described // within commandsToSkipShell const standardKeyboardEvent = new StandardKeyboardEvent(event); - const keybinding = standardKeyboardEvent.toKeybinding(); + const keybinding = standardKeyboardEvent.toRuntimeKeybinding(); const resolveResult = this._keybindingService.resolve(keybinding, standardKeyboardEvent.target); if (resolveResult && this._skipTerminalCommands.some(k => k === resolveResult.commandId)) { event.preventDefault(); diff --git a/src/vs/workbench/parts/update/electron-browser/update.ts b/src/vs/workbench/parts/update/electron-browser/update.ts index 8cc6f3e1cf2..de2b5197ea7 100644 --- a/src/vs/workbench/parts/update/electron-browser/update.ts +++ b/src/vs/workbench/parts/update/electron-browser/update.ts @@ -19,7 +19,7 @@ import { ReleaseNotesInput } from 'vs/workbench/parts/update/electron-browser/re import { IRequestService } from 'vs/platform/request/node/request'; import { asText } from 'vs/base/node/request'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { createKeybinding } from 'vs/base/common/keyCodes'; +import { createRuntimeKeybinding } from 'vs/base/common/keyCodes'; import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; @@ -80,7 +80,7 @@ export function loadReleaseNotes(accessor: ServicesAccessor, version: string): T return unassigned; } - const keybinding = createKeybinding(code); + const keybinding = createRuntimeKeybinding(code, OS); if (!keybinding) { return unassigned; diff --git a/src/vs/workbench/services/keybinding/common/keyboardMapper.ts b/src/vs/workbench/services/keybinding/common/keyboardMapper.ts index c41424fb048..1014cebb1c0 100644 --- a/src/vs/workbench/services/keybinding/common/keyboardMapper.ts +++ b/src/vs/workbench/services/keybinding/common/keyboardMapper.ts @@ -6,7 +6,7 @@ 'use strict'; import { OperatingSystem } from 'vs/base/common/platform'; -import { SimpleKeybinding, KeyCode, ResolvedKeybinding, Keybinding, KeyCodeUtils, KeyMod } from 'vs/base/common/keyCodes'; +import { KeyCode, ResolvedKeybinding, KeyCodeUtils, SimpleRuntimeKeybinding, RuntimeKeybinding, RuntimeKeybindingType } from 'vs/base/common/keyCodes'; import { KeyboardEventCode, KeyboardEventCodeUtils, IMMUTABLE_CODE_TO_KEY_CODE } from 'vs/workbench/services/keybinding/common/keyboardEventCode'; import { CharCode } from 'vs/base/common/charCode'; import { IHTMLContentElement } from 'vs/base/common/htmlContent'; @@ -444,28 +444,20 @@ export class KeyboardMapper { ); } - public simpleKeybindingToHardwareKeypress(keybinding: SimpleKeybinding): HardwareKeypress[] { - const ctrlCmd = keybinding.hasCtrlCmd(); - const winCtrl = keybinding.hasWinCtrl(); - const ctrlKey = (this._OS === OperatingSystem.Macintosh ? winCtrl : ctrlCmd); - const metaKey = (this._OS === OperatingSystem.Macintosh ? ctrlCmd : winCtrl); - const shiftKey = keybinding.hasShift(); - const altKey = keybinding.hasAlt(); - const keyCode = keybinding.getKeyCode(); - - const kbEncoded = this._encode(ctrlKey, shiftKey, altKey, keyCode); + public simpleKeybindingToHardwareKeypress(keybinding: SimpleRuntimeKeybinding): HardwareKeypress[] { + const kbEncoded = this._encode(keybinding.ctrlKey, keybinding.shiftKey, keybinding.altKey, keybinding.keyCode); const hwEncoded = this._kbToHw[kbEncoded]; let result: HardwareKeypress[] = []; if (hwEncoded) { for (let i = 0, len = hwEncoded.length; i < len; i++) { - result[i] = this._decodeHw(hwEncoded[i], metaKey); + result[i] = this._decodeHw(hwEncoded[i], keybinding.metaKey); } } return result; } - public hardwareKeypressToSimpleKeybinding(keypress: HardwareKeypress): SimpleKeybinding { + public hardwareKeypressToSimpleKeybinding(keypress: HardwareKeypress): SimpleRuntimeKeybinding { const hwEncoded = this._encode(keypress.ctrlKey, keypress.shiftKey, keypress.altKey, keypress.code); const kbEncoded = this._hwToKb[hwEncoded]; if (!kbEncoded) { @@ -495,12 +487,12 @@ export class KeyboardMapper { return this._hwToLabel[code]; } - public resolveKeybinding(keybinding: Keybinding): NativeResolvedKeybinding[] { + public resolveKeybinding(keybinding: RuntimeKeybinding): NativeResolvedKeybinding[] { let result: NativeResolvedKeybinding[] = [], resultLen = 0; - if (keybinding.isChord()) { - const firstParts = this.simpleKeybindingToHardwareKeypress(keybinding.extractFirstPart()); - const chordParts = this.simpleKeybindingToHardwareKeypress(keybinding.extractChordPart()); + if (keybinding.type === RuntimeKeybindingType.Chord) { + const firstParts = this.simpleKeybindingToHardwareKeypress(keybinding.firstPart); + const chordParts = this.simpleKeybindingToHardwareKeypress(keybinding.chordPart); for (let i = 0, len = firstParts.length; i < len; i++) { const firstPart = firstParts[i]; @@ -575,21 +567,18 @@ export class KeyboardMapper { return new HardwareKeypress(ctrlKey, shiftKey, altKey, metaKey, code); } - private _decodeKb(kbEncoded: number, metaKey: boolean): SimpleKeybinding { + private _decodeKb(kbEncoded: number, metaKey: boolean): SimpleRuntimeKeybinding { const ctrlKey = (kbEncoded & 0b001) ? true : false; const shiftKey = (kbEncoded & 0b010) ? true : false; const altKey = (kbEncoded & 0b100) ? true : false; const keyCode = (kbEncoded >>> 3); - const ctrlCmd = (this._OS === OperatingSystem.Macintosh ? metaKey : ctrlKey); - const winCtrl = (this._OS === OperatingSystem.Macintosh ? ctrlKey : metaKey); - - return new SimpleKeybinding( - (ctrlCmd ? KeyMod.CtrlCmd : 0) - | (winCtrl ? KeyMod.WinCtrl : 0) - | (shiftKey ? KeyMod.Shift : 0) - | (altKey ? KeyMod.Alt : 0) - | keyCode + return new SimpleRuntimeKeybinding( + ctrlKey, + shiftKey, + altKey, + metaKey, + keyCode ); } } diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index 266a117e3b5..f811d4fffc2 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -291,7 +291,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { this.toDispose.push(dom.addDisposableListener(windowElement, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => { let keyEvent = new StandardKeyboardEvent(e); - let shouldPreventDefault = this._dispatch(keyEvent.toKeybinding(), keyEvent.target); + let shouldPreventDefault = this._dispatch(keyEvent.toRuntimeKeybinding(), keyEvent.target); if (shouldPreventDefault) { keyEvent.preventDefault(); } diff --git a/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts index 2baf332773c..82fc92cc03f 100644 --- a/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/keyboardMapper.test.ts @@ -6,7 +6,7 @@ 'use strict'; import * as assert from 'assert'; -import { KeyMod, KeyCode, SimpleKeybinding, createKeybinding, Keybinding, _createRuntimeKeybinding, createRuntimeKeybinding } from 'vs/base/common/keyCodes'; +import { KeyMod, KeyCode, createRuntimeKeybinding, SimpleRuntimeKeybinding, RuntimeKeybinding } from 'vs/base/common/keyCodes'; import { KeyboardMapper, IKeyboardMapping } from 'vs/workbench/services/keybinding/common/keyboardMapper'; import { OperatingSystem } from 'vs/base/common/platform'; import { UserSettingsLabelProvider, PrintableKeypress } from 'vs/platform/keybinding/common/keybindingLabels'; @@ -81,7 +81,7 @@ suite('keyboardMapper - MAC de_ch', () => { }); test('resolveKeybinding', () => { - function _assertAllLabels(keybinding: Keybinding, labels: string[], ariaLabels: string[], htmlLabel: IHTMLContentElement[][]): void { + function _assertAllLabels(keybinding: RuntimeKeybinding, labels: string[], ariaLabels: string[], htmlLabel: IHTMLContentElement[][]): void { const kb = mapper.resolveKeybinding(keybinding); let actualLabels = kb.map(k => k.getLabel()); @@ -94,16 +94,15 @@ suite('keyboardMapper - MAC de_ch', () => { assert.deepEqual(actualHTMLLabels, htmlLabel); } - function assertAllLabels(keybinding: Keybinding, label: string | string[], ariaLabel: string | string[], htmlLabel: IHTMLContentElement[][]): void { + function assertAllLabels(keybinding: RuntimeKeybinding, label: string | string[], ariaLabel: string | string[], htmlLabel: IHTMLContentElement[][]): void { let _labels = (typeof label === 'string' ? [label] : label); let _ariaLabels = (typeof ariaLabel === 'string' ? [ariaLabel] : ariaLabel); _assertAllLabels(keybinding, _labels, _ariaLabels, htmlLabel); } - // TODO: ElectronAccelerator, UserSettings assertAllLabels( - createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_Z), + createRuntimeKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_Z, OperatingSystem.Macintosh), '⌘Z', 'Command+Z', [[{ @@ -179,15 +178,18 @@ function _assertKeybindingTranslation(mapper: KeyboardMapper, OS: OperatingSyste } else { expected = []; } - let keybindingLabel = new USLayoutResolvedKeybinding(createRuntimeKeybinding(kb, OS), OS).getUserSettingsLabel(); - let actualHardwareKeypresses = mapper.simpleKeybindingToHardwareKeypress(new SimpleKeybinding(kb)); + const runtimeKeybinding = createRuntimeKeybinding(kb, OS); + + const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding, OS).getUserSettingsLabel(); + + const actualHardwareKeypresses = mapper.simpleKeybindingToHardwareKeypress(runtimeKeybinding); if (actualHardwareKeypresses.length === 0) { assert.deepEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`); return; } - let actual = actualHardwareKeypresses + const actual = actualHardwareKeypresses .map(k => new PrintableKeypress(k.ctrlKey, k.shiftKey, k.altKey, k.metaKey, KeyboardEventCodeUtils.toString(k.code))) .map(kp => UserSettingsLabelProvider.toLabel2(kp, null, OS)); assert.deepEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`); @@ -201,7 +203,7 @@ function _assertKeybindingTranslation(mapper: KeyboardMapper, OS: OperatingSyste return; } - const reversedLabel = new USLayoutResolvedKeybinding(_createRuntimeKeybinding(reversed, OS), OS).getUserSettingsLabel(); + const reversedLabel = new USLayoutResolvedKeybinding(reversed, OS).getUserSettingsLabel(); assert.equal(reversedLabel, keybindingLabel, `${keybindingLabel} -> ${hardwareKeypressLabel} -> ${reversedLabel}`); }); }