From 74aa98c937ad6ecbb7dea67928d03dd60fdeb1bd Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 13 May 2016 03:37:34 +0400 Subject: [PATCH] [vim] fix insert mode repeat after delete --- lib/ace/keyboard/vim.js | 32 +++++++++++++++++++------------- lib/ace/keyboard/vim_test.js | 10 +++++++++- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/ace/keyboard/vim.js b/lib/ace/keyboard/vim.js index b8bf24c97f9..32a5bf4b973 100644 --- a/lib/ace/keyboard/vim.js +++ b/lib/ace/keyboard/vim.js @@ -154,17 +154,15 @@ define(function(require, exports, module) { return this.ace.inVirtualSelectionMode && this.ace.selection.index; }; this.onChange = function(delta) { - if (delta.action[0] == 'i') { - var change = { text: delta.lines }; - var curOp = this.curOp = this.curOp || {}; - if (!curOp.changeHandlers) - curOp.changeHandlers = this._eventRegistry["change"] && this._eventRegistry["change"].slice(); - if (this.virtualSelectionMode()) return; - if (!curOp.lastChange) { - curOp.lastChange = curOp.change = change; - } else { - curOp.lastChange.next = curOp.lastChange = change; - } + var change = { text: delta.action[0] == 'i' ? delta.lines : [] }; + var curOp = this.curOp = this.curOp || {}; + if (!curOp.changeHandlers) + curOp.changeHandlers = this._eventRegistry["change"] && this._eventRegistry["change"].slice(); + if (this.virtualSelectionMode()) return; + if (!curOp.lastChange) { + curOp.lastChange = curOp.change = change; + } else { + curOp.lastChange.next = curOp.lastChange = change; } this.$updateMarkers(delta); }; @@ -5001,7 +4999,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } } } - throw Error('No such mapping.'); + // throw Error('No such mapping.'); } }; @@ -5699,6 +5697,10 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (changeObj.origin == '+input' || changeObj.origin == 'paste' || changeObj.origin === undefined /* only in testing */) { var text = changeObj.text.join('\n'); + if (lastChange.maybeReset) { + lastChange.changes = []; + lastChange.maybeReset = false; + } lastChange.changes.push(text); } // Change objects may be chained with next. @@ -5721,7 +5723,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ lastChange.expectCursorActivityForChange = false; } else { // Cursor moved outside the context of an edit. Reset the change. - lastChange.changes = []; + lastChange.maybeReset = true; } } else if (!cm.curOp.isVimOp) { handleExternalSelection(cm, vim); @@ -5785,6 +5787,10 @@ dom.importCssString(".normal-mode .ace_cursor{\ var keyName = CodeMirror.keyName(e); if (!keyName) { return; } function onKeyFound() { + if (lastChange.maybeReset) { + lastChange.changes = []; + lastChange.maybeReset = false; + } lastChange.changes.push(new InsertModeKey(keyName)); return true; } diff --git a/lib/ace/keyboard/vim_test.js b/lib/ace/keyboard/vim_test.js index c9c1543d767..c1da39086d3 100644 --- a/lib/ace/keyboard/vim_test.js +++ b/lib/ace/keyboard/vim_test.js @@ -243,7 +243,7 @@ function testVim(name, run, opts, expectedFail) { // Record for insert mode. if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') { var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges; - if (lastChange) { + if (lastChange && (key.indexOf('Delete') != -1 || key.indexOf('Backspace') != -1)) { lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key)); } } @@ -2905,6 +2905,14 @@ testVim('._insert', function(cm, vim, helpers) { helpers.doKeys('.'); eq('testestt', cm.getValue()); helpers.assertCursorAt(0, 6); + helpers.doKeys('O'); + cm.replaceRange('xyz', cm.getCursor()); + helpers.doInsertModeKeys('Backspace'); + helpers.doInsertModeKeys('Down'); + helpers.doKeys(''); + helpers.doKeys('.'); + eq('xy\nxy\ntestestt', cm.getValue()); + helpers.assertCursorAt(1, 1); }, { value: ''}); testVim('._insert_repeat', function(cm, vim, helpers) { helpers.doKeys('i');