Skip to content

Commit

Permalink
Merge pull request #219 from Lindenk/keybindings
Browse files Browse the repository at this point in the history
Added basic support for rebinding keys.
  • Loading branch information
jpoon committed May 14, 2016
2 parents d2655e3 + 2b9b154 commit 3aee721
Show file tree
Hide file tree
Showing 11 changed files with 510 additions and 171 deletions.
103 changes: 103 additions & 0 deletions README.md
Expand Up @@ -18,6 +18,109 @@ Adjust configurations through user settings (File -> Preferences -> User Setting

* vim.keyboardLayout:
* Supported Values: `en-US (QWERTY)` (default), `es-ES (QWERTY)`, `de-DE (QWERTZ)`, `da-DK (QWERTY)`

Keybindings can be overridden for a mode by supplying a `{string: string}` object defining what key or keys should preform what action when pressed.

Note: Currently, by defining keybindings for a mode, all bindings for that mode will be overridden. This should be fixed in a future update.

Note: Currently, the escape key is still hardcoded to exit insert mode and the `v` key is still hardcoded to exit visual mode.

Example:
```json
{
"vim.normalModeKeybindings": {
"d": "DeleteChar",
"D": "DeleteLastChar"
},
"vim.insertModeKeybindings": {
"e": "InsertAtCursor",
"E": "InsertAfterCursor"
}
}
```

* vim.normalModeKeybindings
* Supported Actions:
```
MoveUp
MoveDown
MoveLeft
MoveRight
MoveLineBegin
MoveLineEnd
MoveWordBegin
MoveWordEnd
MoveFullWordBegin
MoveFullWordEnd
MoveLastWord
MoveLastFullWord
MoveLastWordEnd
MoveLastFullWordEnd
MoveFullPageUp
MoveFullPageDown
MoveParagraphBegin
MoveParagraphEnd
MoveNonBlank
MoveNonBlankFirst
MoveNonBlankLast
MoveMatchingBracket
// Find
Find
// Text Modification
Undo
Redo
Copy
Paste
ChangeWord
ChangeFullWord
ChangeCurrentWord
ChangeCurrentWordToNext
ChangeToLineEnd
DeleteLine
DeleteToNextWord
DeleteToFullNextWord
DeleteToWordEnd
DeleteToFullWordEnd
DeleteToWordBegin
DeleteToFullWordBegin
DeleteToLineEnd
DeleteChar
DeleteLastChar
Indent
Outdent
// Misc
EnterCommand
ExitMessages
```

* vim.insertModeKeybindings
* Supported Actions:
```
// Enter insert mode
InsertAtCursor
InsertAtLineBegin
InsertAfterCursor
InsertAtLineEnd
InsertNewLineBelow
InsertNewLineAbove
```

* vim.visualModeKeybindings
* Supported Actions:
```
EnterVisualMode
```

## Project Status

Expand Down
12 changes: 12 additions & 0 deletions package.json
Expand Up @@ -136,6 +136,18 @@
"default": "en-US (QWERTY)",
"type": "string",
"description": "Keyboard layout to use to translated key presses."
},
"vim.normalModeKeybindings": {
"type": "object",
"description": "Keybinding overrides to use for normal mode."
},
"vim.insertModeKeybindings": {
"type": "object",
"description": "Keybinding overrides to use for insert mode."
},
"vim.visualModeKeybindings": {
"type": "object",
"description": "Keybinding overrides to use for visual mode."
}
}
}
Expand Down
155 changes: 155 additions & 0 deletions src/mode/commands.ts
@@ -0,0 +1,155 @@

// An enum of all bindable actions in Vim
// TODO: Split off commands into normal, insert, and visual catagories
export enum Command {
// Enter insert mode
InsertAtCursor = 1,
InsertAtLineBegin,
InsertAfterCursor,
InsertAtLineEnd,
InsertNewLineBelow,
InsertNewLineAbove,

// Movement
MoveUp,
MoveDown,
MoveLeft,
MoveRight,

MoveLineBegin,
MoveLineEnd,
MoveWordBegin,
MoveWordEnd,
MoveFullWordBegin,
MoveFullWordEnd,
MoveLastWord,
MoveLastFullWord,
MoveLastWordEnd,
MoveLastFullWordEnd,

// MoveHalfPageUp,
// MoveHalfPageDown,
MoveFullPageUp,
MoveFullPageDown,
// MoveFirstLine,
// MoveLastLine,

MoveParagraphBegin,
MoveParagraphEnd,

MoveNonBlank,
MoveNonBlankFirst,
MoveNonBlankLast,
MoveMatchingBracket,

// Find
Find,

// Text Modification
Undo,
Redo,
Copy,
Paste,

ChangeWord,
ChangeFullWord,
ChangeCurrentWord,
ChangeCurrentWordToNext,
ChangeToLineEnd,

DeleteLine,
DeleteToNextWord,
DeleteToFullNextWord,
DeleteToWordEnd,
DeleteToFullWordEnd,
DeleteToWordBegin,
DeleteToFullWordBegin,
DeleteToLineEnd,

DeleteChar,
DeleteLastChar,

Indent,
Outdent,

// Misc
EnterVisualMode,
EnterCommand,
ExitMessages,
}

export function newDefaultNormalKeymap() : {[key: string]: Command} {
return {
"h": Command.MoveLeft,
"j": Command.MoveDown,
"k": Command.MoveUp,
"l": Command.MoveRight,
"0": Command.MoveLineBegin,
"$": Command.MoveLineEnd,

"^": Command.MoveNonBlank,
"gg": Command.MoveNonBlankFirst,
"G": Command.MoveNonBlankLast,

"w": Command.MoveWordBegin,
"W": Command.MoveFullWordBegin,
"e": Command.MoveWordEnd,
"E": Command.MoveLastFullWordEnd,
"ge": Command.MoveLastWordEnd,
"gE": Command.MoveLastFullWordEnd,
"b": Command.MoveLastWord,
"B": Command.MoveLastFullWord,

"{": Command.MoveParagraphBegin,
"}": Command.MoveParagraphEnd,
"%": Command.MoveMatchingBracket,

">>": Command.Indent,
"<<": Command.Outdent,

"u": Command.Undo,
"ctrl+r": Command.Redo,
"y": Command.Copy,
"p": Command.Paste,

"cw": Command.ChangeWord,
"cW": Command.ChangeFullWord,
"ciw": Command.ChangeCurrentWord,
"caw": Command.ChangeCurrentWordToNext,
"C": Command.ChangeToLineEnd,

"dd": Command.DeleteLine,
"dw": Command.DeleteToNextWord,
"dW": Command.DeleteToFullNextWord,
"db": Command.DeleteToWordBegin,
"dB": Command.DeleteToFullWordBegin,
"de": Command.DeleteToWordEnd,
"dE": Command.DeleteToFullWordEnd,
"D" : Command.DeleteToLineEnd,

"x": Command.DeleteChar,
"X": Command.DeleteLastChar,

"/": Command.Find,
":": Command.EnterCommand,
"v": Command.EnterVisualMode,
"esc": Command.ExitMessages
};
}

export function newDefaultInsertKeymap() : {[key: string]: Command} {
return {
"i": Command.InsertAtCursor,
"I": Command.InsertAtLineBegin,
"a": Command.InsertAfterCursor,
"A": Command.InsertAtLineEnd,
"o": Command.InsertNewLineBelow,
"O": Command.InsertNewLineAbove,
};
}

export function newDefaultVisualKeymap() : {[key: string]: Command} {
return {
"v": Command.EnterVisualMode
};
}
5 changes: 4 additions & 1 deletion src/mode/mode.ts
@@ -1,5 +1,6 @@
"use strict";

import {Command} from './commands';
import {Motion} from './../motion/motion';
import {Position} from './../motion/position';

Expand All @@ -14,12 +15,14 @@ export abstract class Mode {
private _name : ModeName;
private _motion : Motion;
protected _keyHistory : string[];
protected _keymap : {[key: string]: Command};

constructor(name: ModeName, motion: Motion) {
constructor(name: ModeName, motion: Motion, keymap: {[key: string]: Command}) {
this._name = name;
this._motion = motion;
this._isActive = false;
this._keyHistory = [];
this._keymap = keymap;
}

get name(): ModeName {
Expand Down
16 changes: 13 additions & 3 deletions src/mode/modeHandler.ts
Expand Up @@ -3,6 +3,7 @@
import * as _ from 'lodash';
import * as vscode from 'vscode';

import * as cmds from './commands';
import {Mode, ModeName} from './mode';
import {Motion, MotionMode} from './../motion/motion';
import {NormalMode} from './modeNormal';
Expand All @@ -19,11 +20,20 @@ export class ModeHandler implements vscode.Disposable {
constructor() {
this._configuration = Configuration.fromUserFile();

// This probably should be somewhere else but will work for now.
// TODO: Only override default settings specified instead of all of them
let normalKeymap = vscode.workspace.getConfiguration("vim")
.get("normalModeKeybindings", cmds.newDefaultNormalKeymap());
let insertKeymap = vscode.workspace.getConfiguration("vim")
.get("insertModeKeybindings", cmds.newDefaultInsertKeymap());
let visualKeymap = vscode.workspace.getConfiguration("vim")
.get("visualModeKeybindings", cmds.newDefaultVisualKeymap());

this._motion = new Motion(null);
this._modes = [
new NormalMode(this._motion, this),
new InsertMode(this._motion),
new VisualMode(this._motion, this),
new NormalMode(this._motion, this, normalKeymap),
new InsertMode(this._motion, insertKeymap),
new VisualMode(this._motion, this, visualKeymap),
];

this.setCurrentModeByName(ModeName.Normal);
Expand Down

0 comments on commit 3aee721

Please sign in to comment.