mirror of
https://github.com/atom/atom.git
synced 2026-01-24 14:28:14 -05:00
When trying to compose operators that don't compose, the op stack is cleared
This commit is contained in:
@@ -2,7 +2,7 @@ Editor = require 'editor'
|
||||
VimMode = require 'vim-mode'
|
||||
|
||||
describe "VimMode", ->
|
||||
editor = null
|
||||
[editor, vimMode] = []
|
||||
|
||||
beforeEach ->
|
||||
editor = new Editor
|
||||
@@ -36,6 +36,25 @@ describe "VimMode", ->
|
||||
editor.setCursorPosition([1, 0])
|
||||
expect(editor.getCursorPosition()).toEqual [1,0]
|
||||
|
||||
it "clears the operator stack when commands can't be composed", ->
|
||||
editor.trigger keydownEvent('d')
|
||||
expect(vimMode.opStack.length).toBe 1
|
||||
editor.trigger keydownEvent('x')
|
||||
expect(vimMode.opStack.length).toBe 0
|
||||
|
||||
editor.trigger keydownEvent('d')
|
||||
expect(vimMode.opStack.length).toBe 1
|
||||
editor.trigger keydownEvent('\\') # \ is an unused key in vim
|
||||
expect(vimMode.opStack.length).toBe 0
|
||||
|
||||
describe "the esc keybinding", ->
|
||||
it "clears the operator stack", ->
|
||||
editor.trigger keydownEvent('d')
|
||||
expect(vimMode.opStack.length).toBe 1
|
||||
|
||||
editor.trigger keydownEvent('esc')
|
||||
expect(vimMode.opStack.length).toBe 0
|
||||
|
||||
describe "the i keybinding", ->
|
||||
it "puts the editor into insert mode", ->
|
||||
expect(editor).not.toHaveClass 'insert-mode'
|
||||
|
||||
@@ -21,24 +21,26 @@ class VimMode
|
||||
@setupCommandMode()
|
||||
|
||||
setupCommandMode: ->
|
||||
atom.bindKeys '.command-mode', (e) ->
|
||||
atom.bindKeys '.command-mode', (e) =>
|
||||
if e.keystroke.match /^\d$/
|
||||
return 'command-mode:numeric-prefix'
|
||||
if e.keystroke.match /^.$/
|
||||
@resetCommandMode()
|
||||
return false
|
||||
|
||||
@bindCommandModeKeys
|
||||
'i': 'insert'
|
||||
'd': 'delete'
|
||||
'x': 'delete-right'
|
||||
'h': 'move-left'
|
||||
'j': 'move-down'
|
||||
'k': 'move-up'
|
||||
'l': 'move-right'
|
||||
'w': 'move-to-next-word'
|
||||
'b': 'move-to-previous-word'
|
||||
'left': 'move-left'
|
||||
'right': 'move-right'
|
||||
i: 'insert'
|
||||
d: 'delete'
|
||||
x: 'delete-right'
|
||||
h: 'move-left'
|
||||
j: 'move-down'
|
||||
k: 'move-up'
|
||||
l: 'move-right'
|
||||
w: 'move-to-next-word'
|
||||
b: 'move-to-previous-word'
|
||||
esc: 'reset-command-mode'
|
||||
left: 'move-left'
|
||||
right: 'move-right'
|
||||
|
||||
@handleCommands
|
||||
'insert': => @activateInsertMode()
|
||||
@@ -51,6 +53,7 @@ class VimMode
|
||||
'move-to-next-word': => new motions.MoveToNextWord(@editor)
|
||||
'move-to-previous-word': => new motions.MoveToPreviousWord(@editor)
|
||||
'numeric-prefix': (e) => @numericPrefix(e)
|
||||
'reset-command-mode': => @resetCommandMode()
|
||||
|
||||
bindCommandModeKeys: (bindings) ->
|
||||
prefixedBindings = {}
|
||||
@@ -78,6 +81,9 @@ class VimMode
|
||||
|
||||
@editor.on 'cursor:position-changed', @moveCursorBeforeNewline
|
||||
|
||||
resetCommandMode: ->
|
||||
@opStack = []
|
||||
|
||||
moveCursorBeforeNewline: =>
|
||||
if not @editor.selection.modifyingSelection and @editor.cursor.isOnEOL() and @editor.getCurrentLine().length > 0
|
||||
@editor.setCursorColumn(@editor.getCurrentLine().length - 1)
|
||||
@@ -107,10 +113,14 @@ class VimMode
|
||||
|
||||
processOpStack: ->
|
||||
return unless @topOperator().isComplete()
|
||||
|
||||
poppedOperator = @opStack.pop()
|
||||
if @opStack.length
|
||||
@topOperator().compose(poppedOperator)
|
||||
@processOpStack()
|
||||
try
|
||||
@topOperator().compose(poppedOperator)
|
||||
@processOpStack()
|
||||
catch e
|
||||
(e instanceof operators.OperatorError) and @resetCommandMode() or throw e
|
||||
else
|
||||
poppedOperator.execute()
|
||||
|
||||
|
||||
@@ -61,4 +61,4 @@ class MoveToNextWord extends Motion
|
||||
column = nextLineMatch?.index or 0
|
||||
{ row, column }
|
||||
|
||||
module.exports = { MoveLeft, MoveRight, MoveUp, MoveDown, MoveToNextWord, MoveToPreviousWord }
|
||||
module.exports = { Motion, MoveLeft, MoveRight, MoveUp, MoveDown, MoveToNextWord, MoveToPreviousWord }
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
_ = require 'underscore'
|
||||
|
||||
class OperatorError
|
||||
constructor: (@message) ->
|
||||
@name = "Operator Error"
|
||||
|
||||
class NumericPrefix
|
||||
count: null
|
||||
complete: null
|
||||
@@ -43,8 +47,11 @@ class Delete
|
||||
@editor.setCursorPosition([@editor.getCursorRow(), 0])
|
||||
|
||||
compose: (motion) ->
|
||||
if not motion.select
|
||||
throw new OperatorError("Delete must compose with a motion")
|
||||
|
||||
@motion = motion
|
||||
@complete = true
|
||||
|
||||
module.exports = { NumericPrefix, Delete }
|
||||
module.exports = { NumericPrefix, Delete, OperatorError }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user