From 99be8ebdb5d9d355e663e0845d1a1966c08b8fef Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Wed, 11 Mar 2015 12:37:11 +0000 Subject: [PATCH 01/11] fix #565 : cursor motion in insert mode should affect `.` --- keymaps/vim-mode.cson | 4 ++++ lib/operators/general-operators.coffee | 6 +++++- lib/operators/input.coffee | 8 ++++++++ lib/vim-state.coffee | 15 +++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/keymaps/vim-mode.cson b/keymaps/vim-mode.cson index 1a58c494..2c0435af 100644 --- a/keymaps/vim-mode.cson +++ b/keymaps/vim-mode.cson @@ -13,6 +13,10 @@ 'atom-text-editor.vim-mode.insert-mode': 'ctrl-w': 'editor:delete-to-beginning-of-word' 'ctrl-u': 'editor:delete-to-beginning-of-line' + 'left': 'vim-mode:move-left-insert' + 'right': 'vim-mode:move-right-insert' + 'up': 'vim-mode:move-up-insert' + 'down': 'vim-mode:move-down-insert' 'atom-text-editor.vim-mode:not(.insert-mode)': 'h': 'vim-mode:move-left' diff --git a/lib/operators/general-operators.coffee b/lib/operators/general-operators.coffee index dd992561..775d3713 100644 --- a/lib/operators/general-operators.coffee +++ b/lib/operators/general-operators.coffee @@ -230,8 +230,12 @@ class Repeat extends Operator execute: (count=1) -> @editor.transact => - _.times count, => + cmd = @vimState.history[0] + while cmd?.cancelled + @vimState.history.shift() cmd = @vimState.history[0] + + _.times count, => cmd?.execute() # # It creates a mark at the current cursor position diff --git a/lib/operators/input.coffee b/lib/operators/input.coffee index 3e5db4a3..e428e169 100644 --- a/lib/operators/input.coffee +++ b/lib/operators/input.coffee @@ -28,6 +28,13 @@ class Insert extends Operator inputOperator: -> true +class InsertCancellable extends Insert + cancelled: false + + confirmTransaction: (transaction) -> + super + @cancelled = true if @typedText?.length == 0 + class InsertAfter extends Insert execute: -> @editor.moveRight() unless @editor.getLastCursor().isAtEndOfLine() @@ -189,6 +196,7 @@ module.exports = { InsertAtBeginningOfLine, InsertAboveWithNewline, InsertBelowWithNewline, + InsertCancellable, Change, Substitute, SubstituteLine diff --git a/lib/vim-state.coffee b/lib/vim-state.coffee index 22109a4b..68839d0c 100644 --- a/lib/vim-state.coffee +++ b/lib/vim-state.coffee @@ -103,6 +103,10 @@ class VimState 'move-up': => new Motions.MoveUp(@editor, this) 'move-down': => new Motions.MoveDown(@editor, this) 'move-right': => new Motions.MoveRight(@editor, this) + 'move-left-insert': => @interruptInsertMode(); [new Motions.MoveLeft(@editor, this), new Operators.InsertCancellable(@editor, this)] + 'move-up-insert': => @interruptInsertMode(); [new Motions.MoveUp(@editor, this), new Operators.InsertCancellable(@editor, this)] + 'move-down-insert': => @interruptInsertMode(); [new Motions.MoveDown(@editor, this), new Operators.InsertCancellable(@editor, this)] + 'move-right-insert': => @interruptInsertMode(); [new Motions.MoveRight(@editor, this), new Operators.InsertCancellable(@editor, this)] 'move-to-next-word': => new Motions.MoveToNextWord(@editor, this) 'move-to-next-whole-word': => new Motions.MoveToNextWholeWord(@editor, this) 'move-to-end-of-word': => new Motions.MoveToEndOfWord(@editor, this) @@ -414,6 +418,17 @@ class VimState for cursor in @editor.getCursors() cursor.moveLeft() unless cursor.isAtBeginningOfLine() + interruptInsertMode: -> + return unless @mode in [null, 'insert'] + @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) + @insertionCheckpoint = null + transaction = _.last(@editor.buffer.history.undoStack) + item = @inputOperator(@history[0]) + if item? and transaction? + item.confirmTransaction(transaction) + @setInsertionCheckpoint() + + deactivateVisualMode: -> return unless @mode is 'visual' for selection in @editor.getSelections() From 74ab580f301aacba09a8be9077c6d2155aefa870 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Wed, 11 Mar 2015 15:20:19 +0000 Subject: [PATCH 02/11] it's better after all for InsertCancellable to remove itself from history --- lib/operators/general-operators.coffee | 6 +----- lib/operators/input.coffee | 6 ++++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/operators/general-operators.coffee b/lib/operators/general-operators.coffee index 775d3713..dd992561 100644 --- a/lib/operators/general-operators.coffee +++ b/lib/operators/general-operators.coffee @@ -230,12 +230,8 @@ class Repeat extends Operator execute: (count=1) -> @editor.transact => - cmd = @vimState.history[0] - while cmd?.cancelled - @vimState.history.shift() - cmd = @vimState.history[0] - _.times count, => + cmd = @vimState.history[0] cmd?.execute() # # It creates a mark at the current cursor position diff --git a/lib/operators/input.coffee b/lib/operators/input.coffee index e428e169..0051b698 100644 --- a/lib/operators/input.coffee +++ b/lib/operators/input.coffee @@ -28,12 +28,14 @@ class Insert extends Operator inputOperator: -> true +# an insert operation following cursor motion in insert mode can be cancelled +# and forgotten like it never happened class InsertCancellable extends Insert - cancelled: false confirmTransaction: (transaction) -> super - @cancelled = true if @typedText?.length == 0 + if @typedText?.length == 0 + @vimState.history.shift() if @vimState.history[0] is @ class InsertAfter extends Insert execute: -> From c23873bca47500d88a40e500988ea0f5abeb23f5 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Wed, 11 Mar 2015 16:46:51 +0000 Subject: [PATCH 03/11] fix copy&paste oversight --- lib/vim-state.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vim-state.coffee b/lib/vim-state.coffee index 68839d0c..5065e9af 100644 --- a/lib/vim-state.coffee +++ b/lib/vim-state.coffee @@ -419,7 +419,7 @@ class VimState cursor.moveLeft() unless cursor.isAtBeginningOfLine() interruptInsertMode: -> - return unless @mode in [null, 'insert'] + return unless @mode is 'insert' @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) @insertionCheckpoint = null transaction = _.last(@editor.buffer.history.undoStack) From efc41771d18e2ca41e6c09a16eac05607aa2ae4a Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Thu, 26 Mar 2015 09:52:35 +0000 Subject: [PATCH 04/11] add test --- spec/operators-spec.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index ea0319fb..dfc4cd1d 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -1574,6 +1574,17 @@ describe "Operators", -> keydown '.' expect(editor.getText()).toBe "abababccc123\nabababccc4567" + it "stores for repeating only the last batch of characters", -> + keydown 'i' + editor.insertText("abc") + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + editor.insertText("de") + keydown 'escape' + expect(editor.getText()).toBe "abdec123\nabdec4567" + + keydown '.' + expect(editor.getText()).toBe "abddeec123\nabddeec4567" + describe 'the a keybinding', -> beforeEach -> editor.setText('') From 93445fca3f609186367fbc50a17d6ab6d00cf294 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Thu, 26 Mar 2015 09:56:44 +0000 Subject: [PATCH 05/11] add another test --- spec/operators-spec.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index dfc4cd1d..f33c4522 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -1608,6 +1608,18 @@ describe "Operators", -> expect(editor.getText()).toBe "abcabc" expect(editor.getCursorScreenPosition()).toEqual [0, 5] + it "stores for repeating only the last batch of characters, repeats as insert", -> + keydown 'a' + editor.insertText("abc") + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + editor.insertText("de") + keydown 'escape' + expect(editor.getText()).toBe "abdec" + expect(editor.getCursorScreenPosition()).toEqual [0, 3] + keydown '.' + expect(editor.getText()).toBe "abddeec" + expect(editor.getCursorScreenPosition()).toEqual [0, 4] + describe "the ctrl-a/ctrl-x keybindings", -> beforeEach -> atom.config.set 'vim-mode.numberRegex', settings.config.numberRegex.default From 44db89aad1818c86e0ad2797589179ac54a55bd5 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Mon, 6 Apr 2015 22:39:02 +0100 Subject: [PATCH 06/11] insert with count Repeated insert such as `3i` and `3a` now works. Also, `.` with a count (such as `3.`) now changes the old prefix: * for example `2dd3.` will delete 2 and then 3 lines, a subsequent `.` will again delete 3 lines; * similarly `dl3.` will delete a character and then 3 more, a subsequent `.` will again delete 3 characters. --- lib/operators/general-operators.coffee | 22 +++++-- lib/operators/input.coffee | 17 +++-- lib/vim-state.coffee | 8 +-- spec/operators-spec.coffee | 87 +++++++++++++++++++++++++- 4 files changed, 119 insertions(+), 15 deletions(-) diff --git a/lib/operators/general-operators.coffee b/lib/operators/general-operators.coffee index dd992561..a8bb4865 100644 --- a/lib/operators/general-operators.coffee +++ b/lib/operators/general-operators.coffee @@ -1,6 +1,7 @@ _ = require 'underscore-plus' {Point, Range} = require 'atom' {ViewModel} = require '../view-models/view-model' +Prefixes = require '../prefixes' Utils = require '../utils' settings = require '../settings' @@ -228,11 +229,24 @@ class Repeat extends Operator isRecordable: -> false - execute: (count=1) -> + execute: (count) -> + return unless (cmd = @vimState.history[0])? + @editor.transact => - _.times count, => - cmd = @vimState.history[0] - cmd?.execute() + + if count? + # try to propagate prefix to inner operation + if cmd instanceof Prefixes.Repeat + cmd.count = count + else if cmd.motion instanceof Prefixes.Repeat + cmd.motion.count = count + else + repeat = new Prefixes.Repeat(count) + repeat.compose(cmd) + cmd = @vimState.history[0] = repeat + + cmd.execute() + # # It creates a mark at the current cursor position # diff --git a/lib/operators/input.coffee b/lib/operators/input.coffee index 0051b698..b88d6a36 100644 --- a/lib/operators/input.coffee +++ b/lib/operators/input.coffee @@ -8,17 +8,22 @@ settings = require '../settings' # tells the operation to repeat itself instead of enter insert mode. class Insert extends Operator standalone: true + count: 1 isComplete: -> @standalone or super - confirmChanges: (changes) -> + confirmChanges: (changes, interrupted) -> bundler = new TransactionBundler(changes) @typedText = bundler.buildInsertText() + if @count > 1 and not interrupted + @editor.insertText(@typedText) for i in [2..@count] - execute: -> + execute: (count) -> + @count = count if count? if @typingCompleted return unless @typedText? and @typedText.length > 0 - @editor.insertText(@typedText, normalizeLineEndings: true) + @editor.transact => + @editor.insertText(@typedText, normalizeLineEndings: true) for i in [1..@count] for cursor in @editor.getCursors() cursor.moveLeft() unless cursor.isAtBeginningOfLine() else @@ -112,7 +117,7 @@ class Change extends Insert for selection in @editor.getSelections() selection.deleteSelectedText() - return super if @typingCompleted + return super(1) if @typingCompleted @vimState.activateInsertMode() @typingCompleted = true @@ -132,7 +137,7 @@ class Substitute extends Insert if @typingCompleted @typedText = @typedText.trimLeft() - return super + return super(1) @vimState.activateInsertMode() @typingCompleted = true @@ -156,7 +161,7 @@ class SubstituteLine extends Insert if @typingCompleted @typedText = @typedText.trimLeft() - return super + return super(1) @vimState.activateInsertMode() @typingCompleted = true diff --git a/lib/vim-state.coffee b/lib/vim-state.coffee index 5065e9af..1c613f5c 100644 --- a/lib/vim-state.coffee +++ b/lib/vim-state.coffee @@ -421,11 +421,11 @@ class VimState interruptInsertMode: -> return unless @mode is 'insert' @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) - @insertionCheckpoint = null - transaction = _.last(@editor.buffer.history.undoStack) + changes = getChangesSinceCheckpoint(@editor.buffer, @insertionCheckpoint) item = @inputOperator(@history[0]) - if item? and transaction? - item.confirmTransaction(transaction) + @insertionCheckpoint = null + if item? + item.confirmChanges(changes, interrupted: true) @setInsertionCheckpoint() diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index f33c4522..d1244ff9 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -235,6 +235,20 @@ describe "Operators", -> keydown('.') expect(editor.getText()).toBe 'abab' + it "is repeatable with a new count", -> + keydown('3') + keydown('s') + editor.insertText("ab") + keydown('escape') + expect(editor.getText()).toBe '0ab45' + keydown('1') + keydown('.') + expect(editor.getText()).toBe '0aab45' + editor.setCursorScreenPosition([0, 0]) + keydown('3') + keydown('.') + expect(editor.getText()).toBe 'abb45' + it "is undoable", -> editor.setCursorScreenPosition([0, 0]) keydown('3') @@ -1373,7 +1387,7 @@ describe "Operators", -> expect(editor.getText()).toBe "" - it "composes with motions", -> + it "composes with prefix", -> keydown 'd' keydown 'd' keydown '2' @@ -1381,6 +1395,25 @@ describe "Operators", -> expect(editor.getText()).toBe "78" + it "changes previous prefix", -> + keydown '2' + keydown 'd' + keydown 'd' + keydown '1' + keydown '.' + + expect(editor.getText()).toBe "78" + + it "adds prefix if none was there", -> + keydown 'd' + keydown 'd' + keydown 'u' + keydown '2' + keydown '.' + keydown '.' + + expect(editor.getText()).toBe "" + describe "the r keybinding", -> beforeEach -> editor.setText("12\n34\n\n") @@ -1560,6 +1593,29 @@ describe "Operators", -> keydown 'u' expect(editor.getText()).toBe "123\n4567" + it "allows count prefix", -> + keydown '3' + keydown 'i' + editor.insertText("abc") + keydown 'escape' + expect(editor.getText()).toBe "abcabcabc123\nabcabcabc4567" + + keydown 'u' + expect(editor.getText()).toBe "123\n4567" + + keydown '.' + keydown '.' + expect(editor.getText()).toBe "abcabcababcabcabcc123\nabcabcababcabcabcc4567" + + keydown 'u' + expect(editor.getText()).toBe "abcabcabc123\nabcabcabc4567" + + editor.setText('123\n4567') + editor.setCursorBufferPosition([0, 0]) + keydown '2' + keydown '.' + expect(editor.getText()).toBe "abcabc123\n4567" + it "allows repeating typing", -> keydown 'i' editor.insertText("abcXX") @@ -1574,7 +1630,21 @@ describe "Operators", -> keydown '.' expect(editor.getText()).toBe "abababccc123\nabababccc4567" + it "gets prefix from .", -> + keydown 'i' + editor.insertText("abc") + keydown 'escape' + expect(editor.getText()).toBe "abc123\nabc4567" + + keydown '2' + keydown '.' + expect(editor.getText()).toBe "ababcabcc123\nababcabcc4567" + + keydown '.' + expect(editor.getText()).toBe "ababcababcabccc123\nababcababcabccc4567" + it "stores for repeating only the last batch of characters", -> + keydown '2' keydown 'i' editor.insertText("abc") atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' @@ -1608,6 +1678,21 @@ describe "Operators", -> expect(editor.getText()).toBe "abcabc" expect(editor.getCursorScreenPosition()).toEqual [0, 5] + it "combines with a prefix", -> + keydown '2' + keydown 'a' + editor.insertText("abc") + keydown 'escape' + expect(editor.getText()).toBe "abcabc" + expect(editor.getCursorScreenPosition()).toEqual [0, 5] + keydown '.' + expect(editor.getText()).toBe "abcabcabcabc" + expect(editor.getCursorScreenPosition()).toEqual [0, 11] + keydown '1' + keydown '.' + expect(editor.getText()).toBe "abcabcabcabcabc" + expect(editor.getCursorScreenPosition()).toEqual [0, 14] + it "stores for repeating only the last batch of characters, repeats as insert", -> keydown 'a' editor.insertText("abc") From be2b4d84fef5d0abe74bad0d7752bbbd8937f5c6 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Wed, 24 Jun 2015 15:41:38 +0100 Subject: [PATCH 07/11] fix lint issue --- lib/operators/input.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/operators/input.coffee b/lib/operators/input.coffee index b88d6a36..f65c5e79 100644 --- a/lib/operators/input.coffee +++ b/lib/operators/input.coffee @@ -39,8 +39,8 @@ class InsertCancellable extends Insert confirmTransaction: (transaction) -> super - if @typedText?.length == 0 - @vimState.history.shift() if @vimState.history[0] is @ + if @typedText?.length is 0 + @vimState.history.shift() if @vimState.history[0] is this class InsertAfter extends Insert execute: -> From 10e48d28b40683c78de52e49293891baf1dc8443 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Wed, 24 Jun 2015 16:09:46 +0100 Subject: [PATCH 08/11] fixing undo problem --- lib/operators/input.coffee | 2 +- lib/vim-state.coffee | 12 ++++++------ spec/operators-spec.coffee | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/operators/input.coffee b/lib/operators/input.coffee index f65c5e79..3d87187f 100644 --- a/lib/operators/input.coffee +++ b/lib/operators/input.coffee @@ -12,7 +12,7 @@ class Insert extends Operator isComplete: -> @standalone or super - confirmChanges: (changes, interrupted) -> + confirmChanges: (changes, insertionCheckpoint, {interrupted}={}) -> bundler = new TransactionBundler(changes) @typedText = bundler.buildInsertText() if @count > 1 and not interrupted diff --git a/lib/vim-state.coffee b/lib/vim-state.coffee index 1c613f5c..47deb531 100644 --- a/lib/vim-state.coffee +++ b/lib/vim-state.coffee @@ -409,23 +409,23 @@ class VimState deactivateInsertMode: -> return unless @mode in [null, 'insert'] @editorElement.component.setInputEnabled(false) - @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) changes = getChangesSinceCheckpoint(@editor.buffer, @insertionCheckpoint) item = @inputOperator(@history[0]) - @insertionCheckpoint = null if item? - item.confirmChanges(changes) + item.confirmChanges(changes, @insertionCheckpoint) + @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) + @insertionCheckpoint = null for cursor in @editor.getCursors() cursor.moveLeft() unless cursor.isAtBeginningOfLine() interruptInsertMode: -> return unless @mode is 'insert' - @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) changes = getChangesSinceCheckpoint(@editor.buffer, @insertionCheckpoint) item = @inputOperator(@history[0]) - @insertionCheckpoint = null if item? - item.confirmChanges(changes, interrupted: true) + item.confirmChanges(changes, @insertionCheckpoint, interrupted: true) + @editor.groupChangesSinceCheckpoint(@insertionCheckpoint) + @insertionCheckpoint = null @setInsertionCheckpoint() diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index d1244ff9..d37596bb 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -1408,6 +1408,7 @@ describe "Operators", -> keydown 'd' keydown 'd' keydown 'u' + editor.setCursorScreenPosition([0, 0]) keydown '2' keydown '.' keydown '.' From 5721f9ee41840d716bf624c60b38b6fb5beb8516 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Thu, 25 Jun 2015 19:05:50 +0100 Subject: [PATCH 09/11] a bit of a cleanup --- lib/operators/input.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/operators/input.coffee b/lib/operators/input.coffee index 3d87187f..2473ef05 100644 --- a/lib/operators/input.coffee +++ b/lib/operators/input.coffee @@ -12,7 +12,8 @@ class Insert extends Operator isComplete: -> @standalone or super - confirmChanges: (changes, insertionCheckpoint, {interrupted}={}) -> + confirmChanges: (changes, insertionCheckpoint, options) -> + interrupted = options?.interrupted bundler = new TransactionBundler(changes) @typedText = bundler.buildInsertText() if @count > 1 and not interrupted From 63a3f22d9560eede5b907bec433fc809e1d22e29 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Tue, 7 Jul 2015 23:23:54 +0100 Subject: [PATCH 10/11] fix bronson/vim-mode-next#4 --- lib/motions/general-motions.coffee | 9 ++--- spec/operators-spec.coffee | 57 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/lib/motions/general-motions.coffee b/lib/motions/general-motions.coffee index 47a3cc78..fe9d5215 100644 --- a/lib/motions/general-motions.coffee +++ b/lib/motions/general-motions.coffee @@ -89,7 +89,7 @@ class Motion selection.modifySelection => @moveCursor(selection.cursor, count, options) ensureCursorIsWithinLine: (cursor) -> - return if @vimState.mode is 'visual' or not cursor.selection.isEmpty() + return if @vimState.mode is 'visual' or @vimState.mode is 'insert' or not cursor.selection.isEmpty() {goalColumn} = cursor {row, column} = cursor.getBufferPosition() lastColumn = cursor.getCurrentLineBufferRange().end.column @@ -153,9 +153,10 @@ class MoveRight extends Motion _.times count, => wrapToNextLine = settings.wrapLeftRightMotion() - # when the motion is combined with an operator, we will only wrap to the next line - # if we are already at the end of the line (after the last character) - wrapToNextLine = false if @vimState.mode is 'operator-pending' and not cursor.isAtEndOfLine() + # when the motion is in insert mode or is combined with an operator, + # we will only wrap to the next line if we are already + # at the end of the line (after the last character) + wrapToNextLine = false if (@vimState.mode is 'insert' or @vimState.mode is 'operator-pending') and not cursor.isAtEndOfLine() cursor.moveRight() unless cursor.isAtEndOfLine() cursor.moveRight() if wrapToNextLine and cursor.isAtEndOfLine() diff --git a/spec/operators-spec.coffee b/spec/operators-spec.coffee index d37596bb..b2a80599 100644 --- a/spec/operators-spec.coffee +++ b/spec/operators-spec.coffee @@ -1656,6 +1656,63 @@ describe "Operators", -> keydown '.' expect(editor.getText()).toBe "abddeec123\nabddeec4567" + describe "without wrapLeftRightMotion", -> + it "handles right motions correctly", -> + editor.setCursorBufferPosition [0, 0] + keydown 'i' + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 1] + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 2] + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 3] + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 3] + editor.insertText "de" + expect(editor.getText()).toBe "123de\n4567" + + it "handles left motions correctly", -> + editor.setCursorBufferPosition [1, 1] + keydown 'i' + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + expect(editor.getCursorBufferPosition()).toEqual [1, 0] + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + expect(editor.getCursorBufferPosition()).toEqual [1, 0] + editor.insertText "de" + expect(editor.getText()).toBe "123\nde4567" + + describe "with wrapLeftRightMotion", -> + beforeEach -> + atom.config.set('vim-mode.wrapLeftRightMotion', true) + + it "handles right motions correctly", -> + editor.setCursorBufferPosition [0, 0] + keydown 'i' + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 1] + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 2] + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 3] + atom.commands.dispatch editorElement, 'vim-mode:move-right-insert' + expect(editor.getCursorBufferPosition()).toEqual [1, 0] + editor.insertText "de" + expect(editor.getText()).toBe "123\nde4567" + + it "handles left motions correctly", -> + editor.setCursorBufferPosition [1, 2] + keydown 'i' + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + expect(editor.getCursorBufferPosition()).toEqual [1, 1] + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + expect(editor.getCursorBufferPosition()).toEqual [1, 0] + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 3] + atom.commands.dispatch editorElement, 'vim-mode:move-left-insert' + expect(editor.getCursorBufferPosition()).toEqual [0, 2] + editor.insertText "de" + expect(editor.getText()).toBe "12de3\n4567" + describe 'the a keybinding', -> beforeEach -> editor.setText('') From 04d966d560f0ccd49124b5d39d19044d0ebd93a6 Mon Sep 17 00:00:00 2001 From: Jacek Kopecky Date: Fri, 10 Jul 2015 19:48:33 +0100 Subject: [PATCH 11/11] fixed interaction with autocomplete --- keymaps/vim-mode.cson | 2 ++ 1 file changed, 2 insertions(+) diff --git a/keymaps/vim-mode.cson b/keymaps/vim-mode.cson index 2c0435af..bfc894ee 100644 --- a/keymaps/vim-mode.cson +++ b/keymaps/vim-mode.cson @@ -15,6 +15,8 @@ 'ctrl-u': 'editor:delete-to-beginning-of-line' 'left': 'vim-mode:move-left-insert' 'right': 'vim-mode:move-right-insert' + +'atom-text-editor.vim-mode.insert-mode:not(.autocomplete-active)': 'up': 'vim-mode:move-up-insert' 'down': 'vim-mode:move-down-insert'