Skip to content

Commit

Permalink
Add visualModesKeyBindings
Browse files Browse the repository at this point in the history
  • Loading branch information
chibicode committed Jun 13, 2018
1 parent d6c61bc commit fe42d41
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 3 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ Here's some ideas on what you can do with neovim integration:

There's several different mechanisms you can use to define custom remappings. Also see the [`useCtrlKeys`](#vimusectrlkeys) and [`handleKeys`](#vimhandlekeys) settings.

#### `"vim.insertModeKeyBindings"`/`"vim.otherModesKeyBindings"`
#### `"vim.insertModeKeyBindings"`/`"vim.otherModesKeyBindings"`/`"vim.visualModesKeyBindings"`

* Keybinding overrides to use for insert and other (non-insert) modes.
* Keybinding overrides to use for insert, visual and other (non-insert) modes.
* Bind `jj` to `<Esc>` in insert mode:

```json
Expand Down Expand Up @@ -316,7 +316,7 @@ There's several different mechanisms you can use to define custom remappings. Al
]
```

#### `"vim.insertModeKeyBindingsNonRecursive"`/`"otherModesKeyBindingsNonRecursive"`
#### `"vim.insertModeKeyBindingsNonRecursive"`/`"otherModesKeyBindingsNonRecursive"`/`"visualModesKeyBindingsNonRecursive"`

* Non-recursive keybinding overrides to use for insert and other (non-insert) modes (similar to `:noremap`)
* *Example:* Bind `j` to `gj`. Notice that if you attempted this binding normally, the j in gj would be expanded into gj, on and on forever. Stop this recursive expansion using insertModeKeyBindingsNonRecursive and/or otherModesKeyBindingNonRecursive.
Expand Down
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,14 @@
"type": "array",
"description": "Non-recursive keybinding overrides to use for insert mode. Allows mapping to vim commands or vscode actions. See README for more."
},
"vim.visualModeKeyBindings": {
"type": "array",
"description": "Remapped keys in visual mode. Allows mapping to vim commands or vscode actions. See README for more."
},
"vim.visualModeKeyBindingsNonRecursive": {
"type": "array",
"description": "Non-recursive keybinding overrides to use for visual mode. Allows mapping to vim commands or vscode actions. See README for more."
},
"vim.textwidth": {
"type": "number",
"description": "Width to word-wrap to when using gq.",
Expand Down
4 changes: 4 additions & 0 deletions src/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ class Configuration implements IConfiguration {
this.insertModeKeyBindingsNonRecursive,
this.otherModesKeyBindings,
this.otherModesKeyBindingsNonRecursive,
this.visualModesKeyBindings,
this.visualModesKeyBindingsNonRecursive,
];
for (const keybindings of keybindingList) {
for (let remapping of keybindings) {
Expand Down Expand Up @@ -331,6 +333,8 @@ class Configuration implements IConfiguration {
insertModeKeyBindingsNonRecursive: IKeyRemapping[] = [];
otherModesKeyBindings: IKeyRemapping[] = [];
otherModesKeyBindingsNonRecursive: IKeyRemapping[] = [];
visualModesKeyBindings: IKeyRemapping[] = [];
visualModesKeyBindingsNonRecursive: IKeyRemapping[] = [];
}

function overlapSetting(args: {
Expand Down
2 changes: 2 additions & 0 deletions src/configuration/iconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,6 @@ export interface IConfiguration {
insertModeKeyBindingsNonRecursive: IKeyRemapping[];
otherModesKeyBindings: IKeyRemapping[];
otherModesKeyBindingsNonRecursive: IKeyRemapping[];
visualModesKeyBindings: IKeyRemapping[];
visualModesKeyBindingsNonRecursive: IKeyRemapping[];
}
12 changes: 12 additions & 0 deletions src/configuration/remapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ export class Remappers implements IRemapper {
this.remappers = [
new InsertModeRemapper(true),
new OtherModesRemapper(true),
new VisualModesRemapper(true),
new InsertModeRemapper(false),
new OtherModesRemapper(false),
new VisualModesRemapper(false),
];
}

Expand Down Expand Up @@ -205,3 +207,13 @@ class OtherModesRemapper extends Remapper {
);
}
}

class VisualModesRemapper extends Remapper {
constructor(recursive: boolean) {
super(
'visualModesKeyBindings' + (recursive ? '' : 'NonRecursive'),
[ModeName.Visual, ModeName.VisualLine, ModeName.VisualBlock],
recursive
);
}
}
45 changes: 45 additions & 0 deletions test/configuration/remapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,25 @@ suite('Remapper', () => {
],
},
];
const visualModeKeyBindings = [
{
before: ['leader', 'w'],
after: [],
commands: [
{
command: 'workbench.action.closeActiveEditor',
args: [],
},
],
},
];

setup(async () => {
let configuration = new Configuration();
configuration.leader = leaderKey;
configuration.insertModeKeyBindings = insertModeKeyBindings;
configuration.otherModesKeyBindings = otherModeKeysRebindings;
configuration.visualModesKeyBindings = visualModeKeyBindings;

await setupWorkspace(configuration);
modeHandler = await getAndUpdateModeHandler();
Expand Down Expand Up @@ -78,4 +91,36 @@ suite('Remapper', () => {
assert.equal(actual, true);
assert.equal(vscode.window.visibleTextEditors.length, 0);
});

test('remapped command with leader, only on visual mode', async () => {
// setup - normal mode
let remapper = new Remappers();
assertEqual(modeHandler.currentMode.name, ModeName.Normal);

// act
try {
await remapper.sendKey([leaderKey, 'w'], modeHandler, modeHandler.vimState);
} catch (e) {
assert.ok(true);
}

// assert
assert.equal(vscode.window.visibleTextEditors.length, 1);

// setup - visual mode
await modeHandler.handleKeyEvent('v');
assertEqual(modeHandler.currentMode.name, ModeName.Visual);

// act
let actual = false;
try {
actual = await remapper.sendKey([leaderKey, 'w'], modeHandler, modeHandler.vimState);
} catch (e) {
assert.fail(e);
}

// assert
assert.equal(actual, true);
assert.equal(vscode.window.visibleTextEditors.length, 0);
});
});
2 changes: 2 additions & 0 deletions test/testConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,6 @@ export class Configuration implements IConfiguration {
insertModeKeyBindingsNonRecursive: IKeyRemapping[] = [];
otherModesKeyBindings: IKeyRemapping[] = [];
otherModesKeyBindingsNonRecursive: IKeyRemapping[] = [];
visualModesKeyBindings: IKeyRemapping[] = [];
visualModesKeyBindingsNonRecursive: IKeyRemapping[] = [];
}

0 comments on commit fe42d41

Please sign in to comment.