1411 lines
49 KiB
CoffeeScript
1411 lines
49 KiB
CoffeeScript
helpers = require './spec-helper'
|
|
|
|
describe "Motions", ->
|
|
[editor, editorView, vimState] = []
|
|
|
|
beforeEach ->
|
|
vimMode = atom.packages.loadPackage('vim-mode')
|
|
vimMode.activateResources()
|
|
|
|
editorView = helpers.cacheEditor(editorView)
|
|
editor = editorView.editor
|
|
|
|
vimState = editorView.vimState
|
|
vimState.activateCommandMode()
|
|
vimState.resetCommandMode()
|
|
|
|
keydown = (key, options={}) ->
|
|
options.element ?= editorView[0]
|
|
helpers.keydown(key, options)
|
|
|
|
commandModeInputKeydown = (key, opts = {}) ->
|
|
opts.element = editor.commandModeInputView.editor.find('input').get(0)
|
|
opts.raw = true
|
|
keydown(key, opts)
|
|
|
|
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]
|
|
|
|
describe "as a selection", ->
|
|
it "selects the character to the left", ->
|
|
keydown('y')
|
|
keydown('h')
|
|
|
|
expect(vimState.getRegister('"').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')
|
|
|
|
it "moves the cursor down", ->
|
|
keydown('j')
|
|
expect(editor.getCursorScreenPosition()).toEqual [2, 1]
|
|
|
|
it "don't go over after the last line", ->
|
|
keydown('j')
|
|
expect(editor.getCursorScreenPosition()).toEqual [2, 1]
|
|
|
|
it "selects the text while moving", ->
|
|
keydown('j')
|
|
expect(editor.getSelectedText()).toBe "bcd\nA"
|
|
|
|
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]
|
|
|
|
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]
|
|
|
|
# FIXME: The definition of Cursor#getEndOfCurrentWordBufferPosition,
|
|
# means that the end of the word can't be the current cursor
|
|
# position (even though it is when your cursor is on a new line).
|
|
#
|
|
# Therefore it picks the end of the next word here (which is [3,3])
|
|
# to start looking for the next word, which is also the end of the
|
|
# buffer so the cursor never advances.
|
|
#
|
|
# See atom/vim-mode#3
|
|
keydown('w')
|
|
expect(editor.getCursorScreenPosition()).toEqual [3, 0]
|
|
|
|
keydown('w')
|
|
expect(editor.getCursorScreenPosition()).toEqual [3, 3]
|
|
|
|
# After cursor gets to the EOF, it should stay there.
|
|
keydown('w')
|
|
expect(editor.getCursorScreenPosition()).toEqual [3, 3]
|
|
|
|
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, 3])
|
|
|
|
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.getRegister('"').text).toBe 'ab '
|
|
|
|
describe "between words", ->
|
|
beforeEach ->
|
|
editor.setCursorScreenPosition([0, 2])
|
|
keydown('y')
|
|
keydown('w')
|
|
|
|
it "selects the whitespace", ->
|
|
expect(vimState.getRegister('"').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 [2, 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.getRegister('"').text).toBe 'cde1+- '
|
|
|
|
it "doesn't go past the end of the file", ->
|
|
editor.setCursorScreenPosition([2, 0])
|
|
keydown('y')
|
|
keydown('W', shift:true)
|
|
expect(vimState.getRegister('"').text).toBe ''
|
|
|
|
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]
|
|
|
|
# INCOMPATIBILITY: vim doesn't stop at [2, 0] it advances immediately
|
|
# to [3, 2]
|
|
keydown('e')
|
|
expect(editor.getCursorScreenPosition()).toEqual [2, 0]
|
|
|
|
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.getRegister('"').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.getRegister('"').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.getRegister('"').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.getRegister('"').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.getRegister('"').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.getRegister('"').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.getRegister('"').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.getRegister('"').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.getRegister('"').text).toBe 'ab '
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
|
|
|
|
describe "the B keybinding", ->
|
|
beforeEach -> editor.setText("cde1+- ab \n 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, 1]
|
|
|
|
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, 8])
|
|
keydown('y')
|
|
keydown('B', shift:true)
|
|
expect(vimState.getRegister('"').text).toBe 'xyz-123'
|
|
|
|
it "doesn't go past the beginning of the file", ->
|
|
editor.setCursorScreenPosition([0, 0])
|
|
keydown('y')
|
|
keydown('B', shift:true)
|
|
expect(vimState.getRegister('"').text).toBe ''
|
|
|
|
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 ->
|
|
keydown('d')
|
|
keydown('^')
|
|
|
|
it 'selects to the first character of the line', ->
|
|
expect(editor.getText()).toBe 'abcde'
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "from the first character of the line", ->
|
|
beforeEach -> editor.setCursorScreenPosition([0, 2])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('^')
|
|
|
|
it "stays put", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('^')
|
|
|
|
it "does nothing", ->
|
|
expect(editor.getText()).toBe ' abcde'
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
describe "from the middle of a word", ->
|
|
beforeEach -> editor.setCursorScreenPosition([0, 4])
|
|
|
|
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 ->
|
|
keydown('d')
|
|
keydown('^')
|
|
|
|
it 'selects to the first character of the line', ->
|
|
expect(editor.getText()).toBe ' cde'
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
describe "the 0 keybinding", ->
|
|
beforeEach ->
|
|
editor.setText(" abcde")
|
|
editor.setCursorScreenPosition([0, 4])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('0')
|
|
|
|
it "moves the cursor to the first column", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('0')
|
|
|
|
it 'selects to the first column of the line', ->
|
|
expect(editor.getText()).toBe 'cde'
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "the $ keybinding", ->
|
|
beforeEach ->
|
|
editor.setText(" abcde\n\n1234567890")
|
|
editor.setCursorScreenPosition([0, 4])
|
|
|
|
describe "as a motion from empty line", ->
|
|
beforeEach -> editor.setCursorScreenPosition([1, 0])
|
|
|
|
it "moves the cursor to the end of the line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('$')
|
|
|
|
# FIXME: See atom/vim-mode#2
|
|
it "moves the cursor to the end of the line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 6]
|
|
|
|
it "should remain in the last column when moving down", ->
|
|
keydown('j')
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
|
|
|
|
keydown('j')
|
|
expect(editor.getCursorScreenPosition()).toEqual [2, 9]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('$')
|
|
|
|
it "selects to the beginning of the lines", ->
|
|
expect(editor.getText()).toBe " ab\n\n1234567890"
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 3]
|
|
|
|
# FIXME: this doesn't work as we can't determine if this is a motion
|
|
# or part of a repeat prefix.
|
|
xdescribe "the 0 keybinding", ->
|
|
beforeEach ->
|
|
editor.setText(" a\n")
|
|
editor.setCursorScreenPosition([0, 2])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('0')
|
|
|
|
it "moves the cursor to the beginning of the line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0,0]
|
|
|
|
describe "the - keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("abcdefg\n abc\n abc\n")
|
|
|
|
describe "from the middle of a line", ->
|
|
beforeEach -> editor.setCursorScreenPosition([1, 3])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('-')
|
|
|
|
it "moves the cursor to the first character of the previous line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('-')
|
|
|
|
it "deletes the current and previous line", ->
|
|
expect(editor.getText()).toBe " abc\n"
|
|
# commented out because the column is wrong due to a bug in `k`; re-enable when `k` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [0, 3]
|
|
|
|
describe "from the first character of a line indented the same as the previous one", ->
|
|
beforeEach -> editor.setCursorScreenPosition([2, 2])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('-')
|
|
|
|
it "moves to the first character of the previous line (directly above)", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('-')
|
|
|
|
it "selects to the first character of the previous line (directly above)", ->
|
|
expect(editor.getText()).toBe "abcdefg\n"
|
|
# commented out because the column is wrong due to a bug in `k`; re-enable when `k` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
describe "from the beginning of a line preceded by an indented line", ->
|
|
beforeEach -> editor.setCursorScreenPosition([2, 0])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('-')
|
|
|
|
it "moves the cursor to the first character of the previous line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('-')
|
|
|
|
it "selects to the first character of the previous line", ->
|
|
expect(editor.getText()).toBe "abcdefg\n"
|
|
# commented out because the column is wrong due to a bug in `k`; re-enable when `k` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "with a count", ->
|
|
beforeEach ->
|
|
editor.setText("1\n2\n3\n4\n5\n6\n")
|
|
editor.setCursorScreenPosition([4, 0])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach ->
|
|
keydown('3')
|
|
keydown('-')
|
|
|
|
it "moves the cursor to the first character of that many lines previous", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('3')
|
|
keydown('-')
|
|
|
|
it "deletes the current line plus that many previous lines", ->
|
|
expect(editor.getText()).toBe "1\n6\n"
|
|
# commented out because the column is wrong due to a bug in `k`; re-enable when `k` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [1, 0]
|
|
|
|
describe "the + keybinding", ->
|
|
beforeEach ->
|
|
editor.setText(" abc\n abc\nabcdefg\n")
|
|
|
|
describe "from the middle of a line", ->
|
|
beforeEach -> editor.setCursorScreenPosition([1, 3])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('+')
|
|
|
|
it "moves the cursor to the first character of the next line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [2, 0]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('+')
|
|
|
|
it "deletes the current and next line", ->
|
|
expect(editor.getText()).toBe " abc\n"
|
|
# commented out because the column is wrong due to a bug in `j`; re-enable when `j` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [0, 3]
|
|
|
|
describe "from the first character of a line indented the same as the next one", ->
|
|
beforeEach -> editor.setCursorScreenPosition([0, 2])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('+')
|
|
|
|
it "moves to the first character of the next line (directly below)", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('+')
|
|
|
|
it "selects to the first character of the next line (directly below)", ->
|
|
expect(editor.getText()).toBe "abcdefg\n"
|
|
# commented out because the column is wrong due to a bug in `j`; re-enable when `j` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
describe "from the beginning of a line followed by an indented line", ->
|
|
beforeEach -> editor.setCursorScreenPosition([0, 0])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('+')
|
|
|
|
it "moves the cursor to the first character of the next line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('+')
|
|
|
|
it "selects to the first character of the next line", ->
|
|
expect(editor.getText()).toBe "abcdefg\n"
|
|
# commented out because the column is wrong due to a bug in `j`; re-enable when `j` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "with a count", ->
|
|
beforeEach ->
|
|
editor.setText("1\n2\n3\n4\n5\n6\n")
|
|
editor.setCursorScreenPosition([1, 0])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach ->
|
|
keydown('3')
|
|
keydown('+')
|
|
|
|
it "moves the cursor to the first character of that many lines following", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [4, 0]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
keydown('d')
|
|
keydown('3')
|
|
keydown('+')
|
|
|
|
it "deletes the current line plus that many following lines", ->
|
|
expect(editor.getText()).toBe "1\n6\n"
|
|
# commented out because the column is wrong due to a bug in `j`; re-enable when `j` is fixed
|
|
#expect(editor.getCursorScreenPosition()).toEqual [1, 0]
|
|
|
|
describe "the enter keybinding", ->
|
|
keydownCodeForEnter = '\r' # 'enter' does not work
|
|
startingText = " abc\n abc\nabcdefg\n"
|
|
|
|
describe "from the middle of a line", ->
|
|
startingCursorPosition = [1, 3]
|
|
|
|
describe "as a motion", ->
|
|
it "acts the same as the + keybinding", ->
|
|
# do it with + and save the results
|
|
editor.setText(startingText)
|
|
editor.setCursorScreenPosition(startingCursorPosition)
|
|
keydown('+')
|
|
referenceCursorPosition = editor.getCursorScreenPosition()
|
|
# do it again with enter and compare the results
|
|
editor.setText(startingText)
|
|
editor.setCursorScreenPosition(startingCursorPosition)
|
|
keydown(keydownCodeForEnter)
|
|
expect(editor.getCursorScreenPosition()).toEqual referenceCursorPosition
|
|
|
|
describe "as a selection", ->
|
|
it "acts the same as the + keybinding", ->
|
|
# do it with + and save the results
|
|
editor.setText(startingText)
|
|
editor.setCursorScreenPosition(startingCursorPosition)
|
|
keydown('d')
|
|
keydown('+')
|
|
referenceText = editor.getText()
|
|
referenceCursorPosition = editor.getCursorScreenPosition()
|
|
# do it again with enter and compare the results
|
|
editor.setText(startingText)
|
|
editor.setCursorScreenPosition(startingCursorPosition)
|
|
keydown('d')
|
|
keydown(keydownCodeForEnter)
|
|
expect(editor.getText()).toEqual referenceText
|
|
expect(editor.getCursorScreenPosition()).toEqual referenceCursorPosition
|
|
|
|
describe "the gg keybinding", ->
|
|
beforeEach ->
|
|
editor.setText(" 1abc\n 2\n3\n")
|
|
editor.setCursorScreenPosition([0, 2])
|
|
|
|
describe "as a motion", ->
|
|
describe "in command mode", ->
|
|
beforeEach ->
|
|
keydown('g')
|
|
keydown('g')
|
|
|
|
it "moves the cursor to the beginning of the first line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
|
|
|
|
describe "in linewise visual mode", ->
|
|
beforeEach ->
|
|
editor.setCursorScreenPosition([1, 0])
|
|
vimState.activateVisualMode('linewise')
|
|
keydown('g')
|
|
keydown('g')
|
|
|
|
it "selects to the first line in the file", ->
|
|
expect(editor.getSelectedText()).toBe " 1abc\n 2\n"
|
|
|
|
it "moves the cursor to a specified line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
describe "in characterwise visual mode", ->
|
|
beforeEach ->
|
|
editor.setCursorScreenPosition([1, 1])
|
|
vimState.activateVisualMode()
|
|
keydown('g')
|
|
keydown('g')
|
|
|
|
it "selects to the first line in the file", ->
|
|
expect(editor.getSelectedText()).toBe "1abc\n 2"
|
|
|
|
it "moves the cursor to a specified line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
|
|
|
|
describe "as a repeated motion", ->
|
|
describe "in command mode", ->
|
|
beforeEach ->
|
|
keydown('2')
|
|
keydown('g')
|
|
keydown('g')
|
|
|
|
it "moves the cursor to a specified line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 1]
|
|
|
|
describe "in linewise visual motion", ->
|
|
beforeEach ->
|
|
editor.setCursorScreenPosition([2, 0])
|
|
vimState.activateVisualMode('linewise')
|
|
keydown('2')
|
|
keydown('g')
|
|
keydown('g')
|
|
|
|
it "selects to a specified line", ->
|
|
expect(editor.getSelectedText()).toBe " 2\n3\n"
|
|
|
|
it "moves the cursor to a specified line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
|
|
|
|
describe "in characterwise visual motion", ->
|
|
beforeEach ->
|
|
editor.setCursorScreenPosition([2, 0])
|
|
vimState.activateVisualMode()
|
|
keydown('2')
|
|
keydown('g')
|
|
keydown('g')
|
|
|
|
it "selects to a first character of specified line", ->
|
|
expect(editor.getSelectedText()).toBe "2\n3"
|
|
|
|
it "moves the cursor to a specified line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 1]
|
|
|
|
describe "the G keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("1\n 2\n 3abc\n ")
|
|
editor.setCursorScreenPosition([0, 2])
|
|
|
|
describe "as a motion", ->
|
|
beforeEach -> keydown('G', shift: true)
|
|
|
|
it "moves the cursor to the last line after whitespace", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [3, 1]
|
|
|
|
describe "as a repeated motion", ->
|
|
beforeEach ->
|
|
keydown('2')
|
|
keydown('G', shift: true)
|
|
|
|
it "moves the cursor to a specified line", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 4]
|
|
|
|
describe "as a selection", ->
|
|
beforeEach ->
|
|
editor.setCursorScreenPosition([1, 0])
|
|
vimState.activateVisualMode()
|
|
keydown('G', shift: true)
|
|
|
|
it "selects to the last line in the file", ->
|
|
expect(editor.getSelectedText()).toBe " 2\n 3abc\n "
|
|
|
|
it "moves the cursor to the last line after whitespace", ->
|
|
expect(editor.getCursorScreenPosition()).toEqual [3,1]
|
|
|
|
describe "the / keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("abc\ndef\nabc\ndef\n")
|
|
editor.setCursorBufferPosition([0, 0])
|
|
|
|
describe "as a motion", ->
|
|
it "moves the cursor to the specified search pattern", ->
|
|
keydown('/')
|
|
|
|
editor.commandModeInputView.editor.setText 'def'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
it "loops back around", ->
|
|
editor.setCursorBufferPosition([3, 0])
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText 'def'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
it "uses a valid regex as a regex", ->
|
|
keydown('/')
|
|
# Cycle through the 'abc' on the first line with a character pattern
|
|
editor.commandModeInputView.editor.setText '[abc]'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 1]
|
|
keydown('n')
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 2]
|
|
|
|
it "uses an invalid regex as a literal string", ->
|
|
# Go straight to the literal [abc
|
|
editor.setText("abc\n[abc]\n")
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText '[abc'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
keydown('n')
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
it 'works with selection in visual mode', ->
|
|
editor.setText('one two three')
|
|
keydown('v')
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText 'th'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 8]
|
|
keydown('d')
|
|
expect(editor.getText()).toBe 'three'
|
|
|
|
it 'extends selection when repeating search in visual mode', ->
|
|
editor.setText('line1\nline2\nline3')
|
|
keydown('v')
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText 'line'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
{start, end} = editor.getSelectedBufferRange()
|
|
expect(start.row).toEqual 0
|
|
expect(end.row).toEqual 1
|
|
keydown('n')
|
|
{start,end} = editor.getSelectedBufferRange()
|
|
expect(start.row).toEqual 0
|
|
expect(end.row).toEqual 2
|
|
|
|
describe "repeating", ->
|
|
it "does nothing with no search history", ->
|
|
# This tests that no exception is raised
|
|
keydown('n')
|
|
|
|
beforeEach ->
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText 'def'
|
|
editor.commandModeInputView.editor.trigger 'core:confirm'
|
|
|
|
describe "the n keybinding", ->
|
|
it "repeats the last search", ->
|
|
keydown('n')
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
describe "the N keybinding", ->
|
|
it "repeats the last search backwards", ->
|
|
editor.setCursorBufferPosition([0, 0])
|
|
keydown('N', shift: true)
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
keydown('N', shift: true)
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
describe "composing", ->
|
|
it "composes with operators", ->
|
|
keydown('d')
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText('def')
|
|
editor.commandModeInputView.editor.trigger('core:confirm')
|
|
expect(editor.getText()).toEqual "def\nabc\ndef\n"
|
|
|
|
it "repeats correctly with operators", ->
|
|
keydown('d')
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText('def')
|
|
editor.commandModeInputView.editor.trigger('core:confirm')
|
|
|
|
keydown('.')
|
|
expect(editor.getText()).toEqual "def\n"
|
|
|
|
describe "when reversed as ?", ->
|
|
it "moves the cursor backwards to the specified search pattern", ->
|
|
keydown('?')
|
|
editor.commandModeInputView.editor.setText('def')
|
|
editor.commandModeInputView.editor.trigger('core:confirm')
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
describe "repeating", ->
|
|
beforeEach ->
|
|
keydown('?')
|
|
editor.commandModeInputView.editor.setText('def')
|
|
editor.commandModeInputView.editor.trigger('core:confirm')
|
|
|
|
describe 'the n keybinding', ->
|
|
it "repeats the last search backwards", ->
|
|
editor.setCursorBufferPosition([0, 0])
|
|
keydown('n')
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
describe 'the N keybinding', ->
|
|
it "repeats the last search forwards", ->
|
|
editor.setCursorBufferPosition([0, 0])
|
|
keydown('N', shift: true)
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
describe "using search history", ->
|
|
beforeEach ->
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText('def')
|
|
editor.commandModeInputView.editor.trigger('core:confirm')
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.setText('abc')
|
|
editor.commandModeInputView.editor.trigger('core:confirm')
|
|
expect(editor.getCursorBufferPosition()).toEqual [2, 0]
|
|
|
|
it "allows searching history in the search field", ->
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.trigger('core:move-up')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual('abc')
|
|
editor.commandModeInputView.editor.trigger('core:move-up')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual('def')
|
|
editor.commandModeInputView.editor.trigger('core:move-up')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual('def')
|
|
|
|
it "resets the search field to empty when scrolling back", ->
|
|
keydown('/')
|
|
editor.commandModeInputView.editor.trigger('core:move-up')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual('abc')
|
|
editor.commandModeInputView.editor.trigger('core:move-up')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual('def')
|
|
editor.commandModeInputView.editor.trigger('core:move-down')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual('abc')
|
|
editor.commandModeInputView.editor.trigger('core:move-down')
|
|
expect(editor.commandModeInputView.editor.getText()).toEqual ''
|
|
|
|
describe "the * keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("abc\n@def\nabc\ndef\n")
|
|
editor.setCursorBufferPosition([0, 0])
|
|
|
|
describe "as a motion", ->
|
|
it "moves cursor to next occurence of word under cursor", ->
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [2, 0]
|
|
|
|
it "doesn't move cursor unless next occurence is the exact word (no partial matches)", ->
|
|
editor.setText("abc\ndef\nghiabc\njkl\nabcdef")
|
|
editor.setCursorBufferPosition([0, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 0]
|
|
|
|
describe "with words that contain 'non-word' characters", ->
|
|
it "moves cursor to next occurence of word under cursor", ->
|
|
editor.setText("abc\n@def\nabc\n@def\n")
|
|
editor.setCursorBufferPosition([1, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
it "doesn't move cursor unless next match has exact word ending", ->
|
|
editor.setText("abc\n@def\nabc\n@def1\n")
|
|
# FIXME: I suspect there is a bug laying around
|
|
# Cursor#getEndOfCurrentWordBufferPosition, this function
|
|
# is returning '@' as a word, instead of returning the whole
|
|
# word '@def', this behavior is avoided in this test, when we
|
|
# execute the '*' command when cursor is on character after '@'
|
|
# (in this particular example, the 'd' char)
|
|
editor.setCursorBufferPosition([1, 1])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
# FIXME: This behavior is different from the one found in
|
|
# vim. This is because the word boundary match in Javascript
|
|
# ignores starting 'non-word' characters.
|
|
# e.g.
|
|
# in Vim: /\<def\>/.test("@def") => false
|
|
# in Javascript: /\bdef\b/.test("@def") => true
|
|
it "moves cursor to the start of valid word char", ->
|
|
editor.setText("abc\ndef\nabc\n@def\n")
|
|
editor.setCursorBufferPosition([1, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 1]
|
|
|
|
describe "when cursor is on non-word char column", ->
|
|
it "matches only the non-word char", ->
|
|
editor.setText("abc\n@def\nabc\n@def\n")
|
|
editor.setCursorBufferPosition([1, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
describe "when cursor is not on a word", ->
|
|
it "does a match with the next word", ->
|
|
editor.setText("abc\n @def\n abc\n @def")
|
|
editor.setCursorBufferPosition([1, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 1]
|
|
|
|
describe "when cursor is at EOF", ->
|
|
it "doesn't try to do any match", ->
|
|
editor.setText("abc\n@def\nabc\n ")
|
|
editor.setCursorBufferPosition([3, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 1]
|
|
|
|
describe "the hash keybinding", ->
|
|
describe "as a motion", ->
|
|
it "moves cursor to next occurence of word under cursor", ->
|
|
editor.setText("abc\n@def\nabc\ndef\n")
|
|
editor.setCursorBufferPosition([2, 0])
|
|
keydown("#")
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 0]
|
|
|
|
it "doesn't move cursor unless next occurence is the exact word (no partial matches)", ->
|
|
editor.setText("abc\ndef\nghiabc\njkl\nabcdef")
|
|
editor.setCursorBufferPosition([0, 0])
|
|
keydown("#")
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 0]
|
|
|
|
describe "with words that containt 'non-word' characters", ->
|
|
it "moves cursor to next occurence of word under cursor", ->
|
|
editor.setText("abc\n@def\nabc\n@def\n")
|
|
editor.setCursorBufferPosition([3, 0])
|
|
keydown("#")
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 0]
|
|
|
|
it "moves cursor to the start of valid word char", ->
|
|
editor.setText("abc\n@def\nabc\ndef\n")
|
|
editor.setCursorBufferPosition([3, 0])
|
|
keydown("#")
|
|
expect(editor.getCursorBufferPosition()).toEqual [1, 1]
|
|
|
|
describe "when cursor is on non-word char column", ->
|
|
it "matches only the non-word char", ->
|
|
editor.setText("abc\n@def\nabc\n@def\n")
|
|
editor.setCursorBufferPosition([1, 0])
|
|
keydown("*")
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
describe "the H keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")
|
|
editor.setCursorScreenPosition([8, 0])
|
|
spyOn(editor, 'setCursorScreenPosition')
|
|
|
|
it "moves the cursor to the first row if visible", ->
|
|
spyOn(editorView, 'getFirstVisibleScreenRow').andReturn(0)
|
|
keydown('H', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([0, 0])
|
|
|
|
it "moves the cursor to the first visible row plus offset", ->
|
|
spyOn(editorView, 'getFirstVisibleScreenRow').andReturn(2)
|
|
keydown('H', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([4, 0])
|
|
|
|
it "respects counts", ->
|
|
spyOn(editorView, 'getFirstVisibleScreenRow').andReturn(0)
|
|
keydown('3')
|
|
keydown('H', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([2, 0])
|
|
|
|
describe "the L keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")
|
|
editor.setCursorScreenPosition([8, 0])
|
|
spyOn(editor, 'setCursorScreenPosition')
|
|
|
|
it "moves the cursor to the first row if visible", ->
|
|
spyOn(editorView, 'getLastVisibleScreenRow').andReturn(10)
|
|
keydown('L', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([10, 0])
|
|
|
|
it "moves the cursor to the first visible row plus offset", ->
|
|
spyOn(editorView, 'getLastVisibleScreenRow').andReturn(6)
|
|
keydown('L', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([4, 0])
|
|
|
|
it "respects counts", ->
|
|
spyOn(editorView, 'getLastVisibleScreenRow').andReturn(10)
|
|
keydown('3')
|
|
keydown('L', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([8, 0])
|
|
|
|
describe "the M keybinding", ->
|
|
beforeEach ->
|
|
editor.setText("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")
|
|
editor.setCursorScreenPosition([8, 0])
|
|
spyOn(editor, 'setCursorScreenPosition')
|
|
spyOn(editorView, 'getLastVisibleScreenRow').andReturn(10)
|
|
spyOn(editorView, 'getFirstVisibleScreenRow').andReturn(0)
|
|
|
|
it "moves the cursor to the first row if visible", ->
|
|
keydown('M', shift: true)
|
|
expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([5, 0])
|
|
|
|
describe 'the mark keybindings', ->
|
|
beforeEach ->
|
|
editor.setText(' 12\n 34\n56\n')
|
|
editor.setCursorBufferPosition([0,1])
|
|
|
|
it 'moves to the beginning of the line of a mark', ->
|
|
editor.setCursorBufferPosition([1,1])
|
|
keydown('m')
|
|
commandModeInputKeydown('a')
|
|
editor.setCursorBufferPosition([0,0])
|
|
keydown('\'')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorBufferPosition()).toEqual [1,4]
|
|
|
|
it 'moves literally to a mark', ->
|
|
editor.setCursorBufferPosition([1,1])
|
|
keydown('m')
|
|
commandModeInputKeydown('a')
|
|
editor.setCursorBufferPosition([0,0])
|
|
keydown('`')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorBufferPosition()).toEqual [1,1]
|
|
|
|
it 'deletes to a mark by line', ->
|
|
editor.setCursorBufferPosition([1,5])
|
|
keydown('m')
|
|
commandModeInputKeydown('a')
|
|
editor.setCursorBufferPosition([0,0])
|
|
keydown('d')
|
|
keydown('\'')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getText()).toEqual '\n56\n'
|
|
|
|
it 'deletes before to a mark literally', ->
|
|
editor.setCursorBufferPosition([1,5])
|
|
keydown('m')
|
|
commandModeInputKeydown('a')
|
|
editor.setCursorBufferPosition([0,1])
|
|
keydown('d')
|
|
keydown('`')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getText()).toEqual ' 4\n56\n'
|
|
|
|
it 'deletes after to a mark literally', ->
|
|
editor.setCursorBufferPosition([1,5])
|
|
keydown('m')
|
|
commandModeInputKeydown('a')
|
|
editor.setCursorBufferPosition([2,1])
|
|
keydown('d')
|
|
keydown('`')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getText()).toEqual ' 12\n 36\n'
|
|
|
|
it 'moves back to previous', ->
|
|
editor.setCursorBufferPosition([1,5])
|
|
keydown('`')
|
|
commandModeInputKeydown('`')
|
|
editor.setCursorBufferPosition([2,1])
|
|
keydown('`')
|
|
commandModeInputKeydown('`')
|
|
expect(editor.getCursorBufferPosition()).toEqual [1,5]
|
|
|
|
|
|
describe 'the f/F keybindings', ->
|
|
beforeEach ->
|
|
editor.setText("abcabcabcabc\n")
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
it 'moves to the first specified character it finds', ->
|
|
keydown('f')
|
|
commandModeInputKeydown('c')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
it 'moves backwards to the first specified character it finds', ->
|
|
editor.setCursorScreenPosition([0, 2])
|
|
keydown('F', shift: true)
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it 'respects count forward', ->
|
|
keydown('2')
|
|
keydown('f')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 6]
|
|
|
|
it 'respects count backward', ->
|
|
editor.setCursorScreenPosition([0, 6])
|
|
keydown('2')
|
|
keydown('F', shift: true)
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it "doesn't move if the character specified isn't found", ->
|
|
keydown('f')
|
|
commandModeInputKeydown('d')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it "doesn't move if there aren't the specified count of the specified character", ->
|
|
keydown('1')
|
|
keydown('0')
|
|
keydown('f')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it "composes with d", ->
|
|
editor.setCursorScreenPosition([0,3])
|
|
keydown('d')
|
|
keydown('2')
|
|
keydown('f')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getText()).toEqual 'abcbc\n'
|
|
|
|
describe 'the t/T keybindings', ->
|
|
beforeEach ->
|
|
editor.setText("abcabcabcabc\n")
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
it 'moves to the character previous to the first specified character it finds', ->
|
|
keydown('t')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
|
|
it 'moves backwards to the character after the first specified character it finds', ->
|
|
editor.setCursorScreenPosition([0, 2])
|
|
keydown('T', shift: true)
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
|
|
|
|
it 'respects count forward', ->
|
|
keydown('2')
|
|
keydown('t')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 5]
|
|
|
|
it 'respects count backward', ->
|
|
editor.setCursorScreenPosition([0, 6])
|
|
keydown('2')
|
|
keydown('T', shift: true)
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
|
|
|
|
it "doesn't move if the character specified isn't found", ->
|
|
keydown('t')
|
|
commandModeInputKeydown('d')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it "doesn't move if there aren't the specified count of the specified character", ->
|
|
keydown('1')
|
|
keydown('0')
|
|
keydown('t')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it "composes with d", ->
|
|
editor.setCursorScreenPosition([0,3])
|
|
keydown('d')
|
|
keydown('2')
|
|
keydown('t')
|
|
commandModeInputKeydown('a')
|
|
expect(editor.getText()).toEqual 'abcabc\n'
|
|
|
|
describe 'the % motion', ->
|
|
beforeEach ->
|
|
editor.setText("( ( ) )--{ text in here; and a function call(with parameters) }\n")
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
it 'matches the correct parenthesis', ->
|
|
keydown('%')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 6]
|
|
|
|
it 'matches the correct brace', ->
|
|
editor.setCursorScreenPosition([0, 9])
|
|
keydown('%')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 62]
|
|
|
|
it 'composes correctly with d', ->
|
|
editor.setCursorScreenPosition([0, 9])
|
|
keydown('d')
|
|
keydown('%')
|
|
expect(editor.getText()).toEqual "( ( ) )--\n"
|
|
|
|
it 'moves correctly when composed with v going forward', ->
|
|
keydown('v')
|
|
keydown('%')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it 'moves correctly when composed with v going backward', ->
|
|
editor.setCursorScreenPosition([0, 6])
|
|
keydown('v')
|
|
keydown('%')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
it 'it moves appropriately to find the nearest matching action', ->
|
|
editor.setCursorScreenPosition([0, 3])
|
|
keydown('%')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
|
|
expect(editor.getText()).toEqual "( ( ) )--{ text in here; and a function call(with parameters) }\n"
|
|
|
|
it 'it moves appropriately to find the nearest matching action', ->
|
|
editor.setCursorScreenPosition([0, 26])
|
|
keydown('%')
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 60]
|
|
expect(editor.getText()).toEqual "( ( ) )--{ text in here; and a function call(with parameters) }\n"
|