     options.element ?= editorElement
     helpers.keydown(key, options)
 
+  keystroke = (keys) ->
+    for key in keys.split('')
+      if key.match(/[A-Z]/)
+        keydown(key, shift: true)
+      else
+        keydown(key)
+
   normalModeInputKeydown = (key, opts = {}) ->
     theEditor = opts.editor or editor
     theEditor.normalModeInputView.editorElement.getModel().setText(key)

    inputEditor.getModel().setText(text)
    atom.commands.dispatch(inputEditor, "core:confirm")

  describe "simple motions", ->
    beforeEach ->
      editor.setText("12345\nabcd\nABCDE")
      editor.setCursorScreenPosition([1, 1])

    describe "the h keybinding", ->
      describe "as a motion", ->
        it "moves the cursor left, but not to the previous line", ->
          keydown('h')
          expect(editor.getCursorScreenPosition()).toEqual [1, 0]

          keydown('h')
          expect(editor.getCursorScreenPosition()).toEqual [1, 0]

        it "moves the cursor to the previous line if wrapLeftRightMotion is true", ->
          atom.config.set('vim-mode.wrapLeftRightMotion', true)
          keydown('h')
          keydown('h')
          expect(editor.getCursorScreenPosition()).toEqual [0, 4]

      describe "as a selection", ->
        it "selects the character to the left", ->
          keydown('y')
          keydown('h')

          expect(vimState.register.get('"').text).toBe 'a'
          expect(editor.getCursorScreenPosition()).toEqual [1, 0]

    describe "the j keybinding", ->
      it "moves the cursor down, but not to the end of the last line", ->
        keydown('j')
        expect(editor.getCursorScreenPosition()).toEqual [2, 1]

        keydown('j')
        expect(editor.getCursorScreenPosition()).toEqual [2, 1]

      it "moves the cursor to the end of the line, not past it", ->
        editor.setCursorScreenPosition([0, 4])

        keydown('j')
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

      it "remembers the position it column it was in after moving to shorter line", ->
        editor.setCursorScreenPosition([0, 4])

        keydown('j')
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

        keydown('j')
        expect(editor.getCursorScreenPosition()).toEqual [2, 4]

      describe "when visual mode", ->
        beforeEach ->
          keydown('v')
          expect(editor.getCursorScreenPosition()).toEqual [1, 2]

        it "moves the cursor down", ->
          keydown('j')
          expect(editor.getCursorScreenPosition()).toEqual [2, 2]

        it "doesn't go over after the last line", ->
          keydown('j')
          expect(editor.getCursorScreenPosition()).toEqual [2, 2]

        it "selects the text while moving", ->
          keydown('j')
          expect(editor.getSelectedText()).toBe "bcd\nAB"

    describe "the k keybinding", ->
      it "moves the cursor up, but not to the beginning of the first line", ->
        keydown('k')
        expect(editor.getCursorScreenPosition()).toEqual [0, 1]

        keydown('k')
        expect(editor.getCursorScreenPosition()).toEqual [0, 1]

    describe "the l keybinding", ->
      beforeEach -> editor.setCursorScreenPosition([1, 2])

      it "moves the cursor right, but not to the next line", ->
        keydown('l')
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

        keydown('l')
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

      it "moves the cursor to the next line if wrapLeftRightMotion is true", ->
        atom.config.set('vim-mode.wrapLeftRightMotion', true)
        keydown('l')
        keydown('l')
        expect(editor.getCursorScreenPosition()).toEqual [2, 0]

      describe "on a blank line", ->
        it "doesn't move the cursor", ->
          editor.setText("\n\n\n")
          editor.setCursorBufferPosition([1, 0])
          keydown('l')
          expect(editor.getCursorBufferPosition()).toEqual [1, 0]

  describe "the w keybinding", ->
    beforeEach -> editor.setText("ab cde1+- \n xyz\n\nzip")

    describe "as a motion", ->
      beforeEach -> editor.setCursorScreenPosition([0, 0])

      it "moves the cursor to the beginning of the next word", ->
        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [0, 3]

        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [0, 7]

        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [1, 1]

        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [2, 0]

        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [3, 0]

        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [3, 2]

        # When the cursor gets to the EOF, it should stay there.
        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual [3, 2]

      it "moves the cursor to the end of the word if last word in file", ->
        editor.setText("abc")
        editor.setCursorScreenPosition([0, 0])
        keydown('w')
        expect(editor.getCursorScreenPosition()).toEqual([0, 2])

    describe "as a selection", ->
      describe "within a word", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 0])
          keydown('y')
          keydown('w')

        it "selects to the end of the word", ->
          expect(vimState.register.get('"').text).toBe 'ab '

      describe "between words", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 2])
          keydown('y')
          keydown('w')

        it "selects the whitespace", ->
          expect(vimState.register.get('"').text).toBe ' '

  describe "the W keybinding", ->
    beforeEach -> editor.setText("cde1+- ab \n xyz\n\nzip")

    describe "as a motion", ->
      beforeEach -> editor.setCursorScreenPosition([0, 0])

      it "moves the cursor to the beginning of the next word", ->
        keydown('W', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [0, 7]

        keydown('W', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [1, 1]

        keydown('W', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [2, 0]

        keydown('W', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [3, 0]

    describe "as a selection", ->
      describe "within a word", ->
        it "selects to the end of the whole word", ->
          editor.setCursorScreenPosition([0, 0])
          keydown('y')
          keydown('W', shift: true)
          expect(vimState.register.get('"').text).toBe 'cde1+- '

      it "continues past blank lines", ->
        editor.setCursorScreenPosition([2, 0])

        keydown('d')
        keydown('W', shift: true)
        expect(editor.getText()).toBe "cde1+- ab \n xyz\nzip"
        expect(vimState.register.get('"').text).toBe '\n'

      it "doesn't go past the end of the file", ->
        editor.setCursorScreenPosition([3, 0])

        keydown('d')
        keydown('W', shift: true)
        expect(editor.getText()).toBe "cde1+- ab \n xyz\n\n"
        expect(vimState.register.get('"').text).toBe 'zip'

  describe "the e keybinding", ->
    beforeEach -> editor.setText("ab cde1+- \n xyz\n\nzip")

    describe "as a motion", ->
      beforeEach -> editor.setCursorScreenPosition([0, 0])

      it "moves the cursor to the end of the current word", ->
        keydown('e')
        expect(editor.getCursorScreenPosition()).toEqual [0, 1]

        keydown('e')
        expect(editor.getCursorScreenPosition()).toEqual [0, 6]

        keydown('e')
        expect(editor.getCursorScreenPosition()).toEqual [0, 8]

        keydown('e')
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

        keydown('e')
        expect(editor.getCursorScreenPosition()).toEqual [3, 2]

    describe "as selection", ->
      describe "within a word", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 0])
          keydown('y')
          keydown('e')

        it "selects to the end of the current word", ->
          expect(vimState.register.get('"').text).toBe 'ab'

      describe "between words", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 2])
          keydown('y')
          keydown('e')

        it "selects to the end of the next word", ->
          expect(vimState.register.get('"').text).toBe ' cde1'

  describe "the E keybinding", ->
    beforeEach -> editor.setText("ab  cde1+- \n xyz \n\nzip\n")

    describe "as a motion", ->
      beforeEach -> editor.setCursorScreenPosition([0, 0])

      it "moves the cursor to the end of the current word", ->
        keydown('E', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [0, 1]

        keydown('E', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [0, 9]

        keydown('E', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

        keydown('E', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [3, 2]

        keydown('E', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [4, 0]

    describe "as selection", ->
      describe "within a word", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 0])
          keydown('y')
          keydown('E', shift: true)

        it "selects to the end of the current word", ->
          expect(vimState.register.get('"').text).toBe 'ab'

      describe "between words", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 2])
          keydown('y')
          keydown('E', shift: true)

        it "selects to the end of the next word", ->
          expect(vimState.register.get('"').text).toBe '  cde1+-'

      describe "press more than once", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 0])
          keydown('v')
          keydown('E', shift: true)
          keydown('E', shift: true)
          keydown('y')

        it "selects to the end of the current word", ->
          expect(vimState.register.get('"').text).toBe 'ab  cde1+-'

  describe "the } keybinding", ->
    beforeEach ->
      editor.setText("abcde\n\nfghij\nhijk\n  xyz  \n\nzip\n\n  \nthe end")
      editor.setCursorScreenPosition([0, 0])

    describe "as a motion", ->
      it "moves the cursor to the end of the paragraph", ->
        keydown('}')
        expect(editor.getCursorScreenPosition()).toEqual [1, 0]

        keydown('}')
        expect(editor.getCursorScreenPosition()).toEqual [5, 0]

        keydown('}')
        expect(editor.getCursorScreenPosition()).toEqual [7, 0]

        keydown('}')
        expect(editor.getCursorScreenPosition()).toEqual [9, 6]

    describe "as a selection", ->
      beforeEach ->
        keydown('y')
        keydown('}')

      it 'selects to the end of the current paragraph', ->
        expect(vimState.register.get('"').text).toBe "abcde\n"

  describe "the { keybinding", ->
    beforeEach ->
      editor.setText("abcde\n\nfghij\nhijk\n  xyz  \n\nzip\n\n  \nthe end")
      editor.setCursorScreenPosition([9, 0])

    describe "as a motion", ->
      it "moves the cursor to the beginning of the paragraph", ->
        keydown('{')
        expect(editor.getCursorScreenPosition()).toEqual [7, 0]

        keydown('{')
        expect(editor.getCursorScreenPosition()).toEqual [5, 0]

        keydown('{')
        expect(editor.getCursorScreenPosition()).toEqual [1, 0]

        keydown('{')
        expect(editor.getCursorScreenPosition()).toEqual [0, 0]

    describe "as a selection", ->
      beforeEach ->
        editor.setCursorScreenPosition([7, 0])
        keydown('y')
        keydown('{')

      it 'selects to the beginning of the current paragraph', ->
        expect(vimState.register.get('"').text).toBe "\nzip\n"

  describe "the b keybinding", ->
    beforeEach -> editor.setText(" ab cde1+- \n xyz\n\nzip }\n last")

    describe "as a motion", ->
      beforeEach -> editor.setCursorScreenPosition([4, 1])

      it "moves the cursor to the beginning of the previous word", ->
        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [3, 4]

        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [3, 0]

        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [2, 0]

        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [1, 1]

        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [0, 8]

        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [0, 4]

        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [0, 1]

        # Go to start of the file, after moving past the first word
        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [0, 0]

        # Stay at the start of the file
        keydown('b')
        expect(editor.getCursorScreenPosition()).toEqual [0, 0]

    describe "as a selection", ->
      describe "within a word", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 2])
          keydown('y')
          keydown('b')

        it "selects to the beginning of the current word", ->
          expect(vimState.register.get('"').text).toBe 'a'
          expect(editor.getCursorScreenPosition()).toEqual [0, 1]

      describe "between words", ->
        beforeEach ->
          editor.setCursorScreenPosition([0, 4])
          keydown('y')
          keydown('b')

        it "selects to the beginning of the last word", ->
          expect(vimState.register.get('"').text).toBe 'ab '
          expect(editor.getCursorScreenPosition()).toEqual [0, 1]

  describe "the B keybinding", ->
    beforeEach -> editor.setText("cde1+- ab \n\t xyz-123\n\n zip")

    describe "as a motion", ->
      beforeEach -> editor.setCursorScreenPosition([4, 1])

      it "moves the cursor to the beginning of the previous word", ->
        keydown('B', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [3, 1]

        keydown('B', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [2, 0]

        keydown('B', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [1, 3]

        keydown('B', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [0, 7]

        keydown('B', shift: true)
        expect(editor.getCursorScreenPosition()).toEqual [0, 0]

    describe "as a selection", ->
      it "selects to the beginning of the whole word", ->
        editor.setCursorScreenPosition([1, 10])
        keydown('y')
        keydown('B', shift: true)
        expect(vimState.register.get('"').text).toBe 'xyz-12' # because cursor is on the `3`

      it "doesn't go past the beginning of the file", ->
        editor.setCursorScreenPosition([0, 0])
        vimState.register.set('"', text: 'abc')
        keydown('y')
        keydown('B', shift: true)
        expect(vimState.register.get('"').text).toBe 'abc'

  describe "the ^ keybinding", ->
    beforeEach ->
      editor.setText("  abcde")

    describe "from the beginning of the line", ->
      beforeEach -> editor.setCursorScreenPosition([0, 0])

      describe "as a motion", ->
        beforeEach -> keydown('^')

        it "moves the cursor to the first character of the line", ->
          expect(editor.getCursorScreenPosition()).toEqual [0, 2]

      describe "as a selection", ->
        beforeEach ->

helpers = require './spec-helper'
_ = require 'underscore-plus'

fdescribe "Motions", ->
  [editor, editorElement, vimState] = []

  beforeEach ->
