Skip to content

Commit

Permalink
map keys from US keyboard to other layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
guillermooo committed Dec 2, 2015
1 parent 9db9fa3 commit b4ead66
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 3 deletions.
2 changes: 2 additions & 0 deletions extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ export function activate(context: vscode.ExtensionContext) {

registerCommand(context, 'extension.vim_<', () => handleKeyEvent("<"));
registerCommand(context, 'extension.vim_>', () => handleKeyEvent(">"));

registerCommand(context, 'extension.vim_backslash', () => handleKeyEvent("\\"));
}

function registerCommand(context: vscode.ExtensionContext, command: string, callback: (...args: any[]) => any) {
Expand Down
15 changes: 13 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
{ "key": "Shift+;", "command": "extension.vim_colon", "when": "editorTextFocus" },
{ "key": ":", "command": "extension.vim_colon", "when": "editorTextFocus" },
{ "key": "space", "command": "extension.vim_space", "when": "editorTextFocus" },
{ "key": "\\", "command": "extension.vim_backslash", "when": "editorTextFocus" },

{ "key": "a", "command": "extension.vim_a", "when": "editorTextFocus" },
{ "key": "b", "command": "extension.vim_b", "when": "editorTextFocus" },
Expand Down Expand Up @@ -120,8 +121,18 @@

{ "key": "Shift+,", "command": "extension.vim_<", "when": "editorTextFocus" },
{ "key": "Shift+.", "command": "extension.vim_>", "when": "editorTextFocus" }

]
],
"configuration": {
"title": "Vim Configuration",
"type": "object",
"properties": {
"vim.keyboardLayout": {
"default": "en-US (QWERTY)",
"type": "string",
"description": "Keyboard layout to use to translated key presses."
}
}
}
},
"scripts": {
"vscode:prepublish": "node ./node_modules/vscode/bin/compile",
Expand Down
15 changes: 15 additions & 0 deletions src/configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {KeyboardLayout} from "./keyboard";

export default class Configuration {

keyboardLayout : KeyboardLayout;

constructor(keyboard : KeyboardLayout) {
this.keyboardLayout = keyboard;
}

static fromUserFile() {
// TODO: read .vimrc or a similar file.
return new Configuration(KeyboardLayout.fromUserConfiguration());
}
}
58 changes: 58 additions & 0 deletions src/keyboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as vscode from "vscode";

export class KeyboardLayout {
private mapper : KeyMapper;

constructor(mapper? : KeyMapper) {
this.mapper = mapper;
}

get name() : string {
return this.mapper ? this.mapper.name : "en-US (QWERTY)";
}

resolve (key : string) : string {
return this.mapper ? this.mapper.resolve(key) : key;
}

static fromUserConfiguration() : KeyboardLayout {
const layout = vscode.workspace.getConfiguration('vim').get("keyboardLayout");

console.log("Using Vim keyboard layout: " + layout);

switch (layout) {
case 'es-ES (QWERTY)':
return new KeyboardLayout(new KeyMapperEsEsQwerty());

default:
return new KeyboardLayout();
}
}
}

export interface KeyMapper {
name : string;
resolve(key : string) : string;
}

class KeyMapperEsEsQwerty implements KeyMapper {

private mappings = {};

constructor() {
this.mappings = {
'>': ':',
// '\\': '<', // doesn't really work; in my keyboard there are two keys for \ in US
';': 'ñ',
"'": "´"
};
}

get name() : string {
return 'es-ES';
}

resolve(key : string) : string {
return this.mappings[key] || key;
}
}
7 changes: 6 additions & 1 deletion src/mode/modeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import {Mode, ModeName} from './mode';
import NormalMode from './modeNormal';
import InsertMode from './modeInsert';
import VisualMode from './modeVisual';
import Configuration from '../configuration';

export default class ModeHandler {
private modes : Mode[];
private statusBarItem : vscode.StatusBarItem;
configuration : Configuration;

constructor() {
this.configuration = Configuration.fromUserFile();

this.modes = [
new NormalMode(),
new InsertMode(),
Expand Down Expand Up @@ -38,8 +42,9 @@ export default class ModeHandler {
}

handleKeyEvent(key : string) : void {
var currentModeName = this.currentMode.Name;
key = this.configuration.keyboardLayout.resolve(key);

var currentModeName = this.currentMode.Name;
var nextMode : Mode;
var inactiveModes = _.filter(this.modes, (m) => !m.IsActive);

Expand Down
40 changes: 40 additions & 0 deletions test/keyboard.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// The module 'assert' provides assertion methods from node
import * as assert from 'assert';
import {KeyboardLayout, KeyMapper} from '../src/keyboard';

suite("KeyboardLayout", () => {

test("ctor", () => {
const layout = new KeyboardLayout();
assert.equal(layout.name, "en-US (QWERTY)");
});

test("lets keys through if using default layout", () => {
const layout = new KeyboardLayout();
assert.equal(layout.resolve('>'), '>');
assert.equal(layout.resolve(':'), ':');
assert.equal(layout.resolve('.'), '.');
});

test("can use custom mapper", () => {
class FakeMapper implements KeyMapper {
get name() : string {
return "fake mapper";
}

resolve(key : string) : string {
return "fake key";
}
}

const layout = new KeyboardLayout(new FakeMapper());
assert.equal(layout.name, "fake mapper");
assert.equal(layout.resolve('>'), 'fake key');
assert.equal(layout.resolve(':'), 'fake key');
assert.equal(layout.resolve('.'), 'fake key');
});
});

suite("KeyMapperEsEsQwerty", () => {
// TODO: cannot set settings from api?
});

0 comments on commit b4ead66

Please sign in to comment.