Initial VS Code 1.19 source merge (#571)

* Initial 1.19 xcopy

* Fix yarn build

* Fix numerous build breaks

* Next batch of build break fixes

* More build break fixes

* Runtime breaks

* Additional post merge fixes

* Fix windows setup file

* Fix test failures.

* Update license header blocks to refer to source eula
This commit is contained in:
Karl Burtram
2018-01-28 23:37:17 -08:00
committed by GitHub
parent 9a1ac20710
commit 251ae01c3e
8009 changed files with 93378 additions and 35634 deletions

View File

@@ -215,7 +215,7 @@ export class KeybindingsEditingService extends Disposable implements IKeybinding
private resolveModelReference(): TPromise<IReference<ITextEditorModel>> {
return this.fileService.existsFile(this.resource)
.then(exists => {
const EOL = this.configurationService.getConfiguration('files', { overrideIdentifier: 'json' })['eol'];
const EOL = this.configurationService.getValue('files', { overrideIdentifier: 'json' })['eol'];
const result = exists ? TPromise.as(null) : this.fileService.updateContent(this.resource, this.getEmptyContent(EOL), { encoding: 'utf8' });
return result.then(() => this.textModelResolverService.createModelReference(this.resource));
});

View File

@@ -15,3 +15,36 @@ export interface IKeyboardMapper {
resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding;
resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding, chordPart: SimpleKeybinding | ScanCodeBinding): ResolvedKeybinding[];
}
export class CachedKeyboardMapper implements IKeyboardMapper {
private _actual: IKeyboardMapper;
private _cache: Map<string, ResolvedKeybinding[]>;
constructor(actual) {
this._actual = actual;
this._cache = new Map<string, ResolvedKeybinding[]>();
}
public dumpDebugInfo(): string {
return this._actual.dumpDebugInfo();
}
public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[] {
let hashCode = keybinding.getHashCode();
if (!this._cache.has(hashCode)) {
let r = this._actual.resolveKeybinding(keybinding);
this._cache.set(hashCode, r);
return r;
}
return this._cache.get(hashCode);
}
public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding {
return this._actual.resolveKeyboardEvent(keyboardEvent);
}
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding, chordPart: SimpleKeybinding | ScanCodeBinding): ResolvedKeybinding[] {
return this._actual.resolveUserBinding(firstPart, chordPart);
}
}

View File

@@ -12,22 +12,6 @@ import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
import { ScanCodeBinding, ScanCode, IMMUTABLE_CODE_TO_KEY_CODE } from 'vs/workbench/services/keybinding/common/scanCode';
export interface IMacLinuxKeyMapping {
value: string;
withShift: string;
withAltGr: string;
withShiftAltGr: string;
valueIsDeadKey?: boolean;
withShiftIsDeadKey?: boolean;
withAltGrIsDeadKey?: boolean;
withShiftAltGrIsDeadKey?: boolean;
}
export interface IMacLinuxKeyboardMapping {
[scanCode: string]: IMacLinuxKeyMapping;
}
/**
* A keyboard mapper to be used when reading the keymap from the OS fails.
*/

View File

@@ -28,7 +28,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { KeybindingIO, OutputBuilder, IUserKeybindingItem } from 'vs/workbench/services/keybinding/common/keybindingIO';
import * as nativeKeymap from 'native-keymap';
import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper';
import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper';
import { WindowsKeyboardMapper, IWindowsKeyboardMapping, windowsKeyboardMappingEquals } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper';
import { IMacLinuxKeyboardMapping, MacLinuxKeyboardMapper, macLinuxKeyboardMappingEquals } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper';
import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper';
@@ -38,7 +38,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { onUnexpectedError } from 'vs/base/common/errors';
export class KeyboardMapperFactory {
public static INSTANCE = new KeyboardMapperFactory();
public static readonly INSTANCE = new KeyboardMapperFactory();
private _layoutInfo: nativeKeymap.IKeyboardLayoutInfo;
private _rawMapping: nativeKeymap.IKeyboardMapping;
@@ -115,7 +115,9 @@ export class KeyboardMapperFactory {
this._initialized = true;
this._rawMapping = rawMapping;
this._keyboardMapper = KeyboardMapperFactory._createKeyboardMapper(this._layoutInfo, this._rawMapping);
this._keyboardMapper = new CachedKeyboardMapper(
KeyboardMapperFactory._createKeyboardMapper(this._layoutInfo, this._rawMapping)
);
this._onDidChangeKeyboardMapper.fire();
}
@@ -243,7 +245,7 @@ export const enum DispatchConfig {
}
function getDispatchConfig(configurationService: IConfigurationService): DispatchConfig {
const keyboard = configurationService.getConfiguration('keyboard');
const keyboard = configurationService.getValue('keyboard');
const r = (keyboard ? (<any>keyboard).dispatch : null);
return (r === 'keyCode' ? DispatchConfig.KeyCode : DispatchConfig.Code);
}
@@ -567,25 +569,22 @@ let schema: IJSONSchema = {
let schemaRegistry = <IJSONContributionRegistry>Registry.as(Extensions.JSONContribution);
schemaRegistry.registerSchema(schemaId, schema);
if (OS === OperatingSystem.Macintosh || OS === OperatingSystem.Linux) {
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
const keyboardConfiguration: IConfigurationNode = {
'id': 'keyboard',
'order': 15,
'type': 'object',
'title': nls.localize('keyboardConfigurationTitle', "Keyboard"),
'overridable': true,
'properties': {
'keyboard.dispatch': {
'type': 'string',
'enum': ['code', 'keyCode'],
'default': 'code',
'description': nls.localize('dispatch', "Controls the dispatching logic for key presses to use either `keydown.code` (recommended) or `keydown.keyCode`.")
}
const configurationRegistry = <IConfigurationRegistry>Registry.as(ConfigExtensions.Configuration);
const keyboardConfiguration: IConfigurationNode = {
'id': 'keyboard',
'order': 15,
'type': 'object',
'title': nls.localize('keyboardConfigurationTitle', "Keyboard"),
'overridable': true,
'properties': {
'keyboard.dispatch': {
'type': 'string',
'enum': ['code', 'keyCode'],
'default': 'code',
'description': nls.localize('dispatch', "Controls the dispatching logic for key presses to use either `code` (recommended) or `keyCode`."),
'included': OS === OperatingSystem.Macintosh || OS === OperatingSystem.Linux
}
};
}
};
configurationRegistry.registerConfiguration(keyboardConfiguration);
}
configurationRegistry.registerConfiguration(keyboardConfiguration);

View File

@@ -13,151 +13,6 @@ import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayo
import { ScanCodeBinding, ScanCode } from 'vs/workbench/services/keybinding/common/scanCode';
suite('keybindingIO', () => {
test('serialize/deserialize', function () {
function testOneSerialization(keybinding: number, expected: string, msg: string, OS: OperatingSystem): void {
let usLayoutResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS), OS);
let actualSerialized = usLayoutResolvedKeybinding.getUserSettingsLabel();
assert.equal(actualSerialized, expected, expected + ' - ' + msg);
}
function testSerialization(keybinding: number, expectedWin: string, expectedMac: string, expectedLinux: string): void {
testOneSerialization(keybinding, expectedWin, 'win', OperatingSystem.Windows);
testOneSerialization(keybinding, expectedMac, 'mac', OperatingSystem.Macintosh);
testOneSerialization(keybinding, expectedLinux, 'linux', OperatingSystem.Linux);
}
function testOneDeserialization(keybinding: string, _expected: number, msg: string, OS: OperatingSystem): void {
let actualDeserialized = KeybindingIO.readKeybinding(keybinding, OS);
let expected = createKeybinding(_expected, OS);
assert.deepEqual(actualDeserialized, expected, keybinding + ' - ' + msg);
}
function testDeserialization(inWin: string, inMac: string, inLinux: string, expected: number): void {
testOneDeserialization(inWin, expected, 'win', OperatingSystem.Windows);
testOneDeserialization(inMac, expected, 'mac', OperatingSystem.Macintosh);
testOneDeserialization(inLinux, expected, 'linux', OperatingSystem.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(KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_A), 'ctrl+a ctrl+a', 'cmd+a cmd+a', 'ctrl+a ctrl+a');
testRoundtrip(KeyChord(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.ABNT_C1, 'abnt_c1', 'abnt_c1', 'abnt_c1');
testRoundtrip(KeyCode.ABNT_C2, 'abnt_c2', 'abnt_c2', 'abnt_c2');
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('ABNT_C1', 'ABNT_C1', 'ABNT_C1', KeyCode.ABNT_C1);
testDeserialization('ABNT_C2', 'ABNT_C2', 'ABNT_C2', KeyCode.ABNT_C2);
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);
});
test('deserialize scan codes', () => {
assert.deepEqual(
KeybindingIO._readUserBinding('ctrl+shift+[comma] ctrl+/'),
[new ScanCodeBinding(true, true, false, false, ScanCode.Comma), new SimpleKeybinding(true, false, false, false, KeyCode.US_SLASH)]
);
});
test('issue #10452 - invalid command', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": ["firstcommand", "seccondcommand"] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding, OS);
assert.equal(keybindingItem.command, null);
});
test('issue #10452 - invalid when', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding, OS);
assert.equal(keybindingItem.when, null);
});
test('issue #10452 - invalid key', () => {
let strJSON = `[{ "key": [], "command": "firstcommand" }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding, OS);
assert.equal(keybindingItem.firstPart, null);
assert.equal(keybindingItem.chordPart, null);
});
test('issue #10452 - invalid key 2', () => {
let strJSON = `[{ "key": "", "command": "firstcommand" }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding, OS);
assert.equal(keybindingItem.firstPart, null);
assert.equal(keybindingItem.chordPart, null);
});
test('test commands args', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [], "args": { "text": "theText" } }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding, OS);
assert.equal(keybindingItem.commandArgs.text, 'theText');
});
});

View File

@@ -12,49 +12,6 @@ import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding
import { ScanCodeBinding, ScanCode } from 'vs/workbench/services/keybinding/common/scanCode';
suite('keyboardMapper - MAC fallback', () => {
//let mapper = new MacLinuxFallbackKeyboardMapper(OperatingSystem.Macintosh);
// function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
// assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh), expected);
// }
test('resolveKeybinding Cmd+Z', () => {
// _assertResolveKeybinding(
// KeyMod.CtrlCmd | KeyCode.KEY_Z,
// [{
// label: '⌘Z',
// ariaLabel: 'Command+Z',
// electronAccelerator: 'Cmd+Z',
// userSettingsLabel: 'cmd+z',
// isWYSIWYG: true,
// isChord: false,
// dispatchParts: ['meta+Z', null],
// }]
// );
});
});
suite('keyboardMapper - LINUX fallback', () => {
//let mapper = new MacLinuxFallbackKeyboardMapper(OperatingSystem.Linux);
// function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
// assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Linux), expected);
// }
test('resolveKeybinding Ctrl+Z', () => {
// _assertResolveKeybinding(
// KeyMod.CtrlCmd | KeyCode.KEY_Z,
// [{
// label: 'Ctrl+Z',
// ariaLabel: 'Control+Z',
// electronAccelerator: 'Ctrl+Z',
// userSettingsLabel: 'ctrl+z',
// isWYSIWYG: true,
// isChord: false,
// dispatchParts: ['ctrl+Z', null],
// }]
// );
});
});

View File

@@ -24,53 +24,7 @@ function createKeyboardMapper(isUSStandard: boolean, file: string, OS: Operating
}
suite('keyboardMapper - MAC de_ch', () => {
//let mapper: MacLinuxKeyboardMapper;
suiteSetup((done) => {
done();
// createKeyboardMapper(false, 'mac_de_ch', OperatingSystem.Macintosh).then((_mapper) => {
// mapper = _mapper;
// done();
// }, done);
});
test('mapping', (done) => {
done();
// assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'mac_de_ch.txt', done);
});
// function assertKeybindingTranslation(kb: number, expected: string | string[]): void {
// _assertKeybindingTranslation(mapper, OperatingSystem.Macintosh, kb, expected);
// }
// function _assertResolveKeybinding(k: number, expected: IResolvedKeybinding[]): void {
// assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Macintosh), expected);
// }
});
function _assertKeybindingTranslation(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, kb: number, _expected: string | string[]): void {
let expected: string[];
if (typeof _expected === 'string') {
expected = [_expected];
} else if (Array.isArray(_expected)) {
expected = _expected;
} else {
expected = [];
}
const runtimeKeybinding = createKeybinding(kb, OS);
const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding, OS).getUserSettingsLabel();
const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(<SimpleKeybinding>runtimeKeybinding);
if (actualHardwareKeypresses.length === 0) {
assert.deepEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`);
return;
}
const actual = actualHardwareKeypresses
.map(k => UserSettingsLabelProvider.toLabel(k, ScanCodeUtils.toString(k.scanCode), null, null, OS));
assert.deepEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`);
}

View File

@@ -43,6 +43,7 @@ import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybindin
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
import { mkdirp } from 'vs/base/node/pfs';
interface Modifiers {
metaKey?: boolean;
@@ -52,181 +53,6 @@ interface Modifiers {
}
suite('Keybindings Editing', () => {
let instantiationService: TestInstantiationService;
let testObject: KeybindingsEditingService;
let testDir: string;
let keybindingsFile;
setup(() => {
return setUpWorkspace().then(() => {
keybindingsFile = path.join(testDir, 'keybindings.json');
instantiationService = new TestInstantiationService();
instantiationService.stub(IEnvironmentService, { appKeybindingsPath: keybindingsFile });
instantiationService.stub(IConfigurationService, ConfigurationService);
instantiationService.stub(IConfigurationService, 'getConfiguration', { 'eol': '\n' });
instantiationService.stub(IConfigurationService, 'onDidUpdateConfiguration', () => { });
instantiationService.stub(IConfigurationService, 'onDidChangeConfiguration', () => { });
instantiationService.stub(IWorkspaceContextService, new TestContextService());
instantiationService.stub(ILifecycleService, new TestLifecycleService());
instantiationService.stub(IHashService, new TestHashService());
instantiationService.stub(IEditorGroupService, new TestEditorGroupService());
instantiationService.stub(ITelemetryService, NullTelemetryService);
instantiationService.stub(IModeService, ModeServiceImpl);
instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
instantiationService.stub(IFileService, new FileService(new TestContextService(new Workspace(testDir, testDir, toWorkspaceFolders([{ path: testDir }]))), new TestTextResourceConfigurationService(), new TestConfigurationService(), { disableWatcher: true }));
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));
instantiationService.stub(IBackupFileService, new TestBackupFileService());
testObject = instantiationService.createInstance(KeybindingsEditingService);
});
});
function setUpWorkspace(): TPromise<void> {
return new TPromise<void>((c, e) => {
testDir = path.join(os.tmpdir(), 'vsctests', uuid.generateUuid());
extfs.mkdirp(testDir, 493, (error) => {
if (error) {
e(error);
} else {
c(null);
}
});
});
}
teardown(() => {
return new TPromise<void>((c, e) => {
if (testDir) {
extfs.del(testDir, os.tmpdir(), () => c(null), () => c(null));
} else {
c(null);
}
}).then(() => testDir = null);
});
test('errors cases - parse errors', () => {
fs.writeFileSync(keybindingsFile, ',,,,,,,,,,,,,,');
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }))
.then(() => assert.fail('Should fail with parse errors'),
error => assert.equal(error.message, 'Unable to write keybindings. Please open **Keybindings file** to correct errors/warnings in the file and try again.'));
});
test('errors cases - parse errors 2', () => {
fs.writeFileSync(keybindingsFile, '[{"key": }]');
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }))
.then(() => assert.fail('Should fail with parse errors'),
error => assert.equal(error.message, 'Unable to write keybindings. Please open **Keybindings file** to correct errors/warnings in the file and try again.'));
});
test('errors cases - dirty', () => {
instantiationService.stub(ITextFileService, 'isDirty', true);
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }))
.then(() => assert.fail('Should fail with dirty error'),
error => assert.equal(error.message, 'Unable to write because the file is dirty. Please save the **Keybindings** file and try again.'));
});
test('errors cases - did not find an array', () => {
fs.writeFileSync(keybindingsFile, '{"key": "alt+c", "command": "hello"}');
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }))
.then(() => assert.fail('Should fail with dirty error'),
error => assert.equal(error.message, 'Unable to write keybindings. **Keybindings file** has an object which is not of type Array. Please open the file to clean up and try again.'));
});
test('edit a default keybinding to an empty file', () => {
fs.writeFileSync(keybindingsFile, '');
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit a default keybinding to a non existing keybindings file', () => {
keybindingsFile = path.join(testDir, 'nonExistingFile.json');
instantiationService.get(IEnvironmentService).appKeybindingsPath = keybindingsFile;
testObject = instantiationService.createInstance(KeybindingsEditingService);
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit a default keybinding to an empty array', () => {
writeToKeybindingsFile();
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit a default keybinding in an existing array', () => {
writeToKeybindingsFile({ command: 'b', key: 'shift+c' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'shift+c', command: 'b' }, { key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('add a new default keybinding', () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ command: 'a' }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit an user keybinding', () => {
writeToKeybindingsFile({ key: 'escape', command: 'b' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'b' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'b', isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit an user keybinding with more than one element', () => {
writeToKeybindingsFile({ key: 'escape', command: 'b' }, { key: 'alt+shift+g', command: 'c' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'b' }, { key: 'alt+shift+g', command: 'c' }];
return testObject.editKeybinding('alt+c', aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'b', isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('remove a default keybinding', () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }];
return testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('remove a user keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: 'b' });
return testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'b', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } }, isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
test('reset an edited keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: 'b' });
return testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } }, isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
test('reset a removed keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-b' });
return testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
function writeToKeybindingsFile(...keybindings: IUserFriendlyKeybinding[]) {
fs.writeFileSync(keybindingsFile, JSON.stringify(keybindings || []));
}
function getUserKeybindings(): IUserFriendlyKeybinding[] {
return json.parse(fs.readFileSync(keybindingsFile).toString('utf8'));
}
function aResolvedKeybindingItem({ command, when, isDefault, firstPart, chordPart }: { command?: string, when?: string, isDefault?: boolean, firstPart?: { keyCode: KeyCode, modifiers?: Modifiers }, chordPart?: { keyCode: KeyCode, modifiers?: Modifiers } }): ResolvedKeybindingItem {
const aSimpleKeybinding = function (part: { keyCode: KeyCode, modifiers?: Modifiers }): SimpleKeybinding {
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
return new SimpleKeybinding(ctrlKey, shiftKey, altKey, metaKey, part.keyCode);
};
const keybinding = firstPart ? chordPart ? new ChordKeybinding(aSimpleKeybinding(firstPart), aSimpleKeybinding(chordPart)) : aSimpleKeybinding(firstPart) : null;
return new ResolvedKeybindingItem(keybinding ? new USLayoutResolvedKeybinding(keybinding, OS) : null, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === void 0 ? true : isDefault);
}
});

View File

@@ -14,28 +14,7 @@ import { ScanCodeBinding, ScanCode } from 'vs/workbench/services/keybinding/comm
const WRITE_FILE_IF_DIFFERENT = false;
function createKeyboardMapper(isUSStandard: boolean, file: string): TPromise<WindowsKeyboardMapper> {
return readRawMapping<IWindowsKeyboardMapping>(file).then((rawMappings) => {
return new WindowsKeyboardMapper(isUSStandard, rawMappings);
});
}
function _assertResolveKeybinding(mapper: WindowsKeyboardMapper, k: number, expected: IResolvedKeybinding[]): void {
assertResolveKeybinding(mapper, createKeybinding(k, OperatingSystem.Windows), expected);
}
suite('keyboardMapper - WINDOWS de_ch', () => {
//let mapper: WindowsKeyboardMapper;
suiteSetup((done) => {
done();
// createKeyboardMapper(false, 'win_de_ch').then((_mapper) => {
// mapper = _mapper;
// done();
// }, done);
});
test('mapping', (done) => {
done();
});