Merge branch 'master' into ben/electron

This commit is contained in:
Benjamin Pasero 2016-01-07 08:22:08 +01:00
commit 6915fcdf80
21 changed files with 503 additions and 288 deletions

View file

@ -7,7 +7,7 @@ var path = require('path');
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var filter = require('gulp-filter');
var minifyCSS = require('gulp-minify-css');
var minifyCSS = require('gulp-cssnano');
var uglify = require('gulp-uglify');
var es = require('event-stream');
var concat = require('gulp-concat');

View file

@ -47,10 +47,10 @@
"gulp-azure-storage": "^0.3.0",
"gulp-bom": "^1.0.0",
"gulp-concat": "^2.6.0",
"gulp-cssnano": "^2.1.0",
"gulp-filter": "^3.0.0",
"gulp-insert": "^0.5.0",
"gulp-json-editor": "^2.2.1",
"gulp-minify-css": "^1.2.1",
"gulp-mocha": "^2.1.3",
"gulp-remote-src": "^0.4.0",
"gulp-rename": "^1.2.0",

View file

@ -123,6 +123,9 @@ let KEY_CODE_MAP: {[keyCode:number]:KeyCode} = {};
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;
if (Browser.isIE11orEarlier) {
KEY_CODE_MAP[91] = KeyCode.Meta;

View file

@ -5,10 +5,15 @@
"use strict";
import nls = require('vs/nls');
import Platform = require('vs/base/common/platform');
import * as nls from 'vs/nls';
import * as defaultPlatform from 'vs/base/common/platform';
import {IHTMLContentElement} from 'vs/base/common/htmlContent';
export interface ISimplifiedPlatform {
isMacintosh: boolean;
isWindows: boolean;
}
/**
* Virtual Key Codes, the value does not hold any inherent meaning.
* Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
@ -106,49 +111,68 @@ export enum KeyCode {
ScrollLock,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ';:' key
*/
US_SEMICOLON,
/**
* For any country/region, the '+' key
* For the US standard keyboard, the '=+' key
*/
US_EQUAL,
/**
* For any country/region, the ',' key
* For the US standard keyboard, the ',<' key
*/
US_COMMA,
/**
* For any country/region, the '-' key
* For the US standard keyboard, the '-_' key
*/
US_MINUS,
/**
* For any country/region, the '.' key
* For the US standard keyboard, the '.>' key
*/
US_DOT,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '/?' key
*/
US_SLASH,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '`~' key
*/
US_BACKTICK,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '[{' key
*/
US_OPEN_SQUARE_BRACKET,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the '\|' key
*/
US_BACKSLASH,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ']}' key
*/
US_CLOSE_SQUARE_BRACKET,
/**
* Used for miscellaneous characters; it can vary by keyboard.
* For the US standard keyboard, the ''"' key
*/
US_QUOTE,
/**
* Used for miscellaneous characters; it can vary by keyboard.
*/
OEM_8,
/**
* Either the angle bracket key or the backslash key on the RT 102-key keyboard.
*/
OEM_102,
NUMPAD_0, // VK_NUMPAD0, 0x60, Numeric keypad 0 key
NUMPAD_1, // VK_NUMPAD1, 0x61, Numeric keypad 1 key
@ -174,8 +198,58 @@ export enum KeyCode {
MAX_VALUE
}
let TO_STRING_MAP: string[] = [];
(function() {
interface IReverseMap {
[str:string]:KeyCode;
}
class Mapping {
_fromKeyCode: string[];
_toKeyCode: IReverseMap;
constructor(fromKeyCode: string[], toKeyCode: IReverseMap) {
this._fromKeyCode = fromKeyCode;
this._toKeyCode = toKeyCode;
}
fromKeyCode(keyCode:KeyCode): string {
return this._fromKeyCode[keyCode];
}
toKeyCode(str:string): KeyCode {
if (this._toKeyCode.hasOwnProperty(str)) {
return this._toKeyCode[str];
}
return KeyCode.Unknown;
}
}
function createMapping(fill1:(map:string[])=>void, fill2:(reverseMap:IReverseMap)=>void): Mapping {
let MAP: string[] = [];
fill1(MAP);
let REVERSE_MAP: IReverseMap = {};
for (let i = 0, len = MAP.length; i < len; i++) {
if (!MAP[i]) {
continue;
}
REVERSE_MAP[MAP[i]] = i;
}
fill2(REVERSE_MAP);
let FINAL_REVERSE_MAP: IReverseMap = {};
for (let entry in REVERSE_MAP) {
if (REVERSE_MAP.hasOwnProperty(entry)) {
FINAL_REVERSE_MAP[entry] = REVERSE_MAP[entry];
FINAL_REVERSE_MAP[entry.toLowerCase()] = REVERSE_MAP[entry];
}
}
return new Mapping(MAP, FINAL_REVERSE_MAP);
}
let STRING = createMapping((TO_STRING_MAP) => {
TO_STRING_MAP[KeyCode.Unknown] = 'unknown';
TO_STRING_MAP[KeyCode.Backspace] = 'Backspace';
@ -274,6 +348,8 @@ let TO_STRING_MAP: string[] = [];
TO_STRING_MAP[KeyCode.US_BACKSLASH] = '\\';
TO_STRING_MAP[KeyCode.US_CLOSE_SQUARE_BRACKET] = ']';
TO_STRING_MAP[KeyCode.US_QUOTE] = '\'';
TO_STRING_MAP[KeyCode.OEM_8] = 'OEM_8';
TO_STRING_MAP[KeyCode.OEM_102] = 'OEM_102';
TO_STRING_MAP[KeyCode.NUMPAD_0] = 'NumPad0';
TO_STRING_MAP[KeyCode.NUMPAD_1] = 'NumPad1';
@ -298,29 +374,41 @@ let TO_STRING_MAP: string[] = [];
// console.warn('Missing string representation for ' + KeyCode[i]);
// }
// }
})();
}, (FROM_STRING_MAP) => {
FROM_STRING_MAP['\r'] = KeyCode.Enter;
});
let FROM_STRING_MAP: {[str:string]:KeyCode;} = {};
FROM_STRING_MAP['\r'] = KeyCode.Enter;
(function() {
for (let i = 0, len = TO_STRING_MAP.length; i < len; i++) {
if (!TO_STRING_MAP[i]) {
continue;
}
FROM_STRING_MAP[TO_STRING_MAP[i]] = i;
FROM_STRING_MAP[TO_STRING_MAP[i].toLowerCase()] = i;
let USER_SETTINGS = createMapping((TO_USER_SETTINGS_MAP) => {
for (let i = 0, len = STRING._fromKeyCode.length; i < len; i++) {
TO_USER_SETTINGS_MAP[i] = STRING._fromKeyCode[i];
}
})();
TO_USER_SETTINGS_MAP[KeyCode.LeftArrow] = 'Left';
TO_USER_SETTINGS_MAP[KeyCode.UpArrow] = 'Up';
TO_USER_SETTINGS_MAP[KeyCode.RightArrow] = 'Right';
TO_USER_SETTINGS_MAP[KeyCode.DownArrow] = 'Down';
}, (FROM_USER_SETTINGS_MAP) => {
FROM_USER_SETTINGS_MAP['OEM_1'] = KeyCode.US_SEMICOLON;
FROM_USER_SETTINGS_MAP['OEM_PLUS'] = KeyCode.US_EQUAL;
FROM_USER_SETTINGS_MAP['OEM_COMMA'] = KeyCode.US_COMMA;
FROM_USER_SETTINGS_MAP['OEM_MINUS'] = KeyCode.US_MINUS;
FROM_USER_SETTINGS_MAP['OEM_PERIOD'] = KeyCode.US_DOT;
FROM_USER_SETTINGS_MAP['OEM_2'] = KeyCode.US_SLASH;
FROM_USER_SETTINGS_MAP['OEM_3'] = KeyCode.US_BACKTICK;
FROM_USER_SETTINGS_MAP['OEM_4'] = KeyCode.US_OPEN_SQUARE_BRACKET;
FROM_USER_SETTINGS_MAP['OEM_5'] = KeyCode.US_BACKSLASH;
FROM_USER_SETTINGS_MAP['OEM_6'] = KeyCode.US_CLOSE_SQUARE_BRACKET;
FROM_USER_SETTINGS_MAP['OEM_7'] = KeyCode.US_QUOTE;
FROM_USER_SETTINGS_MAP['OEM_8'] = KeyCode.OEM_8;
FROM_USER_SETTINGS_MAP['OEM_102'] = KeyCode.OEM_102;
});
export namespace KeyCode {
export function toString(key:KeyCode): string {
return TO_STRING_MAP[key];
return STRING.fromKeyCode(key);
}
export function fromString(key:string): KeyCode {
if (FROM_STRING_MAP.hasOwnProperty(key)) {
return FROM_STRING_MAP[key];
}
return KeyCode.Unknown;
return STRING.toKeyCode(key);
}
}
@ -432,49 +520,65 @@ export class Keybinding {
/**
* Format the binding to a format appropiate for rendering in the UI
*/
private static _toUSLabel(value:number): string {
return _asString(value, (Platform.isMacintosh ? MacUIKeyLabelProvider.INSTANCE : ClassicUIKeyLabelProvider.INSTANCE));
private static _toUSLabel(value:number, Platform:ISimplifiedPlatform): string {
return _asString(value, (Platform.isMacintosh ? MacUIKeyLabelProvider.INSTANCE : ClassicUIKeyLabelProvider.INSTANCE), Platform);
}
/**
* Format the binding to a format appropiate for rendering in the UI
*/
private static _toUSHTMLLabel(value:number): IHTMLContentElement[] {
return _asHTML(value, (Platform.isMacintosh ? MacUIKeyLabelProvider.INSTANCE : ClassicUIKeyLabelProvider.INSTANCE));
private static _toUSHTMLLabel(value:number, Platform:ISimplifiedPlatform): IHTMLContentElement[] {
return _asHTML(value, (Platform.isMacintosh ? MacUIKeyLabelProvider.INSTANCE : ClassicUIKeyLabelProvider.INSTANCE), Platform);
}
/**
* Format the binding to a format appropiate for rendering in the UI
*/
private static _toCustomLabel(value:number, labelProvider:IKeyBindingLabelProvider): string {
return _asString(value, labelProvider);
private static _toCustomLabel(value:number, labelProvider:IKeyBindingLabelProvider, Platform:ISimplifiedPlatform): string {
return _asString(value, labelProvider, Platform);
}
/**
* Format the binding to a format appropiate for rendering in the UI
*/
private static _toCustomHTMLLabel(value:number, labelProvider:IKeyBindingLabelProvider): IHTMLContentElement[] {
return _asHTML(value, labelProvider);
private static _toCustomHTMLLabel(value:number, labelProvider:IKeyBindingLabelProvider, Platform:ISimplifiedPlatform): IHTMLContentElement[] {
return _asHTML(value, labelProvider, Platform);
}
/**
* This prints the binding in a format suitable for electron's accelerators.
* See https://github.com/atom/electron/blob/master/docs/api/accelerator.md
*/
private static _toElectronAccelerator(value:number): string {
private static _toElectronAccelerator(value:number, Platform:ISimplifiedPlatform): string {
if (BinaryKeybindings.hasChord(value)) {
// Electron cannot handle chords
return null;
}
return _asString(value, ElectronAcceleratorLabelProvider.INSTANCE);
return _asString(value, ElectronAcceleratorLabelProvider.INSTANCE, Platform);
}
private static _cachedKeybindingRegex: string = null;
public static getUserSettingsKeybindingRegex(): string {
if (!this._cachedKeybindingRegex) {
let numpadKey = "numpad(0|1|2|3|4|5|6|7|8|9|_multiply|_add|_subtract|_decimal|_divide|_separator)";
let oemKey = "`|\\-|=|\\[|\\]|\\\\\\\\|;|'|,|\\.|\\/|oem_8|oem_102";
let specialKey = "left|up|right|down|pageup|pagedown|end|home|tab|enter|escape|space|backspace|delete|pausebreak|capslock|insert|contextmenu|numlock|scrolllock";
let casualKey = "[a-z]|[0-9]|f(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19)";
let key = '((' + [numpadKey, oemKey, specialKey, casualKey].join(')|(') + '))';
let mod = '((ctrl|shift|alt|cmd|win|meta)\\+)*';
let keybinding = '(' + mod + key + ')';
this._cachedKeybindingRegex = '"\\s*(' + keybinding + '(\\s+' + keybinding +')?' + ')\\s*"';
}
return this._cachedKeybindingRegex;
}
/**
* Format the binding to a format appropiate for the user settings file.
*/
public static toUserSettingsLabel(value:number): string {
let result = _asString(value, UserSettingsKeyLabelProvider.INSTANCE);
result = result.toLowerCase().replace(/arrow/g, '');
public static toUserSettingsLabel(value:number, Platform:ISimplifiedPlatform = defaultPlatform): string {
let result = _asString(value, UserSettingsKeyLabelProvider.INSTANCE, Platform);
result = result.toLowerCase();
if (Platform.isMacintosh) {
result = result.replace(/meta/g, 'cmd');
@ -485,6 +589,90 @@ export class Keybinding {
return result;
}
public static fromUserSettingsLabel(input: string, Platform: ISimplifiedPlatform = defaultPlatform): number {
if (!input) {
return null;
}
input = input.toLowerCase().trim();
let ctrlCmd = false,
shift = false,
alt = false,
winCtrl = false,
key:string = '';
while (/^(ctrl|shift|alt|meta|win|cmd)(\+|\-)/.test(input)) {
if (/^ctrl(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
winCtrl = true;
} else {
ctrlCmd = true;
}
input = input.substr('ctrl-'.length);
}
if (/^shift(\+|\-)/.test(input)) {
shift = true;
input = input.substr('shift-'.length);
}
if (/^alt(\+|\-)/.test(input)) {
alt = true;
input = input.substr('alt-'.length);
}
if (/^meta(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
}
input = input.substr('meta-'.length);
}
if (/^win(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
}
input = input.substr('win-'.length);
}
if (/^cmd(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
}
input = input.substr('cmd-'.length);
}
}
let chord: number = 0;
let firstSpaceIdx = input.indexOf(' ');
if (firstSpaceIdx > 0) {
key = input.substring(0, firstSpaceIdx);
chord = Keybinding.fromUserSettingsLabel(input.substring(firstSpaceIdx), Platform);
} else {
key = input;
}
let keyCode = USER_SETTINGS.toKeyCode(key);
let result = 0;
if (ctrlCmd) {
result |= KeyMod.CtrlCmd;
}
if (shift) {
result |= KeyMod.Shift;
}
if (alt) {
result |= KeyMod.Alt;
}
if (winCtrl) {
result |= KeyMod.WinCtrl;
}
result |= keyCode;
return KeyMod.chord(result, chord);
}
public value:number;
constructor(keybinding:number) {
@ -514,44 +702,44 @@ export class Keybinding {
/**
* Format the binding to a format appropiate for rendering in the UI
*/
public _toUSLabel(): string {
return Keybinding._toUSLabel(this.value);
public _toUSLabel(Platform:ISimplifiedPlatform = defaultPlatform): string {
return Keybinding._toUSLabel(this.value, Platform);
}
/**
* Format the binding to a format appropiate for rendering in the UI
*/
public _toUSHTMLLabel(): IHTMLContentElement[] {
return Keybinding._toUSHTMLLabel(this.value);
public _toUSHTMLLabel(Platform:ISimplifiedPlatform = defaultPlatform): IHTMLContentElement[] {
return Keybinding._toUSHTMLLabel(this.value, Platform);
}
/**
* Format the binding to a format appropiate for rendering in the UI
*/
public toCustomLabel(labelProvider:IKeyBindingLabelProvider): string {
return Keybinding._toCustomLabel(this.value, labelProvider);
public toCustomLabel(labelProvider:IKeyBindingLabelProvider, Platform:ISimplifiedPlatform = defaultPlatform): string {
return Keybinding._toCustomLabel(this.value, labelProvider, Platform);
}
/**
* Format the binding to a format appropiate for rendering in the UI
*/
public toCustomHTMLLabel(labelProvider:IKeyBindingLabelProvider): IHTMLContentElement[] {
return Keybinding._toCustomHTMLLabel(this.value, labelProvider);
public toCustomHTMLLabel(labelProvider:IKeyBindingLabelProvider, Platform:ISimplifiedPlatform = defaultPlatform): IHTMLContentElement[] {
return Keybinding._toCustomHTMLLabel(this.value, labelProvider, Platform);
}
/**
* This prints the binding in a format suitable for electron's accelerators.
* See https://github.com/atom/electron/blob/master/docs/api/accelerator.md
*/
public _toElectronAccelerator(): string {
return Keybinding._toElectronAccelerator(this.value);
public _toElectronAccelerator(Platform:ISimplifiedPlatform = defaultPlatform): string {
return Keybinding._toElectronAccelerator(this.value, Platform);
}
/**
* Format the binding to a format appropiate for the user settings file.
*/
public toUserSettingsLabel(): string {
return Keybinding.toUserSettingsLabel(this.value);
public toUserSettingsLabel(Platform:ISimplifiedPlatform = defaultPlatform): string {
return Keybinding.toUserSettingsLabel(this.value, Platform);
}
}
@ -662,11 +850,11 @@ class UserSettingsKeyLabelProvider implements IKeyBindingLabelProvider {
public modifierSeparator = '+';
public getLabelForKey(keyCode:KeyCode): string {
return KeyCode.toString(keyCode);
return USER_SETTINGS.fromKeyCode(keyCode);
}
}
function _asString(keybinding:number, labelProvider:IKeyBindingLabelProvider): string {
function _asString(keybinding:number, labelProvider:IKeyBindingLabelProvider, Platform:ISimplifiedPlatform): string {
let result:string[] = [],
ctrlCmd = BinaryKeybindings.hasCtrlCmd(keybinding),
shift = BinaryKeybindings.hasShift(keybinding),
@ -707,7 +895,7 @@ function _asString(keybinding:number, labelProvider:IKeyBindingLabelProvider): s
var actualResult = result.join(labelProvider.modifierSeparator);
if (BinaryKeybindings.hasChord(keybinding)) {
return actualResult + ' ' + _asString(BinaryKeybindings.extractChordPart(keybinding), labelProvider);
return actualResult + ' ' + _asString(BinaryKeybindings.extractChordPart(keybinding), labelProvider, Platform);
}
return actualResult;
@ -727,7 +915,7 @@ function _pushKey(result:IHTMLContentElement[], str:string): void {
});
}
function _asHTML(keybinding:number, labelProvider:IKeyBindingLabelProvider, isChord:boolean = false): IHTMLContentElement[] {
function _asHTML(keybinding:number, labelProvider:IKeyBindingLabelProvider, Platform:ISimplifiedPlatform, isChord:boolean = false): IHTMLContentElement[] {
let result:IHTMLContentElement[] = [],
ctrlCmd = BinaryKeybindings.hasCtrlCmd(keybinding),
shift = BinaryKeybindings.hasShift(keybinding),
@ -768,7 +956,7 @@ function _asHTML(keybinding:number, labelProvider:IKeyBindingLabelProvider, isCh
let chordTo: IHTMLContentElement[] = null;
if (BinaryKeybindings.hasChord(keybinding)) {
chordTo = _asHTML(BinaryKeybindings.extractChordPart(keybinding), labelProvider, true);
chordTo = _asHTML(BinaryKeybindings.extractChordPart(keybinding), labelProvider, Platform, true);
result.push({
tagName: 'span',
text: ' '

View file

@ -5,7 +5,8 @@
'use strict';
import * as assert from 'assert';
import {KeyCode, KeyMod, BinaryKeybindings} from 'vs/base/common/keyCodes';
import {KeyCode, KeyMod, BinaryKeybindings, Keybinding} from 'vs/base/common/keyCodes';
import * as Strings from 'vs/base/common/strings';
interface ITestKeybinding {
ctrlCmd?: boolean;
@ -65,4 +66,44 @@ suite('keyCodes', () => {
assert.equal(encodedFirstPart, KeyMod.CtrlCmd | KeyCode.KEY_Y, 'first part');
assert.equal(encodedSecondPart, encodedSecondPart, 'chord part');
});
test('getUserSettingsKeybindingRegex', () => {
let regex = new RegExp(Keybinding.getUserSettingsKeybindingRegex());
function testIsGood(userSettingsLabel:string, message:string = userSettingsLabel): void {
let userSettings = '"' + userSettingsLabel.replace(/\\/g, '\\\\') + '"';
let isGood = regex.test(userSettings);
assert.ok(isGood, message);
}
// check that all key codes are covered by the regex
let ignore: boolean[] = [];
ignore[KeyCode.Shift] = true;
ignore[KeyCode.Ctrl] = true;
ignore[KeyCode.Alt] = true;
ignore[KeyCode.Meta] = true;
for (let keyCode = KeyCode.Unknown + 1; keyCode < KeyCode.MAX_VALUE; keyCode++) {
if (ignore[keyCode]) {
continue;
}
let userSettings = Keybinding.toUserSettingsLabel(keyCode);
testIsGood(userSettings, keyCode + ' - ' + KeyCode[keyCode] + ' - ' + userSettings);
}
// one modifier
testIsGood('ctrl+a');
testIsGood('shift+a');
testIsGood('alt+a');
testIsGood('cmd+a');
testIsGood('meta+a');
testIsGood('win+a');
// more modifiers
testIsGood('ctrl+shift+a');
testIsGood('shift+alt+a');
testIsGood('ctrl+shift+alt+a');
// chords
testIsGood('ctrl+a ctrl+a');
})
});

View file

@ -21,7 +21,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IKeybindingContextKey, IKeybindingItem, ICommandHandler, ICommandsMap} from 'vs/platform/keybinding/common/keybindingService';
import {AbstractPluginService} from 'vs/platform/plugins/common/abstractPluginService';
import {IOSupport} from 'vs/platform/keybinding/common/commonKeybindingResolver';
import {IOSupport} from 'vs/platform/keybinding/common/keybindingResolver';
import {PluginsRegistry, PluginsMessageCollector} from 'vs/platform/plugins/common/pluginsRegistry';
export class SimpleEditor implements IEditor {

View file

@ -119,9 +119,7 @@ export default class LanguageFeatureRegistry<T> {
return;
}
if (this._updateScores(model)) {
this._sortByScore();
}
this._updateScores(model);
let supportIndex: number = -1;
let supportEntry: Entry<T>;
@ -171,10 +169,8 @@ export default class LanguageFeatureRegistry<T> {
for (let entry of this._entries) {
entry._score = score(entry.selector, model.getAssociatedResource(), model.getModeId());
}
return true;
}
private _sortByScore(): void {
// needs sorting
this._entries.sort(LanguageFeatureRegistry._compareByScoreAndTime);
}

View file

@ -16,7 +16,6 @@ import Actions = require('vs/base/common/actions');
import ActionBar = require('vs/base/browser/ui/actionbar/actionbar');
import Lifecycle = require('vs/base/common/lifecycle');
import SortedList = require('vs/base/common/sortedList');
import {KeybindingsUtils} from 'vs/platform/keybinding/common/keybindingsUtils';
import {IContextViewService, IContextMenuService} from 'vs/platform/contextview/browser/contextView';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {INullService} from 'vs/platform/instantiation/common/instantiation';

View file

@ -21,7 +21,7 @@ import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/edito
import {TPromise} from 'vs/base/common/winjs.base';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {RunOnceScheduler} from 'vs/base/common/async';
import {IOSupport} from 'vs/platform/keybinding/common/commonKeybindingResolver';
import {IOSupport} from 'vs/platform/keybinding/common/keybindingResolver';
import {IHTMLContentElement} from 'vs/base/common/htmlContent';
import {renderHtml} from 'vs/base/browser/htmlContentRenderer';
import {Range} from 'vs/editor/common/core/range';
@ -137,26 +137,10 @@ export class DefineKeybindingController implements EditorCommon.IEditorContribut
this._updateDecorations.schedule();
}
private static _cachedKeybindingRegex: string = null;
private static _getKeybindingRegex(): string {
if (!this._cachedKeybindingRegex) {
let numpadKey = "numpad(0|1|2|3|4|5|6|7|8|9|_multiply|_add|_subtract|_decimal|_divide)";
let punctKey = "`|\\-|=|\\[|\\]|\\\\\\\\|;|'|,|\\.|\\/";
let specialKey = "left|up|right|down|pageup|pagedown|end|home|tab|enter|escape|space|backspace|delete|pausebreak|capslock|insert";
let casualKey = "[a-z]|[0-9]|f(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15)";
let key = '((' + [numpadKey, punctKey, specialKey, casualKey].join(')|(') + '))';
let mod = '((ctrl|shift|alt|cmd|win|meta)\\+)*';
let keybinding = '(' + mod + key + ')';
this._cachedKeybindingRegex = '"\\s*(' + keybinding + '(\\s+' + keybinding +')?' + ')\\s*"';
}
return this._cachedKeybindingRegex;
}
private _dec:string[] = [];
private _updateDecorationsNow(): void {
let model = this._editor.getModel();
let regex = DefineKeybindingController._getKeybindingRegex();
let regex = Keybinding.getUserSettingsKeybindingRegex();
var m = model.findMatches(regex, false, true, false, false);

View file

@ -17,7 +17,6 @@ import Filters = require('vs/base/common/filters');
import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions';
import {EditorAction, Behaviour} from 'vs/editor/common/editorAction';
import EditorQuickOpen = require('./editorQuickOpen');
import {KeybindingsUtils} from 'vs/platform/keybinding/common/keybindingsUtils';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
export class EditorActionCommandEntry extends QuickOpenModel.QuickOpenEntryGroup {

View file

@ -6,7 +6,7 @@
import {ILanguage} from './types';
export var language = <ILanguage> {
export var language: ILanguage = {
displayName: 'Swift',
name: 'swift',
defaultToken: '',
@ -130,4 +130,4 @@ export var language = <ILanguage> {
[/([.])(@identifier)/, { cases: { '$2': ['delimeter', 'type.identifier'], '@default': '' } }],
]
}
};
};

View file

@ -6,21 +6,21 @@
import 'vs/css!./keybindings';
import * as nls from 'vs/nls';
import Severity from 'vs/base/common/severity';
import {TPromise} from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import lifecycle = require('vs/base/common/lifecycle');
import DOM = require('vs/base/browser/dom');
import Keyboard = require('vs/base/browser/keyboardEvent');
import {IDisposable} from 'vs/base/common/lifecycle';
import * as DOM from 'vs/base/browser/dom';
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
import {IKeybindingService, IKeybindingScopeLocation, ICommandHandler, IKeybindingItem, IKeybindings, IKeybindingContextKey} from 'vs/platform/keybinding/common/keybindingService';
import {IKeybindingService, IKeybindingScopeLocation, ICommandHandler, IKeybindingItem, IKeybindingContextKey} from 'vs/platform/keybinding/common/keybindingService';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IMessageService} from 'vs/platform/message/common/message';
import {IResolveResult, CommonKeybindingResolver} from 'vs/platform/keybinding/common/commonKeybindingResolver';
import {KeybindingResolver} from 'vs/platform/keybinding/common/keybindingResolver';
import {Keybinding, KeyCode} from 'vs/base/common/keyCodes';
import {IHTMLContentElement} from 'vs/base/common/htmlContent';
var KEYBINDING_CONTEXT_ATTR = 'data-keybinding-context';
let KEYBINDING_CONTEXT_ATTR = 'data-keybinding-context';
export class KeybindingContext {
private _parent: KeybindingContext;
@ -45,8 +45,8 @@ export class KeybindingContext {
}
public getValue(): any {
var r = this._parent ? this._parent.getValue() : Object.create(null);
for (var key in this._value) {
let r = this._parent ? this._parent.getValue() : Object.create(null);
for (let key in this._value) {
r[key] = this._value[key];
}
return r;
@ -138,10 +138,10 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
};
protected _domNode: HTMLElement;
private _toDispose: lifecycle.IDisposable;
private _toDispose: IDisposable;
private _resolver: KeybindingResolver;
private _currentChord: number;
private _currentChordStatusMessage: lifecycle.IDisposable;
private _currentChordStatusMessage: IDisposable;
constructor(domNode: HTMLElement) {
this._lastContextId = -1;
@ -150,7 +150,7 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
this._contexts = Object.create(null);
this._contexts[String(this._myContextId)] = new KeybindingContext(this._myContextId, null);
this._toDispose = DOM.addDisposableListener(this._domNode, DOM.EventType.KEY_DOWN, (e:KeyboardEvent) => {
var keyEvent = new Keyboard.StandardKeyboardEvent(e);
let keyEvent = new StandardKeyboardEvent(e);
this._dispatch(keyEvent);
});
@ -201,9 +201,10 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
}
private _getAllCommandsAsComment(): string {
var boundCommands = this._resolver.getDefaultBoundCommands();
var unboundCommands = Object.keys(KeybindingsRegistry.getCommands()).filter(commandId => commandId[0] !== '_' && !boundCommands[commandId]);
var pretty = unboundCommands.join('\n// - ');
let boundCommands = this._resolver.getDefaultBoundCommands();
let unboundCommands = Object.keys(KeybindingsRegistry.getCommands()).filter(commandId => commandId[0] !== '_' && !boundCommands[commandId]);
unboundCommands.sort();
let pretty = unboundCommands.join('\n// - ');
return '// ' + nls.localize('unboundCommands', "Here are other available commands: ") + '\n// - ' + pretty;
}
@ -213,17 +214,17 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
}
private _dispatch(e: DOM.IKeyboardEvent): void {
var isModifierKey = (e.keyCode === KeyCode.Ctrl || e.keyCode === KeyCode.Shift || e.keyCode === KeyCode.Alt || e.keyCode === KeyCode.Meta);
let isModifierKey = (e.keyCode === KeyCode.Ctrl || e.keyCode === KeyCode.Shift || e.keyCode === KeyCode.Alt || e.keyCode === KeyCode.Meta);
if (isModifierKey) {
return;
}
var contextId = this._findContextAttr(e.target);
var context = this.getContext(contextId);
var contextValue = context.getValue();
let contextId = this._findContextAttr(e.target);
let context = this.getContext(contextId);
let contextValue = context.getValue();
// console.log(JSON.stringify(contextValue, null, '\t'));
var resolveResult = this._resolver.resolveKeyboardEvent(contextValue, this._currentChord, e);
let resolveResult = this._resolver.resolve(contextValue, this._currentChord, e.asKeybinding());
if (resolveResult && resolveResult.enterChord) {
e.preventDefault();
@ -253,7 +254,7 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
if (!/^\^/.test(resolveResult.commandId)) {
e.preventDefault();
}
var commandId = resolveResult.commandId.replace(/^\^/, '');
let commandId = resolveResult.commandId.replace(/^\^/, '');
this._invokeHandler(commandId, { context: contextValue }).done(undefined, err => {
this._messageService.show(Severity.Warning, err);
});
@ -289,7 +290,7 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
}
public createChildContext(parentContextId: number = this._myContextId): number {
var id = (++this._lastContextId);
let id = (++this._lastContextId);
this._contexts[String(id)] = new KeybindingContext(id, this.getContext(parentContextId));
return id;
}
@ -300,9 +301,9 @@ export class KeybindingService extends AbstractKeybindingService implements IKey
public executeCommand(commandId: string, args:any = {}): TPromise<any> {
if (!args.context) {
var contextId = this._findContextAttr(<HTMLElement>document.activeElement);
var context = this.getContext(contextId);
var contextValue = context.getValue();
let contextId = this._findContextAttr(<HTMLElement>document.activeElement);
let context = this.getContext(contextId);
let contextValue = context.getValue();
args.context = contextValue;
}
@ -368,9 +369,3 @@ class ScopedKeybindingService extends AbstractKeybindingService {
return this._parent.executeCommand(commandId, args);
}
}
export class KeybindingResolver extends CommonKeybindingResolver {
public resolveKeyboardEvent(context: any, currentChord: number, key: DOM.IKeyboardEvent): IResolveResult {
return this.resolve(context, currentChord, key.asKeybinding());
}
}

View file

@ -4,11 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
import {KeybindingsUtils} from 'vs/platform/keybinding/common/keybindingsUtils';
import Platform = require('vs/base/common/platform');
import {IKeybindingService, IKeybindingScopeLocation, ICommandHandler, IKeybindingItem, IKeybindings, KbExpr, IUserFriendlyKeybinding, IKeybindingContextKey} from 'vs/platform/keybinding/common/keybindingService';
import {KeyMod, KeyCode, BinaryKeybindings, Keybinding} from 'vs/base/common/keyCodes';
import * as defaultPlatform from 'vs/base/common/platform';
import {IKeybindingItem, KbExpr, IUserFriendlyKeybinding} from 'vs/platform/keybinding/common/keybindingService';
import {KeyMod, KeyCode, BinaryKeybindings, Keybinding, ISimplifiedPlatform} from 'vs/base/common/keyCodes';
export interface IResolveResult {
enterChord: number;
@ -33,7 +31,7 @@ interface ICommandEntry {
commandId: string;
}
export class CommonKeybindingResolver {
export class KeybindingResolver {
private _defaultKeybindings: IKeybindingItem[];
private _defaultBoundCommands: IBoundCommands;
private _map: ICommandMap;
@ -107,10 +105,10 @@ export class CommonKeybindingResolver {
return;
}
var conflicts = this._map[keypress];
let conflicts = this._map[keypress];
for (var i = conflicts.length - 1; i >= 0; i--) {
var conflict = conflicts[i];
for (let i = conflicts.length - 1; i >= 0; i--) {
let conflict = conflicts[i];
if (conflict.commandId === item.command) {
continue;
@ -121,7 +119,7 @@ export class CommonKeybindingResolver {
continue;
}
if (CommonKeybindingResolver.contextIsEntirelyIncluded(true, conflict.context, item.context)) {
if (KeybindingResolver.contextIsEntirelyIncluded(true, conflict.context, item.context)) {
// `item` completely overwrites `conflict`
if (this._shouldWarnOnConflict && isDefault) {
console.warn('Conflict detected, command `' + conflict.commandId + '` cannot be triggered by ' + Keybinding.toUserSettingsLabel(keypress));
@ -182,11 +180,17 @@ export class CommonKeybindingResolver {
}
public getDefaultKeybindings(): string {
var out = new OutputBuilder();
let out = new OutputBuilder();
out.writeLine('[');
this._defaultKeybindings.forEach(k => {
let lastIndex = this._defaultKeybindings.length - 1;
this._defaultKeybindings.forEach((k, index) => {
IOSupport.writeKeybindingItem(out, k);
out.writeLine(',');
if (index !== lastIndex) {
out.writeLine(',');
} else {
out.writeLine();
}
});
out.writeLine(']');
return out.toString();
@ -262,7 +266,7 @@ export class CommonKeybindingResolver {
for (let i = matches.length - 1; i >= 0; i--) {
let k = matches[i];
if (!CommonKeybindingResolver.contextMatchesRules(context, k.context)) {
if (!KeybindingResolver.contextMatchesRules(context, k.context)) {
continue;
}
@ -339,8 +343,8 @@ export class IOSupport {
}
public static readKeybindingItem(input: IUserFriendlyKeybinding, index:number): IKeybindingItem {
var key = IOSupport.readKeybinding(input.key);
var context = IOSupport.readKeybindingContexts(input.when);
let key = IOSupport.readKeybinding(input.key);
let context = IOSupport.readKeybindingContexts(input.when);
return {
keybinding: key,
command: input.command,
@ -350,98 +354,12 @@ export class IOSupport {
};
}
private static writeKeybinding(input: number): string {
return Keybinding.toUserSettingsLabel(input);
public static writeKeybinding(input: number, Platform: ISimplifiedPlatform = defaultPlatform): string {
return Keybinding.toUserSettingsLabel(input, Platform);
}
public static readKeybinding(input: string): number {
if (!input) {
return null;
}
input = input.toLowerCase().trim();
var ctrlCmd = false,
shift = false,
alt = false,
winCtrl = false,
key:string = '';
while (/^(ctrl|shift|alt|meta|win|cmd)(\+|\-)/.test(input)) {
if (/^ctrl(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
winCtrl = true;
} else {
ctrlCmd = true;
}
input = input.substr('ctrl-'.length);
}
if (/^shift(\+|\-)/.test(input)) {
shift = true;
input = input.substr('shift-'.length);
}
if (/^alt(\+|\-)/.test(input)) {
alt = true;
input = input.substr('alt-'.length);
}
if (/^meta(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
}
input = input.substr('meta-'.length);
}
if (/^win(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
}
input = input.substr('win-'.length);
}
if (/^cmd(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
}
input = input.substr('cmd-'.length);
}
}
if (/^(up|down|left|right)/.test(input)) {
input = input.replace(/^(up|down|left|right)/,(captured) => {
return captured + 'arrow';
});
}
var chord: number = 0;
var firstSpaceIdx = input.indexOf(' ');
if (firstSpaceIdx > 0) {
key = input.substring(0, firstSpaceIdx);
chord = IOSupport.readKeybinding(input.substring(firstSpaceIdx));
} else {
key = input;
}
let keyCode = KeyCode.fromString(key);
let result = 0;
if (ctrlCmd) {
result |= KeyMod.CtrlCmd;
}
if (shift) {
result |= KeyMod.Shift;
}
if (alt) {
result |= KeyMod.Alt;
}
if (winCtrl) {
result |= KeyMod.WinCtrl;
}
result |= keyCode;
return KeyMod.chord(result, chord);
public static readKeybinding(input: string, Platform: ISimplifiedPlatform = defaultPlatform): number {
return Keybinding.fromUserSettingsLabel(input, Platform);
}
public static readKeybindingContexts(input: string): KbExpr {

View file

@ -6,7 +6,7 @@
import {TPromise} from 'vs/base/common/winjs.base';
import {TypeConstraint} from 'vs/base/common/types';
import {createDecorator, IInstantiationService, ServiceIdentifier, ServicesAccessor} from 'vs/platform/instantiation/common/instantiation';
import {createDecorator, ServiceIdentifier, ServicesAccessor} from 'vs/platform/instantiation/common/instantiation';
import {Keybinding} from 'vs/base/common/keyCodes';
import {IHTMLContentElement} from 'vs/base/common/htmlContent';
@ -168,7 +168,7 @@ export class KbAndExpression implements KbExpr {
}
public evaluate(context:any): boolean {
for (var i = 0, len = this.expr.length; i < len; i++) {
for (let i = 0, len = this.expr.length; i < len; i++) {
if (!this.expr[i].evaluate(context)) {
return false;
}
@ -221,7 +221,7 @@ export class KbAndExpression implements KbExpr {
}
export var KbExpr = {
export let KbExpr = {
has: (key:string) => new KbDefinedExpression(key),
equals: (key:string, value:any) => new KbEqualsExpression(key, value),
notEquals: (key:string, value:any) => new KbNotEqualsExpression(key, value),
@ -268,7 +268,7 @@ export var KbExpr = {
return false;
}
var m = /^'([^']*)'$/.exec(serializedValue);
let m = /^'([^']*)'$/.exec(serializedValue);
if (m) {
return m[1].trim();
}
@ -305,7 +305,7 @@ export interface IKeybindingContextKey<T> {
reset(): void;
}
export var IKeybindingService = createDecorator<IKeybindingService>('keybindingService');
export let IKeybindingService = createDecorator<IKeybindingService>('keybindingService');
export interface IKeybindingScopeLocation {
setAttribute(attr:string, value:string): void;

View file

@ -7,7 +7,6 @@
import {Registry} from 'vs/platform/platform';
import {TypeConstraint, validateConstraints} from 'vs/base/common/types';
import {ICommandHandler, ICommandHandlerDescription, ICommandsMap, IKeybindingItem, IKeybindings, KbExpr} from 'vs/platform/keybinding/common/keybindingService';
import {KeybindingsUtils} from 'vs/platform/keybinding/common/keybindingsUtils';
import {KeyMod, KeyCode, BinaryKeybindings} from 'vs/base/common/keyCodes';
import Platform = require('vs/base/common/platform');
@ -28,9 +27,6 @@ export interface IKeybindingsRegistry {
getCommands(): ICommandsMap;
getDefaultKeybindings(): IKeybindingItem[];
KEYBINDING_CONTEXT_OPERATOR_EQUAL: string;
KEYBINDING_CONTEXT_OPERATOR_NOT_EQUAL: string;
WEIGHT: {
editorCore(importance?: number): number;
editorContrib(importance?: number): number;
@ -45,9 +41,6 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
private _keybindings: IKeybindingItem[];
private _commands: ICommandsMap;
public KEYBINDING_CONTEXT_OPERATOR_EQUAL = 'equal';
public KEYBINDING_CONTEXT_OPERATOR_NOT_EQUAL = 'not_equal';
public WEIGHT = {
editorCore: (importance: number = 0): number => {
return 0 + importance;
@ -71,8 +64,29 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
this._commands = Object.create(null);
}
/**
* Take current platform into account and reduce to primary & secondary.
*/
private static bindToCurrentPlatform(kb:IKeybindings): { primary?: number; secondary?: number[]; } {
if (Platform.isWindows) {
if (kb && kb.win) {
return kb.win;
}
} else if (Platform.isMacintosh) {
if (kb && kb.mac) {
return kb.mac;
}
} else {
if (kb && kb.linux) {
return kb.linux;
}
}
return kb;
}
public registerCommandRule(rule:ICommandRule): void {
var actualKb = KeybindingsUtils.bindToCurrentPlatform(rule);
let actualKb = KeybindingsRegistryImpl.bindToCurrentPlatform(rule);
if (actualKb && actualKb.primary) {
this.registerDefaultKeybinding(actualKb.primary, rule.id, rule.weight, 0, rule.context);
@ -91,14 +105,13 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
// }
// this._commands[desc.id] = desc.handler;
let {handler} = desc;
let handler = desc.handler;
let description = desc.description || handler.description;
// add argument validation if rich command metadata is provided
if (typeof description === 'object') {
const metadata = <ICommandHandlerDescription>description;
const constraints: TypeConstraint[] = [];
for (let arg of metadata.args) {
let constraints: TypeConstraint[] = [];
for (let arg of description.args) {
constraints.push(arg.constraint);
}
handler = function(accesor, args) {
@ -139,10 +152,10 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
return this._keybindings;
}
}
export var KeybindingsRegistry:IKeybindingsRegistry = new KeybindingsRegistryImpl();
export let KeybindingsRegistry:IKeybindingsRegistry = new KeybindingsRegistryImpl();
// Define extension point ids
export var Extensions = {
export let Extensions = {
EditorModes: 'platform.keybindingsRegistry'
};
Registry.add(Extensions.EditorModes, KeybindingsRegistry);

View file

@ -1,34 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import nls = require('vs/nls');
import Platform = require('vs/base/common/platform');
import {IKeybindings} from 'vs/platform/keybinding/common/keybindingService';
import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
export class KeybindingsUtils {
/**
* Take current platform into account and reduce to primary & secondary.
*/
public static bindToCurrentPlatform(kb:IKeybindings): { primary?: number; secondary?: number[]; } {
if (Platform.isWindows) {
if (kb && kb.win) {
return kb.win;
}
} else if (Platform.isMacintosh) {
if (kb && kb.mac) {
return kb.mac;
}
} else {
if (kb && kb.linux) {
return kb.linux;
}
}
return kb;
}
}

View file

@ -0,0 +1,113 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import {IOSupport} from 'vs/platform/keybinding/common/keybindingResolver';
import {KeyMod, KeyCode, ISimplifiedPlatform} from 'vs/base/common/keyCodes';
suite('Keybinding IO', () => {
test('serialize/deserialize', function() {
const WINDOWS = { isMacintosh: false, isWindows: true };
const MACINTOSH = { isMacintosh: true, isWindows: false };
const LINUX = { isMacintosh: false, isWindows: false };
function testOneSerialization(keybinding:number, expected:string, msg:string, Platform:ISimplifiedPlatform): void {
let actualSerialized = IOSupport.writeKeybinding(keybinding, Platform);
assert.equal(actualSerialized, expected, expected + ' - ' + msg);
}
function testSerialization(keybinding:number, expectedWin:string, expectedMac:string, expectedLinux:string): void {
testOneSerialization(keybinding, expectedWin, 'win', WINDOWS);
testOneSerialization(keybinding, expectedMac, 'mac', MACINTOSH);
testOneSerialization(keybinding, expectedLinux, 'linux', LINUX);
}
function testOneDeserialization(keybinding:string, expected:number, msg:string, Platform:ISimplifiedPlatform): void {
let actualDeserialized = IOSupport.readKeybinding(keybinding, Platform);
assert.equal(actualDeserialized, expected, keybinding + ' - ' + msg);
}
function testDeserialization(inWin:string, inMac:string, inLinux:string, expected:number): void {
testOneDeserialization(inWin, expected, 'win', WINDOWS);
testOneDeserialization(inMac, expected, 'mac', MACINTOSH);
testOneDeserialization(inLinux, expected, 'linux', LINUX);
}
function testRoundtrip(keybinding:number, expectedWin:string, expectedMac:string, expectedLinux:string): void {
testSerialization(keybinding, expectedWin, expectedMac, expectedLinux);
testDeserialization(expectedWin, expectedMac, expectedLinux, keybinding);
}
testRoundtrip(KeyCode.KEY_0, '0', '0', '0');
testRoundtrip(KeyCode.KEY_A, 'a', 'a', 'a');
testRoundtrip(KeyCode.UpArrow, 'up', 'up', 'up');
testRoundtrip(KeyCode.RightArrow, 'right', 'right', 'right');
testRoundtrip(KeyCode.DownArrow, 'down', 'down', 'down');
testRoundtrip(KeyCode.LeftArrow, 'left', 'left', 'left');
// one modifier
testRoundtrip(KeyMod.Alt | KeyCode.KEY_A, 'alt+a', 'alt+a', 'alt+a');
testRoundtrip(KeyMod.CtrlCmd | KeyCode.KEY_A, 'ctrl+a', 'cmd+a', 'ctrl+a');
testRoundtrip(KeyMod.Shift | KeyCode.KEY_A, 'shift+a', 'shift+a', 'shift+a');
testRoundtrip(KeyMod.WinCtrl | KeyCode.KEY_A, 'win+a', 'ctrl+a', 'meta+a');
// two modifiers
testRoundtrip(KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, 'ctrl+alt+a', 'alt+cmd+a', 'ctrl+alt+a');
testRoundtrip(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, 'ctrl+shift+a', 'shift+cmd+a', 'ctrl+shift+a');
testRoundtrip(KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+win+a', 'ctrl+cmd+a', 'ctrl+meta+a');
testRoundtrip(KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'shift+alt+a', 'shift+alt+a', 'shift+alt+a');
testRoundtrip(KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'shift+win+a', 'ctrl+shift+a', 'shift+meta+a');
testRoundtrip(KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'alt+win+a', 'ctrl+alt+a', 'alt+meta+a');
// three modifiers
testRoundtrip(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'ctrl+shift+alt+a', 'shift+alt+cmd+a', 'ctrl+shift+alt+a');
testRoundtrip(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+win+a', 'ctrl+shift+cmd+a', 'ctrl+shift+meta+a');
testRoundtrip(KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'shift+alt+win+a', 'ctrl+shift+alt+a', 'shift+alt+meta+a');
// all modifiers
testRoundtrip(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+alt+win+a', 'ctrl+shift+alt+cmd+a', 'ctrl+shift+alt+meta+a');
// chords
testRoundtrip(KeyMod.chord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_A), 'ctrl+a ctrl+a', 'cmd+a cmd+a', 'ctrl+a ctrl+a');
testRoundtrip(KeyMod.chord(KeyMod.CtrlCmd | KeyCode.UpArrow, KeyMod.CtrlCmd | KeyCode.UpArrow), 'ctrl+up ctrl+up', 'cmd+up cmd+up', 'ctrl+up ctrl+up');
// OEM keys
testRoundtrip(KeyCode.US_SEMICOLON, ';', ';', ';');
testRoundtrip(KeyCode.US_EQUAL, '=', '=', '=');
testRoundtrip(KeyCode.US_COMMA, ',', ',', ',');
testRoundtrip(KeyCode.US_MINUS, '-', '-', '-');
testRoundtrip(KeyCode.US_DOT, '.', '.', '.');
testRoundtrip(KeyCode.US_SLASH, '/', '/', '/');
testRoundtrip(KeyCode.US_BACKTICK, '`', '`', '`');
testRoundtrip(KeyCode.US_OPEN_SQUARE_BRACKET, '[', '[', '[');
testRoundtrip(KeyCode.US_BACKSLASH, '\\', '\\', '\\');
testRoundtrip(KeyCode.US_CLOSE_SQUARE_BRACKET, ']', ']', ']');
testRoundtrip(KeyCode.US_QUOTE, '\'', '\'', '\'');
testRoundtrip(KeyCode.OEM_8, 'oem_8', 'oem_8', 'oem_8');
testRoundtrip(KeyCode.OEM_102, 'oem_102', 'oem_102', 'oem_102');
// OEM aliases
testDeserialization('OEM_1', 'OEM_1', 'OEM_1', KeyCode.US_SEMICOLON);
testDeserialization('OEM_PLUS', 'OEM_PLUS', 'OEM_PLUS', KeyCode.US_EQUAL);
testDeserialization('OEM_COMMA', 'OEM_COMMA', 'OEM_COMMA', KeyCode.US_COMMA);
testDeserialization('OEM_MINUS', 'OEM_MINUS', 'OEM_MINUS', KeyCode.US_MINUS);
testDeserialization('OEM_PERIOD', 'OEM_PERIOD', 'OEM_PERIOD', KeyCode.US_DOT);
testDeserialization('OEM_2', 'OEM_2', 'OEM_2', KeyCode.US_SLASH);
testDeserialization('OEM_3', 'OEM_3', 'OEM_3', KeyCode.US_BACKTICK);
testDeserialization('OEM_4', 'OEM_4', 'OEM_4', KeyCode.US_OPEN_SQUARE_BRACKET);
testDeserialization('OEM_5', 'OEM_5', 'OEM_5', KeyCode.US_BACKSLASH);
testDeserialization('OEM_6', 'OEM_6', 'OEM_6', KeyCode.US_CLOSE_SQUARE_BRACKET);
testDeserialization('OEM_7', 'OEM_7', 'OEM_7', KeyCode.US_QUOTE);
testDeserialization('OEM_8', 'OEM_8', 'OEM_8', KeyCode.OEM_8);
testDeserialization('OEM_102', 'OEM_102', 'OEM_102', KeyCode.OEM_102);
// accepts '-' as separator
testDeserialization('ctrl-shift-alt-win-a', 'ctrl-shift-alt-cmd-a', 'ctrl-shift-alt-meta-a', KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A);
// various input mistakes
testDeserialization(' ctrl-shift-alt-win-A ', ' shift-alt-cmd-Ctrl-A ', ' ctrl-shift-alt-META-A ', KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A);
});
});

View file

@ -4,11 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import {CommonKeybindingResolver, IOSupport} from 'vs/platform/keybinding/common/commonKeybindingResolver';
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
import {KeybindingsUtils} from 'vs/platform/keybinding/common/keybindingsUtils';
import Platform = require('vs/base/common/platform');
import * as assert from 'assert';
import {KeybindingResolver, IOSupport} from 'vs/platform/keybinding/common/keybindingResolver';
import * as Platform from 'vs/base/common/platform';
import {KbExpr, KbAndExpression, IKeybindingItem} from 'vs/platform/keybinding/common/keybindingService';
import {KeyMod, KeyCode, BinaryKeybindings} from 'vs/base/common/keyCodes';
@ -25,10 +23,10 @@ suite('Keybinding Service', () => {
weight2: 0
};
assert.equal(CommonKeybindingResolver.contextMatchesRules({ bar: 'baz' }, contextRules), true);
assert.equal(CommonKeybindingResolver.contextMatchesRules({ bar: 'bz' }, contextRules), false);
assert.equal(KeybindingResolver.contextMatchesRules({ bar: 'baz' }, contextRules), true);
assert.equal(KeybindingResolver.contextMatchesRules({ bar: 'bz' }, contextRules), false);
var resolver = new CommonKeybindingResolver([keybindingItem], []);
var resolver = new KeybindingResolver([keybindingItem], []);
assert.equal(resolver.resolve({ bar: 'baz' }, 0, keybinding).commandId, 'yes');
assert.equal(resolver.resolve({ bar: 'bz' }, 0, keybinding), null);
});
@ -47,10 +45,10 @@ suite('Keybinding Service', () => {
test('contextIsEntirelyIncluded', function () {
var assertIsIncluded = (a: KbExpr[], b: KbExpr[]) => {
assert.equal(CommonKeybindingResolver.contextIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), true);
assert.equal(KeybindingResolver.contextIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), true);
};
var assertIsNotIncluded = (a: KbExpr[], b: KbExpr[]) => {
assert.equal(CommonKeybindingResolver.contextIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), false);
assert.equal(KeybindingResolver.contextIsEntirelyIncluded(false, new KbAndExpression(a), new KbAndExpression(b)), false);
};
var key1IsTrue = KbExpr.equals('key1', true);
var key1IsNotFalse = KbExpr.notEquals('key1', false);
@ -203,7 +201,7 @@ suite('Keybinding Service', () => {
}
];
var resolver = new CommonKeybindingResolver(items, [], false);
var resolver = new KeybindingResolver(items, [], false);
@ -278,7 +276,7 @@ suite('Keybinding Service', () => {
};
function testExpression(expr:string, expected:boolean): void {
let rules = IOSupport.readKeybindingContexts(expr);
assert.equal(CommonKeybindingResolver.contextMatchesRules(context, rules), expected, expr);
assert.equal(KeybindingResolver.contextMatchesRules(context, rules), expected, expr);
}
function testBatch(expr:string, value:any): void {
testExpression(expr, !!value);

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import assert = require('assert');
import * as assert from 'assert';
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
suite('Keybinding Registry', () => {

View file

@ -15,7 +15,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {PluginsRegistry, IMessageCollector} from 'vs/platform/plugins/common/pluginsRegistry';
import {IPluginService} from 'vs/platform/plugins/common/plugins';
import {IOSupport} from 'vs/platform/keybinding/common/commonKeybindingResolver';
import {IOSupport} from 'vs/platform/keybinding/common/keybindingResolver';
import {KeybindingService} from 'vs/platform/keybinding/browser/keybindingServiceImpl';
import {IKeybindingItem, IUserFriendlyKeybinding} from 'vs/platform/keybinding/common/keybindingService';
import {ICommandRule, KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';

View file

@ -179,8 +179,8 @@ const NATIVE_KEY_CODE_TO_KEY_CODE: {[nativeKeyCode:string]:KeyCode;} = {
VKEY_OEM_5: KeyCode.US_BACKSLASH,
VKEY_OEM_6: KeyCode.US_CLOSE_SQUARE_BRACKET,
VKEY_OEM_7: KeyCode.US_QUOTE,
VKEY_OEM_8: KeyCode.Unknown, // MISSING
VKEY_OEM_102: KeyCode.Unknown, // MISSING
VKEY_OEM_8: KeyCode.OEM_8,
VKEY_OEM_102: KeyCode.OEM_102,
VKEY_PROCESSKEY: KeyCode.Unknown, // MISSING
VKEY_PACKET: KeyCode.Unknown, // MISSING
VKEY_DBE_SBCSCHAR: KeyCode.Unknown, // MISSING
@ -348,6 +348,8 @@ export function getNativeLabelProvider(): IKeyBindingLabelProvider {
VKEY_OEM_5: true,
VKEY_OEM_6: true,
VKEY_OEM_7: true,
VKEY_OEM_8: true,
VKEY_OEM_102: true,
};
let remaps:string[] = [];