Skip to content

Commit 84dc2d0

Browse files
lukegbmarijnh
authored andcommitted
[vim bindings] Make Backspace delete characters
In Replace mode (or Overwrite mode) it should still go backwards without deleting characters.
1 parent a0547b7 commit 84dc2d0

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

keymap/vim.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
{ keys: '<Down>', type: 'keyToKey', toKeys: 'j' },
5454
{ keys: '<Space>', type: 'keyToKey', toKeys: 'l' },
5555
{ keys: '<BS>', type: 'keyToKey', toKeys: 'h', context: 'normal'},
56-
{ keys: '<BS>', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }, context: 'insert'},
5756
{ keys: '<C-Space>', type: 'keyToKey', toKeys: 'W' },
5857
{ keys: '<C-BS>', type: 'keyToKey', toKeys: 'B', context: 'normal' },
5958
{ keys: '<S-Space>', type: 'keyToKey', toKeys: 'w' },
@@ -73,6 +72,7 @@
7372
{ keys: '<PageUp>', type: 'keyToKey', toKeys: '<C-b>' },
7473
{ keys: '<PageDown>', type: 'keyToKey', toKeys: '<C-f>' },
7574
{ keys: '<CR>', type: 'keyToKey', toKeys: 'j^', context: 'normal' },
75+
{ keys: '<Ins>', type: 'action', action: 'toggleOverwrite', context: 'insert' },
7676
// Motions
7777
{ keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }},
7878
{ keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }},
@@ -277,6 +277,7 @@
277277

278278
function cmKey(key, cm) {
279279
if (!cm) { return undefined; }
280+
if (this[key]) { return this[key]; }
280281
var vimKey = cmKeyToVimKey(key);
281282
if (!vimKey) {
282283
return false;
@@ -289,7 +290,7 @@
289290
}
290291

291292
var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'};
292-
var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del'};
293+
var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'};
293294
function cmKeyToVimKey(key) {
294295
if (key.charAt(0) == '\'') {
295296
// Keypress character binding of format "'a'"
@@ -2175,6 +2176,17 @@
21752176
var registerName = actionArgs.selectedCharacter;
21762177
macroModeState.enterMacroRecordMode(cm, registerName);
21772178
},
2179+
toggleOverwrite: function(cm) {
2180+
if (!cm.state.overwrite) {
2181+
cm.toggleOverwrite(true);
2182+
cm.setOption('keyMap', 'vim-replace');
2183+
CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
2184+
} else {
2185+
cm.toggleOverwrite(false);
2186+
cm.setOption('keyMap', 'vim-insert');
2187+
CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
2188+
}
2189+
},
21782190
enterInsertMode: function(cm, actionArgs, vim) {
21792191
if (cm.getOption('readOnly')) { return; }
21802192
vim.insertMode = true;
@@ -2220,14 +2232,14 @@
22202232
return;
22212233
}
22222234
}
2223-
cm.setOption('keyMap', 'vim-insert');
22242235
cm.setOption('disableInput', false);
22252236
if (actionArgs && actionArgs.replace) {
22262237
// Handle Replace-mode as a special case of insert mode.
22272238
cm.toggleOverwrite(true);
22282239
cm.setOption('keyMap', 'vim-replace');
22292240
CodeMirror.signal(cm, "vim-mode-change", {mode: "replace"});
22302241
} else {
2242+
cm.toggleOverwrite(false);
22312243
cm.setOption('keyMap', 'vim-insert');
22322244
CodeMirror.signal(cm, "vim-mode-change", {mode: "insert"});
22332245
}
@@ -4779,6 +4791,7 @@
47794791
};
47804792

47814793
CodeMirror.keyMap['vim-replace'] = {
4794+
'Backspace': 'goCharLeft',
47824795
fallthrough: ['vim-insert'],
47834796
attach: attachVimMap,
47844797
detach: detachVimMap,

test/vim_test.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function testVim(name, run, opts, expectedFail) {
145145
for (var i = 0; i < arguments.length; i++) {
146146
var key = arguments[i];
147147
// Find key in keymap and handle.
148-
var handled = CodeMirror.lookupKey(key, 'vim-insert', executeHandler);
148+
var handled = CodeMirror.lookupKey(key, cm.getOption('keyMap'), executeHandler, cm);
149149
// Record for insert mode.
150150
if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') {
151151
var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges;
@@ -1419,6 +1419,32 @@ testVim('i_repeat_delete', function(cm, vim, helpers) {
14191419
eq('abe', cm.getValue());
14201420
helpers.assertCursorAt(0, 1);
14211421
}, { value: 'abcde' });
1422+
testVim('insert', function(cm, vim, helpers) {
1423+
helpers.doKeys('i');
1424+
eq('vim-insert', cm.getOption('keyMap'));
1425+
eq(false, cm.state.overwrite);
1426+
helpers.doKeys('<Ins>');
1427+
eq('vim-replace', cm.getOption('keyMap'));
1428+
eq(true, cm.state.overwrite);
1429+
helpers.doKeys('<Ins>');
1430+
eq('vim-insert', cm.getOption('keyMap'));
1431+
eq(false, cm.state.overwrite);
1432+
});
1433+
testVim('i_backspace', function(cm, vim, helpers) {
1434+
cm.setCursor(0, 10);
1435+
helpers.doKeys('i');
1436+
helpers.doInsertModeKeys('Backspace');
1437+
helpers.assertCursorAt(0, 9);
1438+
eq('012345678', cm.getValue());
1439+
}, { value: '0123456789'});
1440+
testVim('i_overwrite_backspace', function(cm, vim, helpers) {
1441+
cm.setCursor(0, 10);
1442+
helpers.doKeys('i');
1443+
helpers.doKeys('<Ins>');
1444+
helpers.doInsertModeKeys('Backspace');
1445+
helpers.assertCursorAt(0, 9);
1446+
eq('0123456789', cm.getValue());
1447+
}, { value: '0123456789'});
14221448
testVim('A', function(cm, vim, helpers) {
14231449
helpers.doKeys('A');
14241450
helpers.assertCursorAt(0, lines[0].length);

0 commit comments

Comments
 (0)