Skip to content

Commit

Permalink
[keybings] properly translate to monaco keycodes (fixes #493)
Browse files Browse the repository at this point in the history
Signed-off-by: Sven Efftinge <sven.efftinge@typefox.io>
  • Loading branch information
svenefftinge committed Sep 18, 2017
1 parent 45884b2 commit d2d6324
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 146 deletions.
10 changes: 4 additions & 6 deletions packages/core/src/browser/browser.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/*
* Copyright (C) 2017 TypeFox and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : "";

Expand Down
148 changes: 9 additions & 139 deletions packages/monaco/src/browser/monaco-keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,153 +6,23 @@
*/

import { injectable, inject } from 'inversify';
import { isOSX } from '@theia/core/lib/common/os';
import { isFirefox, isIE, isWebKit } from '@theia/core/lib/browser';
import { KeybindingContribution, KeybindingRegistry } from '@theia/core/lib/common/keybinding';
import { Accelerator, Key, KeyCode, Keystroke, Modifier } from '@theia/core/lib/common/keys';
import { MonacoCommands } from './monaco-command';
import { MonacoCommandRegistry } from './monaco-command-registry';
import { KEY_CODE_MAP } from './monaco-keycode-map';
import KeybindingsRegistry = monaco.keybindings.KeybindingsRegistry;
import KeyCodeUtils = monaco.keybindings.KeyCodeUtils;

const MONACO_KEY_CODE_MAP: { [keyCode: number]: number } = {};
(() => {
MONACO_KEY_CODE_MAP[monaco.KeyCode.PauseBreak] = 3; // VK_CANCEL 0x03 Control-break processing
MONACO_KEY_CODE_MAP[monaco.KeyCode.Backspace] = 8;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Tab] = 9;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Enter] = 13;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Shift] = 16;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Ctrl] = 17;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Alt] = 18;
MONACO_KEY_CODE_MAP[monaco.KeyCode.PauseBreak] = 19;
MONACO_KEY_CODE_MAP[monaco.KeyCode.CapsLock] = 20;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Escape] = 27;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Space] = 32;
MONACO_KEY_CODE_MAP[monaco.KeyCode.PageUp] = 33;
MONACO_KEY_CODE_MAP[monaco.KeyCode.PageDown] = 34;
MONACO_KEY_CODE_MAP[monaco.KeyCode.End] = 35;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Home] = 36;
MONACO_KEY_CODE_MAP[monaco.KeyCode.LeftArrow] = 37;
MONACO_KEY_CODE_MAP[monaco.KeyCode.UpArrow] = 38;
MONACO_KEY_CODE_MAP[monaco.KeyCode.RightArrow] = 39;
MONACO_KEY_CODE_MAP[monaco.KeyCode.DownArrow] = 40;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Insert] = 45;
MONACO_KEY_CODE_MAP[monaco.KeyCode.Delete] = 46;

MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_0] = 48;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_1] = 49;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_2] = 50;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_3] = 51;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_4] = 52;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_5] = 53;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_6] = 54;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_7] = 55;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_8] = 56;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_9] = 57;

MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_A] = 65;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_B] = 66;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_C] = 67;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_D] = 68;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_E] = 69;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_F] = 70;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_G] = 71;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_H] = 72;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_I] = 73;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_J] = 74;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_K] = 75;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_L] = 76;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_M] = 77;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_N] = 78;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_O] = 79;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_P] = 80;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_Q] = 81;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_R] = 82;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_S] = 83;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_T] = 84;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_U] = 85;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_V] = 86;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_W] = 87;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_X] = 88;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_Y] = 89;
MONACO_KEY_CODE_MAP[monaco.KeyCode.KEY_Z] = 90;

MONACO_KEY_CODE_MAP[monaco.KeyCode.ContextMenu] = 93;

MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_0] = 96;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_1] = 97;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_2] = 98;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_3] = 99;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_4] = 100;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_5] = 101;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_6] = 102;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_7] = 103;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_8] = 104;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_9] = 105;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_MULTIPLY] = 106;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_ADD] = 107;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_SEPARATOR] = 108;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_SUBTRACT] = 109;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_DECIMAL] = 110;
MONACO_KEY_CODE_MAP[monaco.KeyCode.NUMPAD_DIVIDE] = 111;

MONACO_KEY_CODE_MAP[monaco.KeyCode.F1] = 112;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F2] = 113;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F3] = 114;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F4] = 115;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F5] = 116;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F6] = 117;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F7] = 118;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F8] = 119;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F9] = 120;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F10] = 121;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F11] = 122;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F12] = 123;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F13] = 124;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F14] = 125;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F15] = 126;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F16] = 127;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F17] = 128;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F18] = 129;
MONACO_KEY_CODE_MAP[monaco.KeyCode.F19] = 130;

MONACO_KEY_CODE_MAP[monaco.KeyCode.NumLock] = 144;
MONACO_KEY_CODE_MAP[monaco.KeyCode.ScrollLock] = 145;

MONACO_KEY_CODE_MAP[monaco.KeyCode.US_SEMICOLON] = 186;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_EQUAL] = 187;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_COMMA] = 188;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_MINUS] = 189;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_DOT] = 190;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_SLASH] = 191;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_BACKTICK] = 192;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_OPEN_SQUARE_BRACKET] = 219;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_BACKSLASH] = 220;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_CLOSE_SQUARE_BRACKET] = 221;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_QUOTE] = 222;
MONACO_KEY_CODE_MAP[monaco.KeyCode.OEM_8] = 223;

MONACO_KEY_CODE_MAP[monaco.KeyCode.OEM_102] = 226;

if (isIE) {
MONACO_KEY_CODE_MAP[monaco.KeyCode.Meta] = 91;
} else if (isFirefox) {
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_SEMICOLON] = 59;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_EQUAL] = 107;
MONACO_KEY_CODE_MAP[monaco.KeyCode.US_MINUS] = 109;
if (isOSX) {
MONACO_KEY_CODE_MAP[monaco.KeyCode.Meta] = 224;
}
} else if (isWebKit) {
MONACO_KEY_CODE_MAP[monaco.KeyCode.Meta] = 91;
if (isOSX) {
// the two meta keys in the Mac have different key codes (91 and 93)
MONACO_KEY_CODE_MAP[monaco.KeyCode.Meta] = 93;
} else {
MONACO_KEY_CODE_MAP[monaco.KeyCode.Meta] = 92;
function monaco2BrowserKeyCode(keyCode: monaco.KeyCode): number {
for (let i = 0; i < KEY_CODE_MAP.length; i++) {
if (KEY_CODE_MAP[i] === keyCode) {
return i;
}
}
})();
return -1;
}


@injectable()
export class MonacoKeybindingContribution implements KeybindingContribution {
Expand Down Expand Up @@ -193,7 +63,7 @@ export class MonacoKeybindingContribution implements KeybindingContribution {
protected keyCode(keybinding: monaco.keybindings.SimpleKeybinding): KeyCode {
const keyCode = keybinding.keyCode;
const sequence: Keystroke = {
first: Key.getKey(MONACO_KEY_CODE_MAP[keyCode & 255]),
first: Key.getKey(monaco2BrowserKeyCode(keyCode & 255)),
modifiers: []
};
if (keybinding.ctrlKey) {
Expand Down
155 changes: 155 additions & 0 deletions packages/monaco/src/browser/monaco-keycode-map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as browser from "@theia/core/lib/browser";

const KeyCode = monaco.KeyCode;

export let KEY_CODE_MAP: monaco.KeyCode[] = [];
(function () {
KEY_CODE_MAP[3] = KeyCode.PauseBreak; // VK_CANCEL 0x03 Control-break processing
KEY_CODE_MAP[8] = KeyCode.Backspace;
KEY_CODE_MAP[9] = KeyCode.Tab;
KEY_CODE_MAP[13] = KeyCode.Enter;
KEY_CODE_MAP[16] = KeyCode.Shift;
KEY_CODE_MAP[17] = KeyCode.Ctrl;
KEY_CODE_MAP[18] = KeyCode.Alt;
KEY_CODE_MAP[19] = KeyCode.PauseBreak;
KEY_CODE_MAP[20] = KeyCode.CapsLock;
KEY_CODE_MAP[27] = KeyCode.Escape;
KEY_CODE_MAP[32] = KeyCode.Space;
KEY_CODE_MAP[33] = KeyCode.PageUp;
KEY_CODE_MAP[34] = KeyCode.PageDown;
KEY_CODE_MAP[35] = KeyCode.End;
KEY_CODE_MAP[36] = KeyCode.Home;
KEY_CODE_MAP[37] = KeyCode.LeftArrow;
KEY_CODE_MAP[38] = KeyCode.UpArrow;
KEY_CODE_MAP[39] = KeyCode.RightArrow;
KEY_CODE_MAP[40] = KeyCode.DownArrow;
KEY_CODE_MAP[45] = KeyCode.Insert;
KEY_CODE_MAP[46] = KeyCode.Delete;

KEY_CODE_MAP[48] = KeyCode.KEY_0;
KEY_CODE_MAP[49] = KeyCode.KEY_1;
KEY_CODE_MAP[50] = KeyCode.KEY_2;
KEY_CODE_MAP[51] = KeyCode.KEY_3;
KEY_CODE_MAP[52] = KeyCode.KEY_4;
KEY_CODE_MAP[53] = KeyCode.KEY_5;
KEY_CODE_MAP[54] = KeyCode.KEY_6;
KEY_CODE_MAP[55] = KeyCode.KEY_7;
KEY_CODE_MAP[56] = KeyCode.KEY_8;
KEY_CODE_MAP[57] = KeyCode.KEY_9;

KEY_CODE_MAP[65] = KeyCode.KEY_A;
KEY_CODE_MAP[66] = KeyCode.KEY_B;
KEY_CODE_MAP[67] = KeyCode.KEY_C;
KEY_CODE_MAP[68] = KeyCode.KEY_D;
KEY_CODE_MAP[69] = KeyCode.KEY_E;
KEY_CODE_MAP[70] = KeyCode.KEY_F;
KEY_CODE_MAP[71] = KeyCode.KEY_G;
KEY_CODE_MAP[72] = KeyCode.KEY_H;
KEY_CODE_MAP[73] = KeyCode.KEY_I;
KEY_CODE_MAP[74] = KeyCode.KEY_J;
KEY_CODE_MAP[75] = KeyCode.KEY_K;
KEY_CODE_MAP[76] = KeyCode.KEY_L;
KEY_CODE_MAP[77] = KeyCode.KEY_M;
KEY_CODE_MAP[78] = KeyCode.KEY_N;
KEY_CODE_MAP[79] = KeyCode.KEY_O;
KEY_CODE_MAP[80] = KeyCode.KEY_P;
KEY_CODE_MAP[81] = KeyCode.KEY_Q;
KEY_CODE_MAP[82] = KeyCode.KEY_R;
KEY_CODE_MAP[83] = KeyCode.KEY_S;
KEY_CODE_MAP[84] = KeyCode.KEY_T;
KEY_CODE_MAP[85] = KeyCode.KEY_U;
KEY_CODE_MAP[86] = KeyCode.KEY_V;
KEY_CODE_MAP[87] = KeyCode.KEY_W;
KEY_CODE_MAP[88] = KeyCode.KEY_X;
KEY_CODE_MAP[89] = KeyCode.KEY_Y;
KEY_CODE_MAP[90] = KeyCode.KEY_Z;

KEY_CODE_MAP[93] = KeyCode.ContextMenu;

KEY_CODE_MAP[96] = KeyCode.NUMPAD_0;
KEY_CODE_MAP[97] = KeyCode.NUMPAD_1;
KEY_CODE_MAP[98] = KeyCode.NUMPAD_2;
KEY_CODE_MAP[99] = KeyCode.NUMPAD_3;
KEY_CODE_MAP[100] = KeyCode.NUMPAD_4;
KEY_CODE_MAP[101] = KeyCode.NUMPAD_5;
KEY_CODE_MAP[102] = KeyCode.NUMPAD_6;
KEY_CODE_MAP[103] = KeyCode.NUMPAD_7;
KEY_CODE_MAP[104] = KeyCode.NUMPAD_8;
KEY_CODE_MAP[105] = KeyCode.NUMPAD_9;
KEY_CODE_MAP[106] = KeyCode.NUMPAD_MULTIPLY;
KEY_CODE_MAP[107] = KeyCode.NUMPAD_ADD;
KEY_CODE_MAP[108] = KeyCode.NUMPAD_SEPARATOR;
KEY_CODE_MAP[109] = KeyCode.NUMPAD_SUBTRACT;
KEY_CODE_MAP[110] = KeyCode.NUMPAD_DECIMAL;
KEY_CODE_MAP[111] = KeyCode.NUMPAD_DIVIDE;

KEY_CODE_MAP[112] = KeyCode.F1;
KEY_CODE_MAP[113] = KeyCode.F2;
KEY_CODE_MAP[114] = KeyCode.F3;
KEY_CODE_MAP[115] = KeyCode.F4;
KEY_CODE_MAP[116] = KeyCode.F5;
KEY_CODE_MAP[117] = KeyCode.F6;
KEY_CODE_MAP[118] = KeyCode.F7;
KEY_CODE_MAP[119] = KeyCode.F8;
KEY_CODE_MAP[120] = KeyCode.F9;
KEY_CODE_MAP[121] = KeyCode.F10;
KEY_CODE_MAP[122] = KeyCode.F11;
KEY_CODE_MAP[123] = KeyCode.F12;
KEY_CODE_MAP[124] = KeyCode.F13;
KEY_CODE_MAP[125] = KeyCode.F14;
KEY_CODE_MAP[126] = KeyCode.F15;
KEY_CODE_MAP[127] = KeyCode.F16;
KEY_CODE_MAP[128] = KeyCode.F17;
KEY_CODE_MAP[129] = KeyCode.F18;
KEY_CODE_MAP[130] = KeyCode.F19;

KEY_CODE_MAP[144] = KeyCode.NumLock;
KEY_CODE_MAP[145] = KeyCode.ScrollLock;

KEY_CODE_MAP[186] = KeyCode.US_SEMICOLON;
KEY_CODE_MAP[187] = KeyCode.US_EQUAL;
KEY_CODE_MAP[188] = KeyCode.US_COMMA;
KEY_CODE_MAP[189] = KeyCode.US_MINUS;
KEY_CODE_MAP[190] = KeyCode.US_DOT;
KEY_CODE_MAP[191] = KeyCode.US_SLASH;
KEY_CODE_MAP[192] = KeyCode.US_BACKTICK;
KEY_CODE_MAP[193] = KeyCode.ABNT_C1;
KEY_CODE_MAP[194] = KeyCode.ABNT_C2;
KEY_CODE_MAP[219] = KeyCode.US_OPEN_SQUARE_BRACKET;
KEY_CODE_MAP[220] = KeyCode.US_BACKSLASH;
KEY_CODE_MAP[221] = KeyCode.US_CLOSE_SQUARE_BRACKET;
KEY_CODE_MAP[222] = KeyCode.US_QUOTE;
KEY_CODE_MAP[223] = KeyCode.OEM_8;

KEY_CODE_MAP[226] = KeyCode.OEM_102;

/**
* https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html
* If an Input Method Editor is processing key input and the event is keydown, return 229.
*/
KEY_CODE_MAP[229] = KeyCode.KEY_IN_COMPOSITION;

if (browser.isIE) {
KEY_CODE_MAP[91] = KeyCode.Meta;
} else if (browser.isFirefox) {
KEY_CODE_MAP[59] = KeyCode.US_SEMICOLON;
KEY_CODE_MAP[107] = KeyCode.US_EQUAL;
KEY_CODE_MAP[109] = KeyCode.US_MINUS;
if (monaco.platform.OS === monaco.platform.OperatingSystem.Macintosh) {
KEY_CODE_MAP[224] = KeyCode.Meta;
}
} else if (browser.isWebKit) {
KEY_CODE_MAP[91] = KeyCode.Meta;
if (monaco.platform.OS === monaco.platform.OperatingSystem.Macintosh) {
// the two meta keys in the Mac have different key codes (91 and 93)
KEY_CODE_MAP[93] = KeyCode.Meta;
} else {
KEY_CODE_MAP[92] = KeyCode.Meta;
}
}
})();
3 changes: 2 additions & 1 deletion packages/monaco/src/browser/monaco-quick-open-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { injectable } from 'inversify';
import { QuickOpenService, QuickOpenModel, QuickOpenOptions, QuickOpenItem, QuickOpenGroupItem, QuickOpenMode } from "@theia/core/lib/browser";
import { KEY_CODE_MAP } from './monaco-keycode-map';

export interface InternalMonacoQuickOpenModel extends monaco.quickOpen.IQuickOpenControllerOpts {
readonly prefix?: string;
Expand Down Expand Up @@ -202,7 +203,7 @@ export class QuickOpenEntry extends monaco.quickOpen.QuickOpenEntry {
keybinding.keyCode.shift,
keybinding.keyCode.alt,
keybinding.keyCode.meta,
keybinding.keyCode.key.keyCode
KEY_CODE_MAP[keybinding.keyCode.key.keyCode]
);
return new monaco.keybindings.USLayoutResolvedKeybinding(simple, monaco.platform.OS);
}
Expand Down

0 comments on commit d2d6324

Please sign in to comment.