diff options
Diffstat (limited to 'atom/packages/vim-mode/spec')
| -rw-r--r-- | atom/packages/vim-mode/spec/insert-mode-spec.coffee | 73 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/motions-spec.coffee | 1996 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/operators-spec.coffee | 2284 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/prefixes-spec.coffee | 182 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/scroll-spec.coffee | 230 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/spec-helper.coffee | 76 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/text-objects-spec.coffee | 825 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/vim-mode-spec.coffee | 61 | ||||
| -rw-r--r-- | atom/packages/vim-mode/spec/vim-state-spec.coffee | 519 |
9 files changed, 0 insertions, 6246 deletions
diff --git a/atom/packages/vim-mode/spec/insert-mode-spec.coffee b/atom/packages/vim-mode/spec/insert-mode-spec.coffee deleted file mode 100644 index 061cb50..0000000 --- a/atom/packages/vim-mode/spec/insert-mode-spec.coffee +++ /dev/null @@ -1,73 +0,0 @@ -helpers = require './spec-helper' - -describe "Insert mode commands", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - describe "Copy from line above/below", -> - beforeEach -> - editor.setText("12345\n\nabcd\nefghi") - editor.setCursorBufferPosition([1, 0]) - editor.addCursorAtBufferPosition([3, 0]) - keydown 'i' - - describe "the ctrl-y command", -> - it "copies from the line above", -> - keydown 'y', ctrl: true - expect(editor.getText()).toBe '12345\n1\nabcd\naefghi' - - editor.insertText ' ' - keydown 'y', ctrl: true - expect(editor.getText()).toBe '12345\n1 3\nabcd\na cefghi' - - it "does nothing if there's nothing above the cursor", -> - editor.insertText 'fill' - keydown 'y', ctrl: true - expect(editor.getText()).toBe '12345\nfill5\nabcd\nfillefghi' - - keydown 'y', ctrl: true - expect(editor.getText()).toBe '12345\nfill5\nabcd\nfillefghi' - - it "does nothing on the first line", -> - editor.setCursorBufferPosition([0, 2]) - editor.addCursorAtBufferPosition([3, 2]) - editor.insertText 'a' - expect(editor.getText()).toBe '12a345\n\nabcd\nefaghi' - keydown 'y', ctrl: true - expect(editor.getText()).toBe '12a345\n\nabcd\nefadghi' - - describe "the ctrl-e command", -> - beforeEach -> - atom.keymaps.add "test", - 'atom-text-editor.vim-mode.insert-mode': - 'ctrl-e': 'vim-mode:copy-from-line-below' - - it "copies from the line below", -> - keydown 'e', ctrl: true - expect(editor.getText()).toBe '12345\na\nabcd\nefghi' - - editor.insertText ' ' - keydown 'e', ctrl: true - expect(editor.getText()).toBe '12345\na c\nabcd\n efghi' - - it "does nothing if there's nothing below the cursor", -> - editor.insertText 'foo' - keydown 'e', ctrl: true - expect(editor.getText()).toBe '12345\nfood\nabcd\nfooefghi' - - keydown 'e', ctrl: true - expect(editor.getText()).toBe '12345\nfood\nabcd\nfooefghi' diff --git a/atom/packages/vim-mode/spec/motions-spec.coffee b/atom/packages/vim-mode/spec/motions-spec.coffee deleted file mode 100644 index 9c205ec..0000000 --- a/atom/packages/vim-mode/spec/motions-spec.coffee +++ /dev/null @@ -1,1996 +0,0 @@ -helpers = require './spec-helper' - -describe "Motions", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - normalModeInputKeydown = (key, opts = {}) -> - theEditor = opts.editor or editor - theEditor.normalModeInputView.editorElement.getModel().setText(key) - - submitNormalModeInputText = (text) -> - inputEditor = editor.normalModeInputView.editorElement - 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.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') - 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.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 [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.getRegister('"').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.getRegister('"').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.getRegister('"').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.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\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, 9]) - keydown('y') - keydown('B', shift: true) - expect(vimState.getRegister('"').text).toBe 'xyz-12' - - it "doesn't go past the beginning of the file", -> - editor.setCursorScreenPosition([0, 0]) - vimState.setRegister('"', text: 'abc') - keydown('y') - keydown('B', shift: true) - expect(vimState.getRegister('"').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 -> - 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] - - describe "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" - 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" - 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" - 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 current line", -> - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - - describe "as a selection", -> - beforeEach -> - keydown('d') - keydown('_') - - it "deletes the current line", -> - expect(editor.getText()).toBe " abc\nabcdefg\n" - expect(editor.getCursorScreenPosition()).toEqual [1, 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 [3, 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\n5\n6\n" - 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 normal mode", -> - beforeEach -> - keydown('g') - keydown('g') - - it "moves the cursor to the beginning of the first line", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - - 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 normal mode", -> - beforeEach -> - keydown('2') - keydown('g') - keydown('g') - - it "moves the cursor to a specified line", -> - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - 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 ") - - describe "as a motion", -> - it "moves the cursor to the last nonblank character", -> - editor.setCursorScreenPosition([1, 0]) - keydown('g') - keydown('_') - expect(editor.getCursorScreenPosition()).toEqual [1, 4] - - it "will move the cursor to the beginning of the line if necessary", -> - editor.setCursorScreenPosition([0, 2]) - keydown('g') - keydown('_') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - - describe "as a repeated motion", -> - it "moves the cursor downward and outward", -> - editor.setCursorScreenPosition([0, 0]) - keydown('2') - keydown('g') - keydown('_') - expect(editor.getCursorScreenPosition()).toEqual [1, 4] - - describe "as a selection", -> - it "selects the current line excluding whitespace", -> - editor.setCursorScreenPosition([1, 2]) - vimState.activateVisualMode() - keydown('2') - keydown('g') - keydown('_') - expect(editor.getSelectedText()).toEqual " 2 \n 3abc" - - 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, 0] - - 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", -> - pane = null - - beforeEach -> - pane = {activate: jasmine.createSpy("activate")} - spyOn(atom.workspace, 'getActivePane').andReturn(pane) - - editor.setText("abc\ndef\nabc\ndef\n") - editor.setCursorBufferPosition([0, 0]) - - # clear search history - vimState.globalVimState.searchHistory = [] - vimState.globalVimState.currentSearch = {} - - describe "as a motion", -> - it "beeps when repeating nonexistent last search", -> - keydown '/' - submitNormalModeInputText '' - expect(editor.getCursorBufferPosition()).toEqual [0, 0] - expect(atom.beep).toHaveBeenCalled() - - it "moves the cursor to the specified search pattern", -> - keydown('/') - - submitNormalModeInputText 'def' - - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - expect(pane.activate).toHaveBeenCalled() - expect(atom.beep).not.toHaveBeenCalled() - - it "loops back around", -> - editor.setCursorBufferPosition([3, 0]) - keydown('/') - submitNormalModeInputText 'def' - - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "uses a valid regex as a regex", -> - keydown('/') - # Cycle through the 'abc' on the first line with a character pattern - submitNormalModeInputText '[abc]' - expect(editor.getCursorBufferPosition()).toEqual [0, 1] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [0, 2] - expect(atom.beep).not.toHaveBeenCalled() - - it "uses an invalid regex as a literal string", -> - # Go straight to the literal [abc - editor.setText("abc\n[abc]\n") - keydown('/') - submitNormalModeInputText '[abc' - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "uses ? as a literal string", -> - editor.setText("abc\n[a?c?\n") - keydown('/') - submitNormalModeInputText '?' - expect(editor.getCursorBufferPosition()).toEqual [1, 2] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [1, 4] - expect(atom.beep).not.toHaveBeenCalled() - - it 'works with selection in visual mode', -> - editor.setText('one two three') - keydown('v') - keydown('/') - submitNormalModeInputText 'th' - expect(editor.getCursorBufferPosition()).toEqual [0, 9] - keydown('d') - expect(editor.getText()).toBe 'hree' - expect(atom.beep).not.toHaveBeenCalled() - - it 'extends selection when repeating search in visual mode', -> - editor.setText('line1\nline2\nline3') - keydown('v') - keydown('/') - submitNormalModeInputText 'line' - {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 - expect(atom.beep).not.toHaveBeenCalled() - - describe "case sensitivity", -> - beforeEach -> - editor.setText("\nabc\nABC\n") - editor.setCursorBufferPosition([0, 0]) - keydown('/') - - it "works in case sensitive mode", -> - submitNormalModeInputText 'ABC' - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "works in case insensitive mode", -> - submitNormalModeInputText '\\cAbC' - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "works in case insensitive mode wherever \\c is", -> - submitNormalModeInputText 'AbC\\c' - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "uses case insensitive search if useSmartcaseForSearch is true and searching lowercase", -> - atom.config.set 'vim-mode.useSmartcaseForSearch', true - submitNormalModeInputText 'abc' - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "uses case sensitive search if useSmartcaseForSearch is true and searching uppercase", -> - atom.config.set 'vim-mode.useSmartcaseForSearch', true - submitNormalModeInputText 'ABC' - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - expect(atom.beep).not.toHaveBeenCalled() - - describe "repeating", -> - it "does nothing with no search history", -> - editor.setCursorBufferPosition([0, 0]) - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [0, 0] - expect(atom.beep).toHaveBeenCalled() - - editor.setCursorBufferPosition([1, 1]) - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [1, 1] - expect(atom.beep.callCount).toBe 2 - - describe "repeating with search history", -> - beforeEach -> - keydown('/') - submitNormalModeInputText 'def' - - it "repeats previous search with /<enter>", -> - keydown('/') - submitNormalModeInputText('') - expect(editor.getCursorBufferPosition()).toEqual [3, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "repeats previous search with //", -> - keydown('/') - submitNormalModeInputText('/') - expect(editor.getCursorBufferPosition()).toEqual [3, 0] - expect(atom.beep).not.toHaveBeenCalled() - - describe "the n keybinding", -> - it "repeats the last search", -> - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [3, 0] - expect(atom.beep).not.toHaveBeenCalled() - - 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] - expect(atom.beep).not.toHaveBeenCalled() - - describe "composing", -> - it "composes with operators", -> - keydown('d') - keydown('/') - submitNormalModeInputText('def') - expect(editor.getText()).toEqual "def\nabc\ndef\n" - expect(atom.beep).not.toHaveBeenCalled() - - it "repeats correctly with operators", -> - keydown('d') - keydown('/') - submitNormalModeInputText('def') - - keydown('.') - expect(editor.getText()).toEqual "def\n" - expect(atom.beep).not.toHaveBeenCalled() - - describe "when reversed as ?", -> - it "moves the cursor backwards to the specified search pattern", -> - keydown('?') - submitNormalModeInputText('def') - expect(editor.getCursorBufferPosition()).toEqual [3, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "accepts / as a literal search pattern", -> - editor.setText("abc\nd/f\nabc\nd/f\n") - editor.setCursorBufferPosition([0, 0]) - keydown('?') - submitNormalModeInputText('/') - expect(editor.getCursorBufferPosition()).toEqual [3, 1] - keydown('?') - submitNormalModeInputText('/') - expect(editor.getCursorBufferPosition()).toEqual [1, 1] - expect(atom.beep).not.toHaveBeenCalled() - - describe "repeating", -> - beforeEach -> - keydown('?') - submitNormalModeInputText('def') - - it "repeats previous search as reversed with ?<enter>", -> - keydown('?') - submitNormalModeInputText('') - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "repeats previous search as reversed with ??", -> - keydown('?') - submitNormalModeInputText('?') - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - expect(atom.beep).not.toHaveBeenCalled() - - describe 'the n keybinding', -> - it "repeats the last search backwards", -> - editor.setCursorBufferPosition([0, 0]) - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [3, 0] - expect(atom.beep).not.toHaveBeenCalled() - - describe 'the N keybinding', -> - it "repeats the last search forwards", -> - editor.setCursorBufferPosition([0, 0]) - keydown('N', shift: true) - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - expect(atom.beep).not.toHaveBeenCalled() - - describe "using search history", -> - inputEditor = null - - beforeEach -> - keydown('/') - submitNormalModeInputText('def') - expect(editor.getCursorBufferPosition()).toEqual [1, 0] - - keydown('/') - submitNormalModeInputText('abc') - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - - inputEditor = editor.normalModeInputView.editorElement - - it "allows searching history in the search field", -> - keydown('/') - atom.commands.dispatch(inputEditor, 'core:move-up') - expect(inputEditor.getModel().getText()).toEqual('abc') - atom.commands.dispatch(inputEditor, 'core:move-up') - expect(inputEditor.getModel().getText()).toEqual('def') - atom.commands.dispatch(inputEditor, 'core:move-up') - expect(inputEditor.getModel().getText()).toEqual('def') - expect(atom.beep).not.toHaveBeenCalled() - - it "resets the search field to empty when scrolling back", -> - keydown('/') - atom.commands.dispatch(inputEditor, 'core:move-up') - expect(inputEditor.getModel().getText()).toEqual('abc') - atom.commands.dispatch(inputEditor, 'core:move-up') - expect(inputEditor.getModel().getText()).toEqual('def') - atom.commands.dispatch(inputEditor, 'core:move-down') - expect(inputEditor.getModel().getText()).toEqual('abc') - atom.commands.dispatch(inputEditor, 'core:move-down') - expect(inputEditor.getModel().getText()).toEqual '' - expect(atom.beep).not.toHaveBeenCalled() - - describe "the * keybinding", -> - beforeEach -> - editor.setText("abd\n@def\nabd\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 "repeats with the n key", -> - keydown("*") - expect(editor.getCursorBufferPosition()).toEqual [2, 0] - keydown("n") - 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 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") - editor.setCursorBufferPosition([1, 1]) - keydown("*") - # this is because of the default isKeyword value of vim-mode that includes @ - 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\na @def\n abc\n @def") - editor.setCursorBufferPosition([1, 1]) - 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, 0] - - describe "the hash keybinding", -> - describe "as a motion", -> - it "moves cursor to previous occurence of word under cursor", -> - editor.setText("abc\n@def\nabc\ndef\n") - editor.setCursorBufferPosition([2, 1]) - keydown("#") - expect(editor.getCursorBufferPosition()).toEqual [0, 0] - - it "repeats with n", -> - editor.setText("abc\n@def\nabc\ndef\nabc\n") - editor.setCursorBufferPosition([2, 1]) - keydown("#") - expect(editor.getCursorBufferPosition()).toEqual [0, 0] - keydown("n") - expect(editor.getCursorBufferPosition()).toEqual [4, 0] - keydown("n") - 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 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.getLastCursor(), 'setScreenPosition') - - it "moves the cursor to the first row if visible", -> - spyOn(editor, 'getFirstVisibleScreenRow').andReturn(0) - keydown('H', shift: true) - expect(editor.getLastCursor().setScreenPosition).toHaveBeenCalledWith([0, 0]) - - it "moves the cursor to the first visible row plus offset", -> - spyOn(editor, 'getFirstVisibleScreenRow').andReturn(2) - keydown('H', shift: true) - expect(editor.getLastCursor().setScreenPosition).toHaveBeenCalledWith([4, 0]) - - it "respects counts", -> - spyOn(editor, 'getFirstVisibleScreenRow').andReturn(0) - keydown('3') - keydown('H', shift: true) - expect(editor.getLastCursor().setScreenPosition).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.getLastCursor(), 'setScreenPosition') - - it "moves the cursor to the first row if visible", -> - spyOn(editor, 'getLastVisibleScreenRow').andReturn(10) - keydown('L', shift: true) - expect(editor.getLastCursor().setScreenPosition).toHaveBeenCalledWith([10, 0]) - - it "moves the cursor to the first visible row plus offset", -> - spyOn(editor, 'getLastVisibleScreenRow').andReturn(6) - keydown('L', shift: true) - expect(editor.getLastCursor().setScreenPosition).toHaveBeenCalledWith([4, 0]) - - it "respects counts", -> - spyOn(editor, 'getLastVisibleScreenRow').andReturn(10) - keydown('3') - keydown('L', shift: true) - expect(editor.getLastCursor().setScreenPosition).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.getLastCursor(), 'setScreenPosition') - spyOn(editor, 'getLastVisibleScreenRow').andReturn(10) - spyOn(editor, 'getFirstVisibleScreenRow').andReturn(0) - - it "moves the cursor to the first row if visible", -> - keydown('M', shift: true) - expect(editor.getLastCursor().setScreenPosition).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') - normalModeInputKeydown('a') - editor.setCursorBufferPosition([0, 0]) - keydown('\'') - normalModeInputKeydown('a') - expect(editor.getCursorBufferPosition()).toEqual [1, 4] - - it 'moves literally to a mark', -> - editor.setCursorBufferPosition([1, 1]) - keydown('m') - normalModeInputKeydown('a') - editor.setCursorBufferPosition([0, 0]) - keydown('`') - normalModeInputKeydown('a') - expect(editor.getCursorBufferPosition()).toEqual [1, 1] - - it 'deletes to a mark by line', -> - editor.setCursorBufferPosition([1, 5]) - keydown('m') - normalModeInputKeydown('a') - editor.setCursorBufferPosition([0, 0]) - keydown('d') - keydown('\'') - normalModeInputKeydown('a') - expect(editor.getText()).toEqual '56\n' - - it 'deletes before to a mark literally', -> - editor.setCursorBufferPosition([1, 5]) - keydown('m') - normalModeInputKeydown('a') - editor.setCursorBufferPosition([0, 1]) - keydown('d') - keydown('`') - normalModeInputKeydown('a') - expect(editor.getText()).toEqual ' 4\n56\n' - - it 'deletes after to a mark literally', -> - editor.setCursorBufferPosition([1, 5]) - keydown('m') - normalModeInputKeydown('a') - editor.setCursorBufferPosition([2, 1]) - keydown('d') - keydown('`') - normalModeInputKeydown('a') - expect(editor.getText()).toEqual ' 12\n 36\n' - - it 'moves back to previous', -> - editor.setCursorBufferPosition([1, 5]) - keydown('`') - normalModeInputKeydown('`') - editor.setCursorBufferPosition([2, 1]) - keydown('`') - normalModeInputKeydown('`') - 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') - normalModeInputKeydown('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) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - - it 'respects count forward', -> - keydown('2') - keydown('f') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - it 'respects count backward', -> - editor.setCursorScreenPosition([0, 6]) - keydown('2') - keydown('F', shift: true) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - - it "doesn't move if the character specified isn't found", -> - keydown('f') - normalModeInputKeydown('d') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "doesn't move if there aren't the specified count of the specified character", -> - keydown('1') - keydown('0') - keydown('f') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - # a bug was making this behaviour depend on the count - keydown('1') - keydown('1') - keydown('f') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - # and backwards now - editor.setCursorScreenPosition([0, 6]) - keydown('1') - keydown('0') - keydown('F', shift: true) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - keydown('1') - keydown('1') - keydown('F', shift: true) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - it "composes with d", -> - editor.setCursorScreenPosition([0, 3]) - keydown('d') - keydown('2') - keydown('f') - normalModeInputKeydown('a') - expect(editor.getText()).toEqual 'abcbc\n' - - it "cancels c when no match found", -> - keydown('c') - keydown('f') - normalModeInputKeydown('d') - expect(editor.getText()).toBe("abcabcabcabc\n") - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(vimState.mode).toBe "normal" - - describe 'with accented characters', -> - buildIMECompositionEvent = (event, {data, target}={}) -> - event = new Event(event) - event.data = data - Object.defineProperty(event, 'target', get: -> target) - event - - buildTextInputEvent = ({data, target}) -> - event = new Event('textInput') - event.data = data - Object.defineProperty(event, 'target', get: -> target) - event - - beforeEach -> - editor.setText("abcébcabcébc\n") - editor.setCursorScreenPosition([0, 0]) - - it 'works with IME composition', -> - keydown('f') - normalModeEditor = editor.normalModeInputView.editorElement - jasmine.attachToDOM(normalModeEditor) - domNode = normalModeEditor.component.domNode - inputNode = domNode.querySelector('.hidden-input') - domNode.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode)) - domNode.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: "´", target: inputNode)) - expect(normalModeEditor.getModel().getText()).toEqual '´' - domNode.dispatchEvent(buildIMECompositionEvent('compositionend', data: "é", target: inputNode)) - domNode.dispatchEvent(buildTextInputEvent(data: 'é', target: inputNode)) - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - - 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') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - # or stays put when it's already there - keydown('t') - normalModeInputKeydown('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) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - - it 'respects count forward', -> - keydown('2') - keydown('t') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - it 'respects count backward', -> - editor.setCursorScreenPosition([0, 6]) - keydown('2') - keydown('T', shift: true) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - - it "doesn't move if the character specified isn't found", -> - keydown('t') - normalModeInputKeydown('d') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(atom.beep).not.toHaveBeenCalled() - - it "doesn't move if there aren't the specified count of the specified character", -> - keydown('1') - keydown('0') - keydown('t') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - # a bug was making this behaviour depend on the count - keydown('1') - keydown('1') - keydown('t') - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - # and backwards now - editor.setCursorScreenPosition([0, 6]) - keydown('1') - keydown('0') - keydown('T', shift: true) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - keydown('1') - keydown('1') - keydown('T', shift: true) - normalModeInputKeydown('a') - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - it "composes with d", -> - editor.setCursorScreenPosition([0, 3]) - keydown('d') - keydown('2') - keydown('t') - normalModeInputKeydown('b') - expect(editor.getText()).toBe 'abcbcabc\n' - - it "selects character under cursor even when no movement happens", -> - editor.setCursorBufferPosition([0, 0]) - keydown('d') - keydown('t') - normalModeInputKeydown('b') - expect(editor.getText()).toBe 'bcabcabcabc\n' - - describe 'the v keybinding', -> - beforeEach -> - editor.setText("01\n002\n0003\n00004\n000005\n") - editor.setCursorScreenPosition([1, 1]) - - it "selects down a line", -> - keydown('v') - keydown('j') - keydown('j') - expect(editor.getSelectedText()).toBe "02\n0003\n00" - expect(editor.getSelectedBufferRange().isSingleLine()).toBeFalsy() - - it "selects right", -> - keydown('v') - keydown('l') - expect(editor.getSelectedText()).toBe "02" - expect(editor.getSelectedBufferRange().isSingleLine()).toBeTruthy() - - describe 'the V keybinding', -> - beforeEach -> - editor.setText("01\n002\n0003\n00004\n000005\n") - editor.setCursorScreenPosition([1, 1]) - - it "selects down a line", -> - keydown('V', shift: true) - expect(editor.getSelectedBufferRange().isSingleLine()).toBeFalsy() - keydown('j') - keydown('j') - expect(editor.getSelectedText()).toBe "002\n0003\n00004\n" - expect(editor.getSelectedBufferRange().isSingleLine()).toBeFalsy() - - it "selects up a line", -> - keydown('V', shift: true) - keydown('k') - expect(editor.getSelectedText()).toBe "01\n002\n" - - describe 'the ; and , keybindings', -> - beforeEach -> - editor.setText("abcabcabcabc\n") - editor.setCursorScreenPosition([0, 0]) - - it "repeat f in same direction", -> - keydown('f') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - - it "repeat F in same direction", -> - editor.setCursorScreenPosition([0, 10]) - keydown('F', shift: true) - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - it "repeat f in opposite direction", -> - editor.setCursorScreenPosition([0, 6]) - keydown('f') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - it "repeat F in opposite direction", -> - editor.setCursorScreenPosition([0, 4]) - keydown('F', shift: true) - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - - it "alternate repeat f in same direction and reverse", -> - keydown('f') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - it "alternate repeat F in same direction and reverse", -> - editor.setCursorScreenPosition([0, 10]) - keydown('F', shift: true) - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - - it "repeat t in same direction", -> - keydown('t') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - it "repeat T in same direction", -> - editor.setCursorScreenPosition([0, 10]) - keydown('T', shift: true) - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 9] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - it "repeat t in opposite direction first, and then reverse", -> - editor.setCursorScreenPosition([0, 3]) - keydown('t') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - it "repeat T in opposite direction first, and then reverse", -> - editor.setCursorScreenPosition([0, 4]) - keydown('T', shift: true) - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - - it "repeat with count in same direction", -> - editor.setCursorScreenPosition([0, 0]) - keydown('f') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - keydown('2') - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - - it "repeat with count in reverse direction", -> - editor.setCursorScreenPosition([0, 6]) - keydown('f') - normalModeInputKeydown('c') - expect(editor.getCursorScreenPosition()).toEqual [0, 8] - keydown('2') - keydown(',') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - it "shares the most recent find/till command with other editors", -> - helpers.getEditorElement (otherEditorElement) -> - otherEditor = otherEditorElement.getModel() - - editor.setText("a baz bar\n") - editor.setCursorScreenPosition([0, 0]) - - otherEditor.setText("foo bar baz") - otherEditor.setCursorScreenPosition([0, 0]) - - # by default keyDown and such go in the usual editor - keydown('f') - normalModeInputKeydown('b') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - expect(otherEditor.getCursorScreenPosition()).toEqual [0, 0] - - # replay same find in the other editor - keydown(';', element: otherEditorElement) - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - expect(otherEditor.getCursorScreenPosition()).toEqual [0, 4] - - # do a till in the other editor - keydown('t', element: otherEditorElement) - normalModeInputKeydown('r', editor: otherEditor) - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - expect(otherEditor.getCursorScreenPosition()).toEqual [0, 5] - - # and replay in the normal editor - keydown(';') - expect(editor.getCursorScreenPosition()).toEqual [0, 7] - expect(otherEditor.getCursorScreenPosition()).toEqual [0, 5] - expect(atom.beep).not.toHaveBeenCalled() - - 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('h') - keydown('%') - expect(editor.getCursorScreenPosition()).toEqual [0, 7] - - it 'moves correctly when composed with v going backward', -> - editor.setCursorScreenPosition([0, 5]) - 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" - - it "finds matches across multiple lines", -> - editor.setText("...(\n...)") - editor.setCursorScreenPosition([0, 0]) - keydown("%") - expect(editor.getCursorScreenPosition()).toEqual([1, 3]) - - it "does not affect search history", -> - keydown('/') - submitNormalModeInputText 'func' - expect(editor.getCursorBufferPosition()).toEqual [0, 31] - keydown('%') - expect(editor.getCursorBufferPosition()).toEqual [0, 60] - keydown('n') - expect(editor.getCursorBufferPosition()).toEqual [0, 31] - - describe "scrolling screen and keeping cursor in the same screen position", -> - beforeEach -> - editor.setText([0...80].join("\n")) - editor.setHeight(20 * 10) - editor.setLineHeightInPixels(10) - editor.setScrollTop(40 * 10) - editor.setCursorBufferPosition([42, 0]) - - describe "the ctrl-u keybinding", -> - it "moves the screen down by half screen size and keeps cursor onscreen", -> - keydown('u', ctrl: true) - expect(editor.getScrollTop()).toEqual 300 - expect(editor.getCursorBufferPosition()).toEqual [32, 0] - - it "selects on visual mode", -> - editor.setCursorBufferPosition([42, 1]) - vimState.activateVisualMode() - keydown('u', ctrl: true) - expect(editor.getSelectedText()).toEqual [32..42].join("\n") - - it "selects on linewise mode", -> - vimState.activateVisualMode('linewise') - keydown('u', ctrl: true) - expect(editor.getSelectedText()).toEqual [32..42].join("\n").concat("\n") - - describe "the ctrl-b keybinding", -> - it "moves screen up one page", -> - keydown('b', ctrl: true) - expect(editor.getScrollTop()).toEqual 200 - expect(editor.getCursorScreenPosition()).toEqual [22, 0] - - it "selects on visual mode", -> - editor.setCursorBufferPosition([42, 1]) - vimState.activateVisualMode() - keydown('b', ctrl: true) - expect(editor.getSelectedText()).toEqual [22..42].join("\n") - - it "selects on linewise mode", -> - vimState.activateVisualMode('linewise') - keydown('b', ctrl: true) - expect(editor.getSelectedText()).toEqual [22..42].join("\n").concat("\n") - - - describe "the ctrl-d keybinding", -> - it "moves the screen down by half screen size and keeps cursor onscreen", -> - keydown('d', ctrl: true) - expect(editor.getScrollTop()).toEqual 500 - expect(editor.getCursorBufferPosition()).toEqual [52, 0] - - it "selects on visual mode", -> - editor.setCursorBufferPosition([42, 1]) - vimState.activateVisualMode() - keydown('d', ctrl: true) - expect(editor.getSelectedText()).toEqual [42..52].join("\n").slice(1, -1) - - it "selects on linewise mode", -> - vimState.activateVisualMode('linewise') - keydown('d', ctrl: true) - expect(editor.getSelectedText()).toEqual [42..52].join("\n").concat("\n") - - describe "the ctrl-f keybinding", -> - it "moves screen down one page", -> - keydown('f', ctrl: true) - expect(editor.getScrollTop()).toEqual 600 - expect(editor.getCursorScreenPosition()).toEqual [62, 0] - - it "selects on visual mode", -> - editor.setCursorBufferPosition([42, 1]) - vimState.activateVisualMode() - keydown('f', ctrl: true) - expect(editor.getSelectedText()).toEqual [42..62].join("\n").slice(1, -1) - - it "selects on linewise mode", -> - vimState.activateVisualMode('linewise') - keydown('f', ctrl: true) - expect(editor.getSelectedText()).toEqual [42..62].join("\n").concat("\n") diff --git a/atom/packages/vim-mode/spec/operators-spec.coffee b/atom/packages/vim-mode/spec/operators-spec.coffee deleted file mode 100644 index 0dff120..0000000 --- a/atom/packages/vim-mode/spec/operators-spec.coffee +++ /dev/null @@ -1,2284 +0,0 @@ -helpers = require './spec-helper' -settings = require '../lib/settings' - -describe "Operators", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - normalModeInputKeydown = (key, opts = {}) -> - editor.normalModeInputView.editorElement.getModel().setText(key) - - describe "cancelling operations", -> - it "throws an error when no operation is pending", -> - # cancel operation pushes an empty input operation - # doing this without a pending operation would throw an exception - expect(-> vimState.pushOperations(new Input(''))).toThrow() - - it "cancels and cleans up properly", -> - # make sure normalModeInputView is created - keydown('/') - expect(vimState.isOperatorPending()).toBe true - editor.normalModeInputView.viewModel.cancel() - - expect(vimState.isOperatorPending()).toBe false - expect(editor.normalModeInputView).toBe undefined - - describe "the x keybinding", -> - describe "on a line with content", -> - describe "without vim-mode.wrapLeftRightMotion", -> - beforeEach -> - editor.setText("abc\n012345\n\nxyz") - editor.setCursorScreenPosition([1, 4]) - - it "deletes a character", -> - keydown('x') - expect(editor.getText()).toBe 'abc\n01235\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 4] - expect(vimState.getRegister('"').text).toBe '4' - - keydown('x') - expect(editor.getText()).toBe 'abc\n0123\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 3] - expect(vimState.getRegister('"').text).toBe '5' - - keydown('x') - expect(editor.getText()).toBe 'abc\n012\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - expect(vimState.getRegister('"').text).toBe '3' - - keydown('x') - expect(editor.getText()).toBe 'abc\n01\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 1] - expect(vimState.getRegister('"').text).toBe '2' - - keydown('x') - expect(editor.getText()).toBe 'abc\n0\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe '1' - - keydown('x') - expect(editor.getText()).toBe 'abc\n\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe '0' - - it "deletes multiple characters with a count", -> - keydown('2') - keydown('x') - expect(editor.getText()).toBe 'abc\n0123\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 3] - expect(vimState.getRegister('"').text).toBe '45' - - editor.setCursorScreenPosition([0, 1]) - keydown('3') - keydown('x') - expect(editor.getText()).toBe 'a\n0123\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(vimState.getRegister('"').text).toBe 'bc' - - describe "with multiple cursors", -> - beforeEach -> - editor.setText "abc\n012345\n\nxyz" - editor.setCursorScreenPosition [1, 4] - editor.addCursorAtBufferPosition [0, 1] - - it "is undone as one operation", -> - keydown('x') - expect(editor.getText()).toBe "ac\n01235\n\nxyz" - keydown('u') - expect(editor.getText()).toBe "abc\n012345\n\nxyz" - - describe "with vim-mode.wrapLeftRightMotion", -> - beforeEach -> - editor.setText("abc\n012345\n\nxyz") - editor.setCursorScreenPosition([1, 4]) - atom.config.set('vim-mode.wrapLeftRightMotion', true) - - it "deletes a character", -> - # copy of the earlier test because wrapLeftRightMotion should not affect it - keydown('x') - expect(editor.getText()).toBe 'abc\n01235\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 4] - expect(vimState.getRegister('"').text).toBe '4' - - keydown('x') - expect(editor.getText()).toBe 'abc\n0123\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 3] - expect(vimState.getRegister('"').text).toBe '5' - - keydown('x') - expect(editor.getText()).toBe 'abc\n012\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - expect(vimState.getRegister('"').text).toBe '3' - - keydown('x') - expect(editor.getText()).toBe 'abc\n01\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 1] - expect(vimState.getRegister('"').text).toBe '2' - - keydown('x') - expect(editor.getText()).toBe 'abc\n0\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe '1' - - keydown('x') - expect(editor.getText()).toBe 'abc\n\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe '0' - - it "deletes multiple characters and newlines with a count", -> - atom.config.set('vim-mode.wrapLeftRightMotion', true) - keydown('2') - keydown('x') - expect(editor.getText()).toBe 'abc\n0123\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [1, 3] - expect(vimState.getRegister('"').text).toBe '45' - - editor.setCursorScreenPosition([0, 1]) - keydown('3') - keydown('x') - expect(editor.getText()).toBe 'a0123\n\nxyz' - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(vimState.getRegister('"').text).toBe 'bc\n' - - keydown('7') - keydown('x') - expect(editor.getText()).toBe 'ayz' - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(vimState.getRegister('"').text).toBe '0123\n\nx' - - describe "on an empty line", -> - beforeEach -> - editor.setText("abc\n012345\n\nxyz") - editor.setCursorScreenPosition([2, 0]) - - it "deletes nothing on an empty line when vim-mode.wrapLeftRightMotion is false", -> - atom.config.set('vim-mode.wrapLeftRightMotion', false) - keydown('x') - expect(editor.getText()).toBe "abc\n012345\n\nxyz" - expect(editor.getCursorScreenPosition()).toEqual [2, 0] - - it "deletes an empty line when vim-mode.wrapLeftRightMotion is true", -> - atom.config.set('vim-mode.wrapLeftRightMotion', true) - keydown('x') - expect(editor.getText()).toBe "abc\n012345\nxyz" - expect(editor.getCursorScreenPosition()).toEqual [2, 0] - - describe "the X keybinding", -> - describe "on a line with content", -> - beforeEach -> - editor.setText("ab\n012345") - editor.setCursorScreenPosition([1, 2]) - - it "deletes a character", -> - keydown('X', shift: true) - expect(editor.getText()).toBe 'ab\n02345' - expect(editor.getCursorScreenPosition()).toEqual [1, 1] - expect(vimState.getRegister('"').text).toBe '1' - - keydown('X', shift: true) - expect(editor.getText()).toBe 'ab\n2345' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe '0' - - keydown('X', shift: true) - expect(editor.getText()).toBe 'ab\n2345' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe '0' - - atom.config.set('vim-mode.wrapLeftRightMotion', true) - keydown('X', shift: true) - expect(editor.getText()).toBe 'ab2345' - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - expect(vimState.getRegister('"').text).toBe '\n' - - describe "on an empty line", -> - beforeEach -> - editor.setText("012345\n\nabcdef") - editor.setCursorScreenPosition([1, 0]) - - it "deletes nothing when vim-mode.wrapLeftRightMotion is false", -> - atom.config.set('vim-mode.wrapLeftRightMotion', false) - keydown('X', shift: true) - expect(editor.getText()).toBe "012345\n\nabcdef" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - it "deletes the newline when wrapLeftRightMotion is true", -> - atom.config.set('vim-mode.wrapLeftRightMotion', true) - keydown('X', shift: true) - expect(editor.getText()).toBe "012345\nabcdef" - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - describe "the s keybinding", -> - beforeEach -> - editor.setText('012345') - editor.setCursorScreenPosition([0, 1]) - - it "deletes the character to the right and enters insert mode", -> - keydown('s') - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getText()).toBe '02345' - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(vimState.getRegister('"').text).toBe '1' - - it "is repeatable", -> - editor.setCursorScreenPosition([0, 0]) - keydown('3') - keydown('s') - editor.insertText("ab") - keydown('escape') - expect(editor.getText()).toBe 'ab345' - editor.setCursorScreenPosition([0, 2]) - keydown('.') - expect(editor.getText()).toBe 'abab' - - it "is undoable", -> - editor.setCursorScreenPosition([0, 0]) - keydown('3') - keydown('s') - editor.insertText("ab") - keydown('escape') - expect(editor.getText()).toBe 'ab345' - keydown('u') - expect(editor.getText()).toBe '012345' - expect(editor.getSelectedText()).toBe '' - - describe "in visual mode", -> - beforeEach -> - keydown('v') - editor.selectRight() - keydown('s') - - it "deletes the selected characters and enters insert mode", -> - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getText()).toBe '0345' - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(vimState.getRegister('"').text).toBe '12' - - describe "the S keybinding", -> - beforeEach -> - editor.setText("12345\nabcde\nABCDE") - editor.setCursorScreenPosition([1, 3]) - - it "deletes the entire line and enters insert mode", -> - keydown('S', shift: true) - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getText()).toBe "12345\n\nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe "abcde\n" - expect(vimState.getRegister('"').type).toBe 'linewise' - - it "is repeatable", -> - keydown('S', shift: true) - editor.insertText("abc") - keydown 'escape' - expect(editor.getText()).toBe "12345\nabc\nABCDE" - editor.setCursorScreenPosition([2, 3]) - keydown '.' - expect(editor.getText()).toBe "12345\nabc\nabc\n" - - it "is undoable", -> - keydown('S', shift: true) - editor.insertText("abc") - keydown 'escape' - expect(editor.getText()).toBe "12345\nabc\nABCDE" - keydown 'u' - expect(editor.getText()).toBe "12345\nabcde\nABCDE" - expect(editor.getSelectedText()).toBe '' - - it "works when the cursor's goal column is greater than its current column", -> - editor.setText("\n12345") - editor.setCursorBufferPosition([1, Infinity]) - editor.moveUp() - keydown("S", shift: true) - expect(editor.getText()).toBe("\n12345") - - # Can't be tested without setting grammar of test buffer - xit "respects indentation", -> - - describe "the d keybinding", -> - it "enters operator-pending mode", -> - keydown('d') - expect(editorElement.classList.contains('operator-pending-mode')).toBe(true) - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - describe "when followed by a d", -> - it "deletes the current line and exits operator-pending mode", -> - editor.setText("12345\nabcde\n\nABCDE") - editor.setCursorScreenPosition([1, 1]) - - keydown('d') - keydown('d') - - expect(editor.getText()).toBe "12345\n\nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe "abcde\n" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "deletes the last line", -> - editor.setText("12345\nabcde\nABCDE") - editor.setCursorScreenPosition([2, 1]) - - keydown('d') - keydown('d') - - expect(editor.getText()).toBe "12345\nabcde\n" - expect(editor.getCursorScreenPosition()).toEqual [2, 0] - - it "leaves the cursor on the first nonblank character", -> - editor.setText("12345\n abcde\n") - editor.setCursorScreenPosition([0, 4]) - - keydown('d') - keydown('d') - - expect(editor.getText()).toBe " abcde\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "undo behavior", -> - beforeEach -> - editor.setText("12345\nabcde\nABCDE\nQWERT") - editor.setCursorScreenPosition([1, 1]) - - it "undoes both lines", -> - keydown('d') - keydown('2') - keydown('d') - - keydown('u') - - expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT" - expect(editor.getSelectedText()).toBe '' - - describe "with multiple cursors", -> - beforeEach -> - editor.setCursorBufferPosition([1, 1]) - editor.addCursorAtBufferPosition([0, 0]) - - it "is undone as one operation", -> - keydown('d') - keydown('l') - - keydown('u') - - expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT" - expect(editor.getSelectedText()).toBe '' - - describe "when followed by a w", -> - it "deletes the next word until the end of the line and exits operator-pending mode", -> - editor.setText("abcd efg\nabc") - editor.setCursorScreenPosition([0, 5]) - - keydown('d') - keydown('w') - - # Incompatibility with VIM. In vim, `w` behaves differently as an - # operator than as a motion; it stops at the end of a line.expect(editor.getText()).toBe "abcd abc" - expect(editor.getText()).toBe "abcd abc" - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "deletes to the beginning of the next word", -> - editor.setText('abcd efg') - editor.setCursorScreenPosition([0, 2]) - - keydown('d') - keydown('w') - - expect(editor.getText()).toBe 'abefg' - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - editor.setText('one two three four') - editor.setCursorScreenPosition([0, 0]) - - keydown('d') - keydown('3') - keydown('w') - - expect(editor.getText()).toBe 'four' - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - - describe "when followed by an iw", -> - it "deletes the containing word", -> - editor.setText("12345 abcde ABCDE") - editor.setCursorScreenPosition([0, 9]) - - keydown('d') - expect(editorElement.classList.contains('operator-pending-mode')).toBe(true) - keydown('i') - keydown('w') - - expect(editor.getText()).toBe "12345 ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - expect(vimState.getRegister('"').text).toBe "abcde" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - describe "when followed by a j", -> - originalText = "12345\nabcde\nABCDE\n" - - beforeEach -> - editor.setText(originalText) - - describe "on the beginning of the file", -> - it "deletes the next two lines", -> - editor.setCursorScreenPosition([0, 0]) - keydown('d') - keydown('j') - expect(editor.getText()).toBe("ABCDE\n") - - describe "on the end of the file", -> - it "deletes nothing", -> - editor.setCursorScreenPosition([4, 0]) - keydown('d') - keydown('j') - expect(editor.getText()).toBe(originalText) - - describe "on the middle of second line", -> - it "deletes the last two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('d') - keydown('j') - expect(editor.getText()).toBe("12345\n") - - describe "when followed by an k", -> - originalText = "12345\nabcde\nABCDE" - - beforeEach -> - editor.setText(originalText) - - describe "on the end of the file", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([2, 4]) - keydown('d') - keydown('k') - expect(editor.getText()).toBe("12345\n") - - describe "on the beginning of the file", -> - xit "deletes nothing", -> - editor.setCursorScreenPosition([0, 0]) - keydown('d') - keydown('k') - expect(editor.getText()).toBe(originalText) - - describe "when on the middle of second line", -> - it "deletes the first two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('d') - keydown('k') - expect(editor.getText()).toBe("ABCDE") - - describe "when followed by a G", -> - beforeEach -> - originalText = "12345\nabcde\nABCDE" - editor.setText(originalText) - - describe "on the beginning of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 0]) - keydown('d') - keydown('G', shift: true) - expect(editor.getText()).toBe("12345\n") - - describe "on the middle of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('d') - keydown('G', shift: true) - expect(editor.getText()).toBe("12345\n") - - describe "when followed by a goto line G", -> - beforeEach -> - originalText = "12345\nabcde\nABCDE" - editor.setText(originalText) - - describe "on the beginning of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 0]) - keydown('d') - keydown('2') - keydown('G', shift: true) - expect(editor.getText()).toBe("12345\nABCDE") - - describe "on the middle of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('d') - keydown('2') - keydown('G', shift: true) - expect(editor.getText()).toBe("12345\nABCDE") - - describe "when followed by a t)", -> - describe "with the entire line yanked before", -> - beforeEach -> - editor.setText("test (xyz)") - editor.setCursorScreenPosition([0, 6]) - - it "deletes until the closing parenthesis", -> - keydown('y') - keydown('y') - keydown('d') - keydown('t') - normalModeInputKeydown(')') - expect(editor.getText()).toBe("test ()") - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - describe "with multiple cursors", -> - it "deletes each selection", -> - editor.setText("abcd\n1234\nABCD\n") - editor.setCursorBufferPosition([0, 1]) - editor.addCursorAtBufferPosition([1, 2]) - editor.addCursorAtBufferPosition([2, 3]) - - keydown('d') - keydown('e') - - expect(editor.getText()).toBe "a\n12\nABC" - expect(editor.getCursorBufferPositions()).toEqual [ - [0, 0], - [1, 1], - [2, 2], - ] - - it "doesn't delete empty selections", -> - editor.setText("abcd\nabc\nabd") - editor.setCursorBufferPosition([0, 0]) - editor.addCursorAtBufferPosition([1, 0]) - editor.addCursorAtBufferPosition([2, 0]) - - keydown('d') - keydown('t') - normalModeInputKeydown('d') - - expect(editor.getText()).toBe "d\nabc\nd" - expect(editor.getCursorBufferPositions()).toEqual [ - [0, 0], - [1, 0], - [2, 0], - ] - - describe "the D keybinding", -> - beforeEach -> - editor.getBuffer().setText("012\n") - editor.setCursorScreenPosition([0, 1]) - keydown('D', shift: true) - - it "deletes the contents until the end of the line", -> - expect(editor.getText()).toBe "0\n" - - describe "the c keybinding", -> - beforeEach -> - editor.setText("12345\nabcde\nABCDE") - - describe "when followed by a c", -> - describe "with autoindent", -> - beforeEach -> - editor.setText("12345\n abcde\nABCDE") - editor.setCursorScreenPosition([1, 1]) - spyOn(editor, 'shouldAutoIndent').andReturn(true) - spyOn(editor, 'autoIndentBufferRow').andCallFake (line) -> - editor.indent() - spyOn(editor.languageMode, 'suggestedIndentForLineAtBufferRow').andCallFake -> 1 - - it "deletes the current line and enters insert mode", -> - editor.setCursorScreenPosition([1, 1]) - - keydown('c') - keydown('c') - - expect(editor.getText()).toBe "12345\n \nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - expect(editorElement.classList.contains('normal-mode')).toBe(false) - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - it "is repeatable", -> - keydown('c') - keydown('c') - editor.insertText("abc") - keydown 'escape' - expect(editor.getText()).toBe "12345\n abc\nABCDE" - editor.setCursorScreenPosition([2, 3]) - keydown '.' - expect(editor.getText()).toBe "12345\n abc\n abc\n" - - it "is undoable", -> - keydown('c') - keydown('c') - editor.insertText("abc") - keydown 'escape' - expect(editor.getText()).toBe "12345\n abc\nABCDE" - keydown 'u' - expect(editor.getText()).toBe "12345\n abcde\nABCDE" - expect(editor.getSelectedText()).toBe '' - - describe "when the cursor is on the last line", -> - it "deletes the line's content and enters insert mode on the last line", -> - editor.setCursorScreenPosition([2, 1]) - - keydown('c') - keydown('c') - - expect(editor.getText()).toBe "12345\nabcde\n\n" - expect(editor.getCursorScreenPosition()).toEqual [2, 0] - expect(editorElement.classList.contains('normal-mode')).toBe(false) - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - describe "when the cursor is on the only line", -> - it "deletes the line's content and enters insert mode", -> - editor.setText("12345") - editor.setCursorScreenPosition([0, 2]) - - keydown('c') - keydown('c') - - expect(editor.getText()).toBe "" - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('normal-mode')).toBe(false) - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - describe "when followed by i w", -> - it "undo's and redo's completely", -> - editor.setCursorScreenPosition([1, 1]) - - keydown('c') - keydown('i') - keydown('w') - expect(editor.getText()).toBe "12345\n\nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - # Just cannot get "typing" to work correctly in test. - editor.setText("12345\nfg\nABCDE") - keydown('escape') - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editor.getText()).toBe "12345\nfg\nABCDE" - - keydown('u') - expect(editor.getText()).toBe "12345\nabcde\nABCDE" - keydown('r', ctrl: true) - expect(editor.getText()).toBe "12345\nfg\nABCDE" - - describe "when followed by a w", -> - it "changes the word", -> - editor.setText("word1 word2 word3") - editor.setCursorBufferPosition([0, "word1 w".length]) - - keydown("c") - keydown("w") - keydown("escape") - - expect(editor.getText()).toBe "word1 w word3" - - describe "when followed by a G", -> - beforeEach -> - originalText = "12345\nabcde\nABCDE" - editor.setText(originalText) - - describe "on the beginning of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 0]) - keydown('c') - keydown('G', shift: true) - keydown('escape') - expect(editor.getText()).toBe("12345\n\n") - - describe "on the middle of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('c') - keydown('G', shift: true) - keydown('escape') - expect(editor.getText()).toBe("12345\n\n") - - describe "when followed by a %", -> - beforeEach -> - editor.setText("12345(67)8\nabc(d)e\nA()BCDE") - - describe "before brackets or on the first one", -> - beforeEach -> - editor.setCursorScreenPosition([0, 1]) - editor.addCursorAtScreenPosition([1, 1]) - editor.addCursorAtScreenPosition([2, 1]) - keydown('c') - keydown('%') - editor.insertText('x') - - it "replaces inclusively until matching bracket", -> - expect(editor.getText()).toBe("1x8\naxe\nAxBCDE") - expect(vimState.mode).toBe "insert" - - it "undoes correctly with u", -> - keydown('escape') - expect(vimState.mode).toBe "normal" - keydown 'u' - expect(editor.getText()).toBe("12345(67)8\nabc(d)e\nA()BCDE") - - describe "inside brackets or on the ending one", -> - it "replaces inclusively backwards until matching bracket", -> - editor.setCursorScreenPosition([0, 6]) - editor.addCursorAtScreenPosition([1, 5]) - editor.addCursorAtScreenPosition([2, 2]) - keydown('c') - keydown('%') - editor.insertText('x') - expect(editor.getText()).toBe("12345x7)8\nabcxe\nAxBCDE") - expect(vimState.mode).toBe "insert" - - describe "after or without brackets", -> - it "deletes nothing", -> - editor.setText("12345(67)8\nabc(d)e\nABCDE") - editor.setCursorScreenPosition([0, 9]) - editor.addCursorAtScreenPosition([2, 2]) - keydown('c') - keydown('%') - expect(editor.getText()).toBe("12345(67)8\nabc(d)e\nABCDE") - expect(vimState.mode).toBe "normal" - - describe "repetition with .", -> - beforeEach -> - editor.setCursorScreenPosition([0, 1]) - keydown('c') - keydown('%') - editor.insertText('x') - keydown('escape') - - it "repeats correctly before a bracket", -> - editor.setCursorScreenPosition([1, 0]) - keydown('.') - expect(editor.getText()).toBe("1x8\nxe\nA()BCDE") - expect(vimState.mode).toBe "normal" - - it "repeats correctly on the opening bracket", -> - editor.setCursorScreenPosition([1, 3]) - keydown('.') - expect(editor.getText()).toBe("1x8\nabcxe\nA()BCDE") - expect(vimState.mode).toBe "normal" - - it "repeats correctly inside brackets", -> - editor.setCursorScreenPosition([1, 4]) - keydown('.') - expect(editor.getText()).toBe("1x8\nabcx)e\nA()BCDE") - expect(vimState.mode).toBe "normal" - - it "repeats correctly on the closing bracket", -> - editor.setCursorScreenPosition([1, 5]) - keydown('.') - expect(editor.getText()).toBe("1x8\nabcxe\nA()BCDE") - expect(vimState.mode).toBe "normal" - - it "does nothing when repeated after a bracket", -> - editor.setCursorScreenPosition([2, 3]) - keydown('.') - expect(editor.getText()).toBe("1x8\nabc(d)e\nA()BCDE") - expect(vimState.mode).toBe "normal" - - describe "when followed by a goto line G", -> - beforeEach -> - editor.setText "12345\nabcde\nABCDE" - - describe "on the beginning of the second line", -> - it "deletes all the text on the line", -> - editor.setCursorScreenPosition([1, 0]) - keydown('c') - keydown('2') - keydown('G', shift: true) - keydown('escape') - expect(editor.getText()).toBe("12345\n\nABCDE") - - describe "on the middle of the second line", -> - it "deletes all the text on the line", -> - editor.setCursorScreenPosition([1, 2]) - keydown('c') - keydown('2') - keydown('G', shift: true) - keydown('escape') - expect(editor.getText()).toBe("12345\n\nABCDE") - - describe "in visual mode", -> - beforeEach -> - editor.setText "123456789\nabcde\nfghijklmnopq\nuvwxyz" - editor.setCursorScreenPosition [1, 1] - - describe "with characterwise selection on a single line", -> - it "repeats with .", -> - keydown 'v' - keydown '2' - keydown 'l' - keydown 'c' - editor.insertText "ab" - keydown 'escape' - expect(editor.getText()).toBe "123456789\naabe\nfghijklmnopq\nuvwxyz" - - editor.setCursorScreenPosition [0, 1] - keydown '.' - expect(editor.getText()).toBe "1ab56789\naabe\nfghijklmnopq\nuvwxyz" - - it "repeats shortened with . near the end of the line", -> - editor.setCursorScreenPosition [0, 2] - keydown 'v' - keydown '4' - keydown 'l' - keydown 'c' - editor.insertText "ab" - keydown 'escape' - expect(editor.getText()).toBe "12ab89\nabcde\nfghijklmnopq\nuvwxyz" - - editor.setCursorScreenPosition [1, 3] - keydown '.' - expect(editor.getText()).toBe "12ab89\nabcab\nfghijklmnopq\nuvwxyz" - - it "repeats shortened with . near the end of the line regardless of whether motion wrapping is enabled", -> - atom.config.set('vim-mode.wrapLeftRightMotion', true) - editor.setCursorScreenPosition [0, 2] - keydown 'v' - keydown '4' - keydown 'l' - keydown 'c' - editor.insertText "ab" - keydown 'escape' - expect(editor.getText()).toBe "12ab89\nabcde\nfghijklmnopq\nuvwxyz" - - editor.setCursorScreenPosition [1, 3] - keydown '.' - # this differs from VIM, which would eat the \n before fghij... - expect(editor.getText()).toBe "12ab89\nabcab\nfghijklmnopq\nuvwxyz" - - describe "is repeatable with characterwise selection over multiple lines", -> - it "repeats with .", -> - keydown 'v' - keydown 'j' - keydown '3' - keydown 'l' - keydown 'c' - editor.insertText "x" - keydown 'escape' - expect(editor.getText()).toBe "123456789\naxklmnopq\nuvwxyz" - - editor.setCursorScreenPosition [0, 1] - keydown '.' - expect(editor.getText()).toBe "1xnopq\nuvwxyz" - - it "repeats shortened with . near the end of the line", -> - # this behaviour is unlike VIM, see #737 - keydown 'v' - keydown 'j' - keydown '6' - keydown 'l' - keydown 'c' - editor.insertText "x" - keydown 'escape' - expect(editor.getText()).toBe "123456789\naxnopq\nuvwxyz" - - editor.setCursorScreenPosition [0, 1] - keydown '.' - expect(editor.getText()).toBe "1x\nuvwxyz" - - describe "is repeatable with linewise selection", -> - describe "with one line selected", -> - it "repeats with .", -> - keydown 'V', shift: true - keydown 'c' - editor.insertText "x" - keydown 'escape' - expect(editor.getText()).toBe "123456789\nx\nfghijklmnopq\nuvwxyz" - - editor.setCursorScreenPosition [0, 7] - keydown '.' - expect(editor.getText()).toBe "x\nx\nfghijklmnopq\nuvwxyz" - - editor.setCursorScreenPosition [2, 0] - keydown '.' - expect(editor.getText()).toBe "x\nx\nx\nuvwxyz" - - describe "with multiple lines selected", -> - it "repeats with .", -> - keydown 'V', shift: true - keydown 'j' - keydown 'c' - editor.insertText "x" - keydown 'escape' - expect(editor.getText()).toBe "123456789\nx\nuvwxyz" - - editor.setCursorScreenPosition [0, 7] - keydown '.' - expect(editor.getText()).toBe "x\nuvwxyz" - - it "repeats shortened with . near the end of the file", -> - keydown 'V', shift: true - keydown 'j' - keydown 'c' - editor.insertText "x" - keydown 'escape' - expect(editor.getText()).toBe "123456789\nx\nuvwxyz" - - editor.setCursorScreenPosition [1, 7] - keydown '.' - expect(editor.getText()).toBe "123456789\nx\n" - - xdescribe "is repeatable with block selection", -> - # there is no block selection yet - - describe "the C keybinding", -> - beforeEach -> - editor.getBuffer().setText("012\n") - editor.setCursorScreenPosition([0, 1]) - keydown('C', shift: true) - - it "deletes the contents until the end of the line and enters insert mode", -> - expect(editor.getText()).toBe "0\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('normal-mode')).toBe(false) - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - describe "the y keybinding", -> - beforeEach -> - editor.getBuffer().setText("012 345\nabc\ndefg\n") - editor.setCursorScreenPosition([0, 4]) - vimState.setRegister('"', text: '345') - - describe "when selected lines in visual linewise mode", -> - beforeEach -> - keydown('V', shift: true) - keydown('j') - keydown('y') - - it "is in linewise motion", -> - expect(vimState.getRegister('"').type).toEqual "linewise" - - it "saves the lines to the default register", -> - expect(vimState.getRegister('"').text).toBe "012 345\nabc\n" - - it "places the cursor at the beginning of the selection", -> - expect(editor.getCursorBufferPositions()).toEqual([[0, 0]]) - - describe "when followed by a second y ", -> - beforeEach -> - keydown('y') - keydown('y') - - it "saves the line to the default register", -> - expect(vimState.getRegister('"').text).toBe "012 345\n" - - it "leaves the cursor at the starting position", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - describe "when useClipboardAsDefaultRegister enabled", -> - it "writes to clipboard", -> - atom.config.set 'vim-mode.useClipboardAsDefaultRegister', true - keydown('y') - keydown('y') - expect(atom.clipboard.read()).toBe '012 345\n' - - describe "when followed with a repeated y", -> - beforeEach -> - keydown('y') - keydown('2') - keydown('y') - - it "copies n lines, starting from the current", -> - expect(vimState.getRegister('"').text).toBe "012 345\nabc\n" - - it "leaves the cursor at the starting position", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - describe "with a register", -> - beforeEach -> - keydown('"') - keydown('a') - keydown('y') - keydown('y') - - it "saves the line to the a register", -> - expect(vimState.getRegister('a').text).toBe "012 345\n" - - it "appends the line to the A register", -> - keydown('"') - keydown('A', shift: true) - keydown('y') - keydown('y') - expect(vimState.getRegister('a').text).toBe "012 345\n012 345\n" - - describe "with a forward motion", -> - beforeEach -> - keydown('y') - keydown('e') - - it "saves the selected text to the default register", -> - expect(vimState.getRegister('"').text).toBe '345' - - it "leaves the cursor at the starting position", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - it "does not yank when motion fails", -> - keydown('y') - keydown('t') - normalModeInputKeydown('x') - expect(vimState.getRegister('"').text).toBe '345' - - describe "with a text object", -> - it "moves the cursor to the beginning of the text object", -> - editor.setCursorBufferPosition([0, 5]) - keydown("y") - keydown("i") - keydown("w") - expect(editor.getCursorBufferPositions()).toEqual([[0, 4]]) - - describe "with a left motion", -> - beforeEach -> - keydown('y') - keydown('h') - - it "saves the left letter to the default register", -> - expect(vimState.getRegister('"').text).toBe " " - - it "moves the cursor position to the left", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - - describe "with a down motion", -> - beforeEach -> - keydown 'y' - keydown 'j' - - it "saves both full lines to the default register", -> - expect(vimState.getRegister('"').text).toBe "012 345\nabc\n" - - it "leaves the cursor at the starting position", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - describe "with an up motion", -> - beforeEach -> - editor.setCursorScreenPosition([2, 2]) - keydown 'y' - keydown 'k' - - it "saves both full lines to the default register", -> - expect(vimState.getRegister('"').text).toBe "abc\ndefg\n" - - it "puts the cursor on the first line and the original column", -> - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - - describe "when followed by a G", -> - beforeEach -> - originalText = "12345\nabcde\nABCDE" - editor.setText(originalText) - - describe "on the beginning of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 0]) - keydown('y') - keydown('G', shift: true) - keydown('P', shift: true) - expect(editor.getText()).toBe("12345\nabcde\nABCDE\nabcde\nABCDE") - - describe "on the middle of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('y') - keydown('G', shift: true) - keydown('P', shift: true) - expect(editor.getText()).toBe("12345\nabcde\nABCDE\nabcde\nABCDE") - - describe "when followed by a goto line G", -> - beforeEach -> - originalText = "12345\nabcde\nABCDE" - editor.setText(originalText) - - describe "on the beginning of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 0]) - keydown('y') - keydown('2') - keydown('G', shift: true) - keydown('P', shift: true) - expect(editor.getText()).toBe("12345\nabcde\nabcde\nABCDE") - - describe "on the middle of the second line", -> - it "deletes the bottom two lines", -> - editor.setCursorScreenPosition([1, 2]) - keydown('y') - keydown('2') - keydown('G', shift: true) - keydown('P', shift: true) - expect(editor.getText()).toBe("12345\nabcde\nabcde\nABCDE") - - describe "with multiple cursors", -> - it "moves each cursor and copies the last selection's text", -> - editor.setText " abcd\n 1234" - editor.setCursorBufferPosition([0, 0]) - editor.addCursorAtBufferPosition([1, 5]) - - keydown("y") - keydown("^") - - expect(vimState.getRegister('"').text).toBe '123' - expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 2]] - - describe "in a long file", -> - beforeEach -> - editor.setHeight(400) - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - text = "" - for i in [1..200] - text += "#{i}\n" - editor.setText(text) - - describe "yanking many lines forward", -> - it "does not scroll the window", -> - editor.setCursorBufferPosition [40, 1] - previousScrollTop = editor.getScrollTop() - - # yank many lines - keydown('y') - keydown('1') - keydown('6') - keydown('0') - keydown('G', shift: true) - - expect(editor.getScrollTop()).toEqual(previousScrollTop) - expect(editor.getCursorBufferPosition()).toEqual [40, 1] - expect(vimState.getRegister('"').text.split('\n').length).toBe 121 - - describe "yanking many lines backwards", -> - it "scrolls the window", -> - editor.setCursorBufferPosition [140, 1] - previousScrollTop = editor.getScrollTop() - - # yank many lines - keydown('y') - keydown('6') - keydown('0') - keydown('G', shift: true) - - expect(editor.getScrollTop()).toNotEqual previousScrollTop - expect(editor.getCursorBufferPosition()).toEqual [59, 1] - expect(vimState.getRegister('"').text.split('\n').length).toBe 83 - - describe "the yy keybinding", -> - describe "on a single line file", -> - beforeEach -> - editor.getBuffer().setText "exclamation!\n" - editor.setCursorScreenPosition [0, 0] - - it "copies the entire line and pastes it correctly", -> - keydown('y') - keydown('y') - keydown('p') - - expect(vimState.getRegister('"').text).toBe "exclamation!\n" - expect(editor.getText()).toBe "exclamation!\nexclamation!\n" - - describe "on a single line file with no newline", -> - beforeEach -> - editor.getBuffer().setText "no newline!" - editor.setCursorScreenPosition [0, 0] - - it "copies the entire line and pastes it correctly", -> - keydown('y') - keydown('y') - keydown('p') - - expect(vimState.getRegister('"').text).toBe "no newline!\n" - expect(editor.getText()).toBe "no newline!\nno newline!" - - it "copies the entire line and pastes it respecting count and new lines", -> - keydown('y') - keydown('y') - keydown('2') - keydown('p') - - expect(vimState.getRegister('"').text).toBe "no newline!\n" - expect(editor.getText()).toBe "no newline!\nno newline!\nno newline!" - - describe "the Y keybinding", -> - beforeEach -> - editor.getBuffer().setText "012 345\nabc\n" - editor.setCursorScreenPosition [0, 4] - - it "saves the line to the default register", -> - keydown('Y', shift: true) - - expect(vimState.getRegister('"').text).toBe "012 345\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - describe "the p keybinding", -> - describe "with character contents", -> - beforeEach -> - editor.getBuffer().setText "012\n" - editor.setCursorScreenPosition [0, 0] - vimState.setRegister('"', text: '345') - vimState.setRegister('a', text: 'a') - atom.clipboard.write "clip" - - describe "from the default register", -> - beforeEach -> keydown('p') - - it "inserts the contents", -> - expect(editor.getText()).toBe "034512\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - - describe "at the end of a line", -> - beforeEach -> - editor.setCursorScreenPosition [0, 2] - keydown('p') - - it "positions cursor correctly", -> - expect(editor.getText()).toBe "012345\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - describe "when useClipboardAsDefaultRegister enabled", -> - it "inserts contents from clipboard", -> - atom.config.set 'vim-mode.useClipboardAsDefaultRegister', true - keydown('p') - expect(editor.getText()).toBe "0clip12\n" - - describe "from a specified register", -> - beforeEach -> - keydown('"') - keydown('a') - keydown('p') - - it "inserts the contents of the 'a' register", -> - expect(editor.getText()).toBe "0a12\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - - describe "at the end of a line", -> - it "inserts before the current line's newline", -> - editor.setText("abcde\none two three") - editor.setCursorScreenPosition([1, 4]) - - keydown 'd' - keydown '$' - keydown 'k' - keydown '$' - keydown 'p' - - expect(editor.getText()).toBe "abcdetwo three\none " - - describe "with a selection", -> - beforeEach -> - editor.selectRight() - keydown('p') - - it "replaces the current selection", -> - expect(editor.getText()).toBe "34512\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "with linewise contents", -> - describe "on a single line", -> - beforeEach -> - editor.getBuffer().setText("012") - editor.setCursorScreenPosition([0, 1]) - vimState.setRegister('"', text: " 345\n", type: 'linewise') - - it "inserts the contents of the default register", -> - keydown('p') - - expect(editor.getText()).toBe "012\n 345" - expect(editor.getCursorScreenPosition()).toEqual [1, 1] - - it "replaces the current selection", -> - editor.selectRight() - keydown('p') - - expect(editor.getText()).toBe "0 345\n2" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - describe "on multiple lines", -> - beforeEach -> - editor.getBuffer().setText("012\n 345") - vimState.setRegister('"', text: " 456\n", type: 'linewise') - - it "inserts the contents of the default register at middle line", -> - editor.setCursorScreenPosition([0, 1]) - keydown('p') - - expect(editor.getText()).toBe "012\n 456\n 345" - expect(editor.getCursorScreenPosition()).toEqual [1, 1] - - it "inserts the contents of the default register at end of line", -> - editor.setCursorScreenPosition([1, 1]) - keydown('p') - - expect(editor.getText()).toBe "012\n 345\n 456" - expect(editor.getCursorScreenPosition()).toEqual [2, 1] - - describe "with multiple linewise contents", -> - beforeEach -> - editor.getBuffer().setText("012\nabc") - editor.setCursorScreenPosition([1, 0]) - vimState.setRegister('"', text: " 345\n 678\n", type: 'linewise') - keydown('p') - - it "inserts the contents of the default register", -> - expect(editor.getText()).toBe "012\nabc\n 345\n 678" - expect(editor.getCursorScreenPosition()).toEqual [2, 1] - - describe "pasting twice", -> - beforeEach -> - editor.setText("12345\nabcde\nABCDE\nQWERT") - editor.setCursorScreenPosition([1, 1]) - vimState.setRegister('"', text: '123') - keydown('2') - keydown('p') - - it "inserts the same line twice", -> - expect(editor.getText()).toBe "12345\nab123123cde\nABCDE\nQWERT" - - describe "when undone", -> - beforeEach -> - keydown('u') - - it "removes both lines", -> - expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT" - - describe "the P keybinding", -> - describe "with character contents", -> - beforeEach -> - editor.getBuffer().setText("012\n") - editor.setCursorScreenPosition([0, 0]) - vimState.setRegister('"', text: '345') - vimState.setRegister('a', text: 'a') - keydown('P', shift: true) - - it "inserts the contents of the default register above", -> - expect(editor.getText()).toBe "345012\n" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "the O keybinding", -> - beforeEach -> - spyOn(editor, 'shouldAutoIndent').andReturn(true) - spyOn(editor, 'autoIndentBufferRow').andCallFake (line) -> - editor.indent() - - editor.getBuffer().setText(" abc\n 012\n") - editor.setCursorScreenPosition([1, 1]) - - it "switches to insert and adds a newline above the current one", -> - keydown('O', shift: true) - expect(editor.getText()).toBe " abc\n \n 012\n" - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - it "is repeatable", -> - editor.getBuffer().setText(" abc\n 012\n 4spaces\n") - editor.setCursorScreenPosition([1, 1]) - keydown('O', shift: true) - editor.insertText "def" - keydown 'escape' - expect(editor.getText()).toBe " abc\n def\n 012\n 4spaces\n" - editor.setCursorScreenPosition([1, 1]) - keydown '.' - expect(editor.getText()).toBe " abc\n def\n def\n 012\n 4spaces\n" - editor.setCursorScreenPosition([4, 1]) - keydown '.' - expect(editor.getText()).toBe " abc\n def\n def\n 012\n def\n 4spaces\n" - - it "is undoable", -> - keydown('O', shift: true) - editor.insertText "def" - keydown 'escape' - expect(editor.getText()).toBe " abc\n def\n 012\n" - keydown 'u' - expect(editor.getText()).toBe " abc\n 012\n" - - describe "the o keybinding", -> - beforeEach -> - spyOn(editor, 'shouldAutoIndent').andReturn(true) - spyOn(editor, 'autoIndentBufferRow').andCallFake (line) -> - editor.indent() - - editor.getBuffer().setText("abc\n 012\n") - editor.setCursorScreenPosition([1, 2]) - - it "switches to insert and adds a newline above the current one", -> - keydown('o') - expect(editor.getText()).toBe "abc\n 012\n \n" - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getCursorScreenPosition()).toEqual [2, 2] - - # This works in practice, but the editor doesn't respect the indentation - # rules without a syntax grammar. Need to set the editor's grammar - # to fix it. - xit "is repeatable", -> - editor.getBuffer().setText(" abc\n 012\n 4spaces\n") - editor.setCursorScreenPosition([1, 1]) - keydown('o') - editor.insertText "def" - keydown 'escape' - expect(editor.getText()).toBe " abc\n 012\n def\n 4spaces\n" - keydown '.' - expect(editor.getText()).toBe " abc\n 012\n def\n def\n 4spaces\n" - editor.setCursorScreenPosition([4, 1]) - keydown '.' - expect(editor.getText()).toBe " abc\n def\n def\n 012\n 4spaces\n def\n" - - it "is undoable", -> - keydown('o') - editor.insertText "def" - keydown 'escape' - expect(editor.getText()).toBe "abc\n 012\n def\n" - keydown 'u' - expect(editor.getText()).toBe "abc\n 012\n" - - describe "the a keybinding", -> - beforeEach -> - editor.getBuffer().setText("012\n") - - describe "at the beginning of the line", -> - beforeEach -> - editor.setCursorScreenPosition([0, 0]) - keydown('a') - - it "switches to insert mode and shifts to the right", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - describe "at the end of the line", -> - beforeEach -> - editor.setCursorScreenPosition([0, 3]) - keydown('a') - - it "doesn't linewrap", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - - describe "the A keybinding", -> - beforeEach -> - editor.getBuffer().setText("11\n22\n") - - describe "at the beginning of a line", -> - it "switches to insert mode at the end of the line", -> - editor.setCursorScreenPosition([0, 0]) - keydown('A', shift: true) - - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - it "repeats always as insert at the end of the line", -> - editor.setCursorScreenPosition([0, 0]) - keydown('A', shift: true) - editor.insertText("abc") - keydown 'escape' - editor.setCursorScreenPosition([1, 0]) - keydown '.' - - expect(editor.getText()).toBe "11abc\n22abc\n" - expect(editorElement.classList.contains('insert-mode')).toBe(false) - expect(editor.getCursorScreenPosition()).toEqual [1, 4] - - describe "the I keybinding", -> - beforeEach -> - editor.getBuffer().setText("11\n 22\n") - - describe "at the end of a line", -> - it "switches to insert mode at the beginning of the line", -> - editor.setCursorScreenPosition([0, 2]) - keydown('I', shift: true) - - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - - it "switches to insert mode after leading whitespace", -> - editor.setCursorScreenPosition([1, 4]) - keydown('I', shift: true) - - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - - it "repeats always as insert at the first character of the line", -> - editor.setCursorScreenPosition([0, 2]) - keydown('I', shift: true) - editor.insertText("abc") - keydown 'escape' - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - editor.setCursorScreenPosition([1, 4]) - keydown '.' - - expect(editor.getText()).toBe "abc11\n abc22\n" - expect(editorElement.classList.contains('insert-mode')).toBe(false) - expect(editor.getCursorScreenPosition()).toEqual [1, 4] - - describe "the J keybinding", -> - beforeEach -> - editor.getBuffer().setText("012\n 456\n") - editor.setCursorScreenPosition([0, 1]) - - describe "without repeating", -> - beforeEach -> keydown('J', shift: true) - - it "joins the contents of the current line with the one below it", -> - expect(editor.getText()).toBe "012 456\n" - - describe "with repeating", -> - beforeEach -> - editor.setText("12345\nabcde\nABCDE\nQWERT") - editor.setCursorScreenPosition([1, 1]) - keydown('2') - keydown('J', shift: true) - - describe "undo behavior", -> - beforeEach -> keydown('u') - - it "handles repeats", -> - expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT" - - describe "the > keybinding", -> - beforeEach -> - editor.setText("12345\nabcde\nABCDE") - - describe "on the last line", -> - beforeEach -> - editor.setCursorScreenPosition([2, 0]) - - describe "when followed by a >", -> - beforeEach -> - keydown('>') - keydown('>') - - it "indents the current line", -> - expect(editor.getText()).toBe "12345\nabcde\n ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [2, 2] - - describe "on the first line", -> - beforeEach -> - editor.setCursorScreenPosition([0, 0]) - - describe "when followed by a >", -> - beforeEach -> - keydown('>') - keydown('>') - - it "indents the current line", -> - expect(editor.getText()).toBe " 12345\nabcde\nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "when followed by a repeating >", -> - beforeEach -> - keydown('3') - keydown('>') - keydown('>') - - it "indents multiple lines at once", -> - expect(editor.getText()).toBe " 12345\n abcde\n ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "undo behavior", -> - beforeEach -> keydown('u') - - it "outdents all three lines", -> - expect(editor.getText()).toBe "12345\nabcde\nABCDE" - - describe "in visual mode linewise", -> - beforeEach -> - editor.setCursorScreenPosition([0, 0]) - keydown('v', shift: true) - keydown('j') - - describe "single indent multiple lines", -> - beforeEach -> - keydown('>') - - it "indents both lines once and exits visual mode", -> - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - expect(editor.getSelectedBufferRanges()).toEqual [ [[0, 2], [0, 2]] ] - - it "allows repeating the operation", -> - keydown('.') - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - - describe "multiple indent multiple lines", -> - beforeEach -> - keydown('2') - keydown('>') - - it "indents both lines twice and exits visual mode", -> - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - expect(editor.getSelectedBufferRanges()).toEqual [ [[0, 4], [0, 4]] ] - - describe "with multiple selections", -> - beforeEach -> - editor.setCursorScreenPosition([1, 3]) - keydown('v') - keydown('j') - editor.addCursorAtScreenPosition([0, 0]) - - it "indents the lines and keeps the cursors", -> - keydown('>') - expect(editor.getText()).toBe " 12345\n abcde\n ABCDE" - expect(editor.getCursorScreenPositions()).toEqual [[1, 2], [0, 2]] - - describe "the < keybinding", -> - beforeEach -> - editor.setText(" 12345\n abcde\nABCDE") - editor.setCursorScreenPosition([0, 0]) - - describe "when followed by a <", -> - beforeEach -> - keydown('<') - keydown('<') - - it "outdents the current line", -> - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "when followed by a repeating <", -> - beforeEach -> - keydown('2') - keydown('<') - keydown('<') - - it "outdents multiple lines at once", -> - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "undo behavior", -> - beforeEach -> keydown('u') - - it "indents both lines", -> - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - - describe "in visual mode linewise", -> - beforeEach -> - keydown('v', shift: true) - keydown('j') - - describe "single outdent multiple lines", -> - beforeEach -> - keydown('<') - - it "outdents the current line and exits visual mode", -> - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editor.getText()).toBe " 12345\n abcde\nABCDE" - expect(editor.getSelectedBufferRanges()).toEqual [ [[0, 2], [0, 2]] ] - - it "allows repeating the operation", -> - keydown('.') - expect(editor.getText()).toBe "12345\nabcde\nABCDE" - - describe "multiple outdent multiple lines", -> - beforeEach -> - keydown('2') - keydown('<') - - it "outdents both lines twice and exits visual mode", -> - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editor.getText()).toBe "12345\nabcde\nABCDE" - expect(editor.getSelectedBufferRanges()).toEqual [ [[0, 0], [0, 0]] ] - - describe "the = keybinding", -> - oldGrammar = [] - - beforeEach -> - waitsForPromise -> - atom.packages.activatePackage('language-javascript') - - oldGrammar = editor.getGrammar() - editor.setText("foo\n bar\n baz") - editor.setCursorScreenPosition([1, 0]) - - describe "when used in a scope that supports auto-indent", -> - beforeEach -> - jsGrammar = atom.grammars.grammarForScopeName('source.js') - editor.setGrammar(jsGrammar) - - afterEach -> - editor.setGrammar(oldGrammar) - - describe "when followed by a =", -> - beforeEach -> - keydown('=') - keydown('=') - - it "indents the current line", -> - expect(editor.indentationForBufferRow(1)).toBe 0 - - describe "when followed by a G", -> - beforeEach -> - editor.setCursorScreenPosition([0, 0]) - keydown('=') - keydown('G', shift: true) - - it "uses the default count", -> - expect(editor.indentationForBufferRow(1)).toBe 0 - expect(editor.indentationForBufferRow(2)).toBe 0 - - describe "when followed by a repeating =", -> - beforeEach -> - keydown('2') - keydown('=') - keydown('=') - - it "autoindents multiple lines at once", -> - expect(editor.getText()).toBe "foo\nbar\nbaz" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - describe "undo behavior", -> - beforeEach -> keydown('u') - - it "indents both lines", -> - expect(editor.getText()).toBe "foo\n bar\n baz" - - describe "the . keybinding", -> - beforeEach -> - editor.setText("12\n34\n56\n78") - editor.setCursorScreenPosition([0, 0]) - - it "repeats the last operation", -> - keydown '2' - keydown 'd' - keydown 'd' - keydown '.' - - expect(editor.getText()).toBe "" - - it "composes with motions", -> - keydown 'd' - keydown 'd' - keydown '2' - keydown '.' - - expect(editor.getText()).toBe "78" - - describe "the r keybinding", -> - beforeEach -> - editor.setText("12\n34\n\n") - editor.setCursorBufferPosition([0, 0]) - editor.addCursorAtBufferPosition([1, 0]) - - it "replaces a single character", -> - keydown('r') - normalModeInputKeydown('x') - expect(editor.getText()).toBe 'x2\nx4\n\n' - - it "does nothing when cancelled", -> - keydown('r') - expect(editorElement.classList.contains('operator-pending-mode')).toBe(true) - keydown('escape') - expect(editor.getText()).toBe '12\n34\n\n' - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "replaces a single character with a line break", -> - keydown('r') - atom.commands.dispatch(editor.normalModeInputView.editorElement, 'core:confirm') - expect(editor.getText()).toBe '\n2\n\n4\n\n' - expect(editor.getCursorBufferPositions()).toEqual [[1, 0], [3, 0]] - - it "composes properly with motions", -> - keydown('2') - keydown('r') - normalModeInputKeydown('x') - expect(editor.getText()).toBe 'xx\nxx\n\n' - - it "does nothing on an empty line", -> - editor.setCursorBufferPosition([2, 0]) - keydown('r') - normalModeInputKeydown('x') - expect(editor.getText()).toBe '12\n34\n\n' - - it "does nothing if asked to replace more characters than there are on a line", -> - keydown('3') - keydown('r') - normalModeInputKeydown('x') - expect(editor.getText()).toBe '12\n34\n\n' - - describe "when in visual mode", -> - beforeEach -> - keydown('v') - keydown('e') - - it "replaces the entire selection with the given character", -> - keydown('r') - normalModeInputKeydown('x') - expect(editor.getText()).toBe 'xx\nxx\n\n' - - it "leaves the cursor at the beginning of the selection", -> - keydown('r') - normalModeInputKeydown('x') - expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 0]] - - describe 'with accented characters', -> - buildIMECompositionEvent = (event, {data, target}={}) -> - event = new Event(event) - event.data = data - Object.defineProperty(event, 'target', get: -> target) - event - - buildTextInputEvent = ({data, target}) -> - event = new Event('textInput') - event.data = data - Object.defineProperty(event, 'target', get: -> target) - event - - it 'works with IME composition', -> - keydown('r') - normalModeEditor = editor.normalModeInputView.editorElement - jasmine.attachToDOM(normalModeEditor) - domNode = normalModeEditor.component.domNode - inputNode = domNode.querySelector('.hidden-input') - domNode.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode)) - domNode.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's', target: inputNode)) - expect(normalModeEditor.getModel().getText()).toEqual 's' - domNode.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd', target: inputNode)) - expect(normalModeEditor.getModel().getText()).toEqual 'sd' - domNode.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode)) - domNode.dispatchEvent(buildTextInputEvent(data: '速度', target: inputNode)) - expect(editor.getText()).toBe '速度2\n速度4\n\n' - - describe 'the m keybinding', -> - beforeEach -> - editor.setText('12\n34\n56\n') - editor.setCursorBufferPosition([0, 1]) - - it 'marks a position', -> - keydown('m') - normalModeInputKeydown('a') - expect(vimState.getMark('a')).toEqual [0, 1] - - describe 'the ~ keybinding', -> - beforeEach -> - editor.setText('aBc\nXyZ') - editor.setCursorBufferPosition([0, 0]) - editor.addCursorAtBufferPosition([1, 0]) - - it 'toggles the case and moves right', -> - keydown('~') - expect(editor.getText()).toBe 'ABc\nxyZ' - expect(editor.getCursorScreenPositions()).toEqual [[0, 1], [1, 1]] - - keydown('~') - expect(editor.getText()).toBe 'Abc\nxYZ' - expect(editor.getCursorScreenPositions()).toEqual [[0, 2], [1, 2]] - - keydown('~') - expect(editor.getText()).toBe 'AbC\nxYz' - expect(editor.getCursorScreenPositions()).toEqual [[0, 2], [1, 2]] - - it 'takes a count', -> - keydown('4') - keydown('~') - - expect(editor.getText()).toBe 'AbC\nxYz' - expect(editor.getCursorScreenPositions()).toEqual [[0, 2], [1, 2]] - - describe "in visual mode", -> - it "toggles the case of the selected text", -> - editor.setCursorBufferPosition([0, 0]) - keydown("V", shift: true) - keydown("~") - expect(editor.getText()).toBe 'AbC\nXyZ' - - describe "with g and motion", -> - it "toggles the case of text", -> - editor.setCursorBufferPosition([0, 0]) - keydown("g") - keydown("~") - keydown("2") - keydown("l") - expect(editor.getText()).toBe 'Abc\nXyZ' - - it "uses default count", -> - editor.setCursorBufferPosition([0, 0]) - keydown("g") - keydown("~") - keydown("G", shift: true) - expect(editor.getText()).toBe 'AbC\nxYz' - - describe 'the U keybinding', -> - beforeEach -> - editor.setText('aBc\nXyZ') - editor.setCursorBufferPosition([0, 0]) - - it "makes text uppercase with g and motion", -> - keydown("g") - keydown("U", shift: true) - keydown("l") - expect(editor.getText()).toBe 'ABc\nXyZ' - - keydown("g") - keydown("U", shift: true) - keydown("e") - expect(editor.getText()).toBe 'ABC\nXyZ' - - editor.setCursorBufferPosition([1, 0]) - keydown("g") - keydown("U", shift: true) - keydown("$") - expect(editor.getText()).toBe 'ABC\nXYZ' - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - - it "uses default count", -> - editor.setCursorBufferPosition([0, 0]) - keydown("g") - keydown("U", shift: true) - keydown("G", shift: true) - expect(editor.getText()).toBe 'ABC\nXYZ' - - it "makes the selected text uppercase in visual mode", -> - keydown("V", shift: true) - keydown("U", shift: true) - expect(editor.getText()).toBe 'ABC\nXyZ' - - describe 'the u keybinding', -> - beforeEach -> - editor.setText('aBc\nXyZ') - editor.setCursorBufferPosition([0, 0]) - - it "makes text lowercase with g and motion", -> - keydown("g") - keydown("u") - keydown("$") - expect(editor.getText()).toBe 'abc\nXyZ' - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - it "uses default count", -> - editor.setCursorBufferPosition([0, 0]) - keydown("g") - keydown("u") - keydown("G", shift: true) - expect(editor.getText()).toBe 'abc\nxyz' - - it "makes the selected text lowercase in visual mode", -> - keydown("V", shift: true) - keydown("u") - expect(editor.getText()).toBe 'abc\nXyZ' - - describe "the i keybinding", -> - beforeEach -> - editor.setText('123\n4567') - editor.setCursorBufferPosition([0, 0]) - editor.addCursorAtBufferPosition([1, 0]) - - it "allows undoing an entire batch of typing", -> - keydown 'i' - editor.insertText("abcXX") - editor.backspace() - editor.backspace() - keydown 'escape' - expect(editor.getText()).toBe "abc123\nabc4567" - - keydown 'i' - editor.insertText "d" - editor.insertText "e" - editor.insertText "f" - keydown 'escape' - expect(editor.getText()).toBe "abdefc123\nabdefc4567" - - keydown 'u' - expect(editor.getText()).toBe "abc123\nabc4567" - - keydown 'u' - expect(editor.getText()).toBe "123\n4567" - - it "allows repeating typing", -> - keydown 'i' - editor.insertText("abcXX") - editor.backspace() - editor.backspace() - keydown 'escape' - expect(editor.getText()).toBe "abc123\nabc4567" - - keydown '.' - expect(editor.getText()).toBe "ababcc123\nababcc4567" - - keydown '.' - expect(editor.getText()).toBe "abababccc123\nabababccc4567" - - describe 'with nonlinear input', -> - beforeEach -> - editor.setText '' - editor.setCursorBufferPosition [0, 0] - - it 'deals with auto-matched brackets', -> - keydown 'i' - # this sequence simulates what the bracket-matcher package does - # when the user types (a)b<enter> - editor.insertText '()' - editor.moveLeft() - editor.insertText 'a' - editor.moveRight() - editor.insertText 'b\n' - keydown 'escape' - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - keydown '.' - expect(editor.getText()).toBe '(a)b\n(a)b\n' - expect(editor.getCursorScreenPosition()).toEqual [2, 0] - - it 'deals with autocomplete', -> - keydown 'i' - # this sequence simulates autocompletion of 'add' to 'addFoo' - editor.insertText 'a' - editor.insertText 'd' - editor.insertText 'd' - editor.setTextInBufferRange [[0, 0], [0, 3]], 'addFoo' - keydown 'escape' - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - expect(editor.getText()).toBe 'addFoo' - - keydown '.' - expect(editor.getText()).toBe 'addFoaddFooo' - expect(editor.getCursorScreenPosition()).toEqual [0, 10] - - describe 'the a keybinding', -> - beforeEach -> - editor.setText('') - editor.setCursorBufferPosition([0, 0]) - - it "can be undone in one go", -> - keydown 'a' - editor.insertText("abc") - keydown 'escape' - expect(editor.getText()).toBe "abc" - keydown 'u' - expect(editor.getText()).toBe "" - - it "repeats correctly", -> - keydown 'a' - editor.insertText("abc") - keydown 'escape' - expect(editor.getText()).toBe "abc" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - keydown '.' - expect(editor.getText()).toBe "abcabc" - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - describe "the ctrl-a/ctrl-x keybindings", -> - beforeEach -> - atom.config.set 'vim-mode.numberRegex', settings.config.numberRegex.default - editor.setText('123\nab45\ncd-67ef\nab-5\na-bcdef') - editor.setCursorBufferPosition [0, 0] - editor.addCursorAtBufferPosition [1, 0] - editor.addCursorAtBufferPosition [2, 0] - editor.addCursorAtBufferPosition [3, 3] - editor.addCursorAtBufferPosition [4, 0] - - describe "increasing numbers", -> - it "increases the next number", -> - keydown('a', ctrl: true) - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]] - expect(editor.getText()).toBe '124\nab46\ncd-66ef\nab-4\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "repeats with .", -> - keydown 'a', ctrl: true - keydown '.' - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]] - expect(editor.getText()).toBe '125\nab47\ncd-65ef\nab-3\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "can have a count", -> - keydown '5' - keydown 'a', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 2], [4, 0]] - expect(editor.getText()).toBe '128\nab50\ncd-62ef\nab0\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "can make a negative number positive, change number of digits", -> - keydown '9' - keydown '9' - keydown 'a', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 4], [2, 3], [3, 3], [4, 0]] - expect(editor.getText()).toBe '222\nab144\ncd32ef\nab94\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "does nothing when cursor is after the number", -> - editor.setCursorBufferPosition [2, 5] - keydown 'a', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[2, 5]] - expect(editor.getText()).toBe '123\nab45\ncd-67ef\nab-5\na-bcdef' - expect(atom.beep).toHaveBeenCalled() - - it "does nothing on an empty line", -> - editor.setText('\n') - editor.setCursorBufferPosition [0, 0] - editor.addCursorAtBufferPosition [1, 0] - keydown 'a', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 0]] - expect(editor.getText()).toBe '\n' - expect(atom.beep).toHaveBeenCalled() - - it "honours the vim-mode:numberRegex setting", -> - editor.setText('123\nab45\ncd -67ef\nab-5\na-bcdef') - editor.setCursorBufferPosition [0, 0] - editor.addCursorAtBufferPosition [1, 0] - editor.addCursorAtBufferPosition [2, 0] - editor.addCursorAtBufferPosition [3, 3] - editor.addCursorAtBufferPosition [4, 0] - atom.config.set('vim-mode.numberRegex', '(?:\\B-)?[0-9]+') - keydown('a', ctrl: true) - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 5], [3, 3], [4, 0]] - expect(editor.getText()).toBe '124\nab46\ncd -66ef\nab-6\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - describe "decreasing numbers", -> - it "decreases the next number", -> - keydown('x', ctrl: true) - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]] - expect(editor.getText()).toBe '122\nab44\ncd-68ef\nab-6\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "repeats with .", -> - keydown 'x', ctrl: true - keydown '.' - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]] - expect(editor.getText()).toBe '121\nab43\ncd-69ef\nab-7\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "can have a count", -> - keydown '5' - keydown 'x', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 4], [4, 0]] - expect(editor.getText()).toBe '118\nab40\ncd-72ef\nab-10\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "can make a positive number negative, change number of digits", -> - keydown '9' - keydown '9' - keydown 'x', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[0, 1], [1, 4], [2, 5], [3, 5], [4, 0]] - expect(editor.getText()).toBe '24\nab-54\ncd-166ef\nab-104\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - it "does nothing when cursor is after the number", -> - editor.setCursorBufferPosition [2, 5] - keydown 'x', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[2, 5]] - expect(editor.getText()).toBe '123\nab45\ncd-67ef\nab-5\na-bcdef' - expect(atom.beep).toHaveBeenCalled() - - it "does nothing on an empty line", -> - editor.setText('\n') - editor.setCursorBufferPosition [0, 0] - editor.addCursorAtBufferPosition [1, 0] - keydown 'x', ctrl: true - expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 0]] - expect(editor.getText()).toBe '\n' - expect(atom.beep).toHaveBeenCalled() - - it "honours the vim-mode:numberRegex setting", -> - editor.setText('123\nab45\ncd -67ef\nab-5\na-bcdef') - editor.setCursorBufferPosition [0, 0] - editor.addCursorAtBufferPosition [1, 0] - editor.addCursorAtBufferPosition [2, 0] - editor.addCursorAtBufferPosition [3, 3] - editor.addCursorAtBufferPosition [4, 0] - atom.config.set('vim-mode.numberRegex', '(?:\\B-)?[0-9]+') - keydown('x', ctrl: true) - expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 5], [3, 3], [4, 0]] - expect(editor.getText()).toBe '122\nab44\ncd -68ef\nab-4\na-bcdef' - expect(atom.beep).not.toHaveBeenCalled() - - describe 'the R keybinding', -> - beforeEach -> - editor.setText('12345\n67890') - editor.setCursorBufferPosition([0, 2]) - - it "enters replace mode and replaces characters", -> - keydown "R", shift: true - expect(editorElement.classList.contains('insert-mode')).toBe true - expect(editorElement.classList.contains('replace-mode')).toBe true - - editor.insertText "ab" - keydown 'escape' - - expect(editor.getText()).toBe "12ab5\n67890" - expect(editor.getCursorScreenPosition()).toEqual [0, 3] - expect(editorElement.classList.contains('insert-mode')).toBe false - expect(editorElement.classList.contains('replace-mode')).toBe false - expect(editorElement.classList.contains('normal-mode')).toBe true - - it "continues beyond end of line as insert", -> - keydown "R", shift: true - expect(editorElement.classList.contains('insert-mode')).toBe true - expect(editorElement.classList.contains('replace-mode')).toBe true - - editor.insertText "abcde" - keydown 'escape' - - expect(editor.getText()).toBe "12abcde\n67890" - - it "treats backspace as undo", -> - editor.insertText "foo" - keydown "R", shift: true - - editor.insertText "a" - editor.insertText "b" - expect(editor.getText()).toBe "12fooab5\n67890" - - keydown 'backspace', raw: true - expect(editor.getText()).toBe "12fooa45\n67890" - - editor.insertText "c" - - expect(editor.getText()).toBe "12fooac5\n67890" - - keydown 'backspace', raw: true - keydown 'backspace', raw: true - - expect(editor.getText()).toBe "12foo345\n67890" - expect(editor.getSelectedText()).toBe "" - - keydown 'backspace', raw: true - expect(editor.getText()).toBe "12foo345\n67890" - expect(editor.getSelectedText()).toBe "" - - it "can be repeated", -> - keydown "R", shift: true - editor.insertText "ab" - keydown 'escape' - editor.setCursorBufferPosition([1, 2]) - keydown '.' - expect(editor.getText()).toBe "12ab5\n67ab0" - expect(editor.getCursorScreenPosition()).toEqual [1, 3] - - editor.setCursorBufferPosition([0, 4]) - keydown '.' - expect(editor.getText()).toBe "12abab\n67ab0" - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - it "can be interrupted by arrow keys and behave as insert for repeat", -> - # FIXME don't know how to test this (also, depends on PR #568) - - it "repeats correctly when backspace was used in the text", -> - keydown "R", shift: true - editor.insertText "a" - keydown 'backspace', raw: true - editor.insertText "b" - keydown 'escape' - editor.setCursorBufferPosition([1, 2]) - keydown '.' - expect(editor.getText()).toBe "12b45\n67b90" - expect(editor.getCursorScreenPosition()).toEqual [1, 2] - - editor.setCursorBufferPosition([0, 4]) - keydown '.' - expect(editor.getText()).toBe "12b4b\n67b90" - expect(editor.getCursorScreenPosition()).toEqual [0, 4] - - it "doesn't replace a character if newline is entered", -> - keydown "R", shift: true - expect(editorElement.classList.contains('insert-mode')).toBe true - expect(editorElement.classList.contains('replace-mode')).toBe true - - editor.insertText "\n" - keydown 'escape' - - expect(editor.getText()).toBe "12\n345\n67890" diff --git a/atom/packages/vim-mode/spec/prefixes-spec.coffee b/atom/packages/vim-mode/spec/prefixes-spec.coffee deleted file mode 100644 index 71c4a12..0000000 --- a/atom/packages/vim-mode/spec/prefixes-spec.coffee +++ /dev/null @@ -1,182 +0,0 @@ -helpers = require './spec-helper' - -describe "Prefixes", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - describe "Repeat", -> - describe "with operations", -> - beforeEach -> - editor.setText("123456789abc") - editor.setCursorScreenPosition([0, 0]) - - it "repeats N times", -> - keydown('3') - keydown('x') - - expect(editor.getText()).toBe '456789abc' - - it "repeats NN times", -> - keydown('1') - keydown('0') - keydown('x') - - expect(editor.getText()).toBe 'bc' - - describe "with motions", -> - beforeEach -> - editor.setText('one two three') - editor.setCursorScreenPosition([0, 0]) - - it "repeats N times", -> - keydown('d') - keydown('2') - keydown('w') - - expect(editor.getText()).toBe 'three' - - describe "in visual mode", -> - beforeEach -> - editor.setText('one two three') - editor.setCursorScreenPosition([0, 0]) - - it "repeats movements in visual mode", -> - keydown("v") - keydown("2") - keydown("w") - - expect(editor.getCursorScreenPosition()).toEqual [0, 9] - - describe "Register", -> - describe "the a register", -> - it "saves a value for future reading", -> - vimState.setRegister('a', text: 'new content') - expect(vimState.getRegister("a").text).toEqual 'new content' - - it "overwrites a value previously in the register", -> - vimState.setRegister('a', text: 'content') - vimState.setRegister('a', text: 'new content') - expect(vimState.getRegister("a").text).toEqual 'new content' - - describe "the B register", -> - it "saves a value for future reading", -> - vimState.setRegister('B', text: 'new content') - expect(vimState.getRegister("b").text).toEqual 'new content' - expect(vimState.getRegister("B").text).toEqual 'new content' - - it "appends to a value previously in the register", -> - vimState.setRegister('b', text: 'content') - vimState.setRegister('B', text: 'new content') - expect(vimState.getRegister("b").text).toEqual 'contentnew content' - - it "appends linewise to a linewise value previously in the register", -> - vimState.setRegister('b', {type: 'linewise', text: 'content\n'}) - vimState.setRegister('B', text: 'new content') - expect(vimState.getRegister("b").text).toEqual 'content\nnew content\n' - - it "appends linewise to a character value previously in the register", -> - vimState.setRegister('b', text: 'content') - vimState.setRegister('B', {type: 'linewise', text: 'new content\n'}) - expect(vimState.getRegister("b").text).toEqual 'content\nnew content\n' - - - describe "the * register", -> - describe "reading", -> - it "is the same the system clipboard", -> - expect(vimState.getRegister('*').text).toEqual 'initial clipboard content' - expect(vimState.getRegister('*').type).toEqual 'character' - - describe "writing", -> - beforeEach -> - vimState.setRegister('*', text: 'new content') - - it "overwrites the contents of the system clipboard", -> - expect(atom.clipboard.read()).toEqual 'new content' - - # FIXME: once linux support comes out, this needs to read from - # the correct clipboard. For now it behaves just like the * register - # See :help x11-cut-buffer and :help registers for more details on how these - # registers work on an X11 based system. - describe "the + register", -> - describe "reading", -> - it "is the same the system clipboard", -> - expect(vimState.getRegister('*').text).toEqual 'initial clipboard content' - expect(vimState.getRegister('*').type).toEqual 'character' - - describe "writing", -> - beforeEach -> - vimState.setRegister('*', text: 'new content') - - it "overwrites the contents of the system clipboard", -> - expect(atom.clipboard.read()).toEqual 'new content' - - describe "the _ register", -> - describe "reading", -> - it "is always the empty string", -> - expect(vimState.getRegister("_").text).toEqual '' - - describe "writing", -> - it "throws away anything written to it", -> - vimState.setRegister('_', text: 'new content') - expect(vimState.getRegister("_").text).toEqual '' - - describe "the % register", -> - beforeEach -> - spyOn(editor, 'getURI').andReturn('/Users/atom/known_value.txt') - - describe "reading", -> - it "returns the filename of the current editor", -> - expect(vimState.getRegister('%').text).toEqual '/Users/atom/known_value.txt' - - describe "writing", -> - it "throws away anything written to it", -> - vimState.setRegister('%', "new content") - expect(vimState.getRegister('%').text).toEqual '/Users/atom/known_value.txt' - - describe "the ctrl-r command in insert mode", -> - beforeEach -> - editor.setText "02\n" - editor.setCursorScreenPosition [0, 0] - vimState.setRegister('"', text: '345') - vimState.setRegister('a', text: 'abc') - atom.clipboard.write "clip" - keydown 'a' - editor.insertText '1' - - it "inserts contents of the unnamed register with \"", -> - keydown 'r', ctrl: true - keydown '"' - expect(editor.getText()).toBe '013452\n' - - describe "when useClipboardAsDefaultRegister enabled", -> - it "inserts contents from clipboard with \"", -> - atom.config.set 'vim-mode.useClipboardAsDefaultRegister', true - keydown 'r', ctrl: true - keydown '"' - expect(editor.getText()).toBe '01clip2\n' - - it "inserts contents of the 'a' register", -> - keydown 'r', ctrl: true - keydown 'a' - expect(editor.getText()).toBe '01abc2\n' - - it "is cancelled with the escape key", -> - keydown 'r', ctrl: true - keydown 'escape' - expect(editor.getText()).toBe '012\n' - expect(vimState.mode).toBe "insert" - expect(editor.getCursorScreenPosition()).toEqual [0, 2] diff --git a/atom/packages/vim-mode/spec/scroll-spec.coffee b/atom/packages/vim-mode/spec/scroll-spec.coffee deleted file mode 100644 index ebe400a..0000000 --- a/atom/packages/vim-mode/spec/scroll-spec.coffee +++ /dev/null @@ -1,230 +0,0 @@ -helpers = require './spec-helper' - -describe "Scrolling", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - describe "scrolling keybindings", -> - beforeEach -> - editor.setText("1\n2\n3\n4\n5\n6\n7\n8\n9\n10") - spyOn(editor, 'getFirstVisibleScreenRow').andReturn(2) - spyOn(editor, 'getLastVisibleScreenRow').andReturn(8) - spyOn(editor, 'scrollToScreenPosition') - - describe "the ctrl-e keybinding", -> - beforeEach -> - spyOn(editor, 'getCursorScreenPosition').andReturn({row: 4, column: 0}) - spyOn(editor, 'setCursorScreenPosition') - - it "moves the screen down by one and keeps cursor onscreen", -> - keydown('e', ctrl: true) - expect(editor.scrollToScreenPosition).toHaveBeenCalledWith([7, 0]) - expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([6, 0]) - - describe "the ctrl-y keybinding", -> - beforeEach -> - spyOn(editor, 'getCursorScreenPosition').andReturn({row: 6, column: 0}) - spyOn(editor, 'setCursorScreenPosition') - - it "moves the screen up by one and keeps the cursor onscreen", -> - keydown('y', ctrl: true) - expect(editor.scrollToScreenPosition).toHaveBeenCalledWith([3, 0]) - expect(editor.setCursorScreenPosition).toHaveBeenCalledWith([4, 0]) - - describe "scroll cursor keybindings", -> - beforeEach -> - text = "" - for i in [1..200] - text += "#{i}\n" - editor.setText(text) - - spyOn(editor, 'moveToFirstCharacterOfLine') - spyOn(editor, 'getLineHeightInPixels').andReturn(20) - spyOn(editor, 'setScrollTop') - spyOn(editor, 'getHeight').andReturn(200) - spyOn(editor, 'getFirstVisibleScreenRow').andReturn(90) - spyOn(editor, 'getLastVisibleScreenRow').andReturn(110) - - describe "the z<CR> keybinding", -> - keydownCodeForEnter = '\r' - - beforeEach -> - spyOn(editor, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0}) - - it "moves the screen to position cursor at the top of the window and moves cursor to first non-blank in the line", -> - keydown('z') - keydown(keydownCodeForEnter) - expect(editor.setScrollTop).toHaveBeenCalledWith(960) - expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled() - - describe "the zt keybinding", -> - beforeEach -> - spyOn(editor, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0}) - - it "moves the screen to position cursor at the top of the window and leave cursor in the same column", -> - keydown('z') - keydown('t') - expect(editor.setScrollTop).toHaveBeenCalledWith(960) - expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled() - - describe "the z. keybinding", -> - beforeEach -> - spyOn(editor, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0}) - - it "moves the screen to position cursor at the center of the window and moves cursor to first non-blank in the line", -> - keydown('z') - keydown('.') - expect(editor.setScrollTop).toHaveBeenCalledWith(900) - expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled() - - describe "the zz keybinding", -> - beforeEach -> - spyOn(editor, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0}) - - it "moves the screen to position cursor at the center of the window and leave cursor in the same column", -> - keydown('z') - keydown('z') - expect(editor.setScrollTop).toHaveBeenCalledWith(900) - expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled() - - describe "the z- keybinding", -> - beforeEach -> - spyOn(editor, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0}) - - it "moves the screen to position cursor at the bottom of the window and moves cursor to first non-blank in the line", -> - keydown('z') - keydown('-') - expect(editor.setScrollTop).toHaveBeenCalledWith(860) - expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled() - - describe "the zb keybinding", -> - beforeEach -> - spyOn(editor, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0}) - - it "moves the screen to position cursor at the bottom of the window and leave cursor in the same column", -> - keydown('z') - keydown('b') - expect(editor.setScrollTop).toHaveBeenCalledWith(860) - expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled() - - describe "horizontal scroll cursor keybindings", -> - beforeEach -> - editor.setWidth(600) - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - text = "" - for i in [100..199] - text += "#{i} " - editor.setText(text) - editor.setCursorBufferPosition([0, 0]) - - describe "the zs keybinding", -> - zsPos = (pos) -> - editor.setCursorBufferPosition([0, pos]) - keydown('z') - keydown('s') - editor.getScrollLeft() - - startPosition = NaN - - beforeEach -> - startPosition = editor.getScrollLeft() - - it "does nothing near the start of the line", -> - pos1 = zsPos(1) - expect(pos1).toEqual(startPosition) - - it "moves the cursor the nearest it can to the left edge of the editor", -> - pos10 = zsPos(10) - expect(pos10).toBeGreaterThan(startPosition) - - pos11 = zsPos(11) - expect(pos11 - pos10).toEqual(10) - - it "does nothing near the end of the line", -> - posEnd = zsPos(399) - expect(editor.getCursorBufferPosition()).toEqual [0, 399] - - pos390 = zsPos(390) - expect(pos390).toEqual(posEnd) - expect(editor.getCursorBufferPosition()).toEqual [0, 390] - - pos340 = zsPos(340) - expect(pos340).toBeLessThan(posEnd) - pos342 = zsPos(342) - expect(pos342 - pos340).toEqual(20) - - it "does nothing if all lines are short", -> - editor.setText('short') - startPosition = editor.getScrollLeft() - pos1 = zsPos(1) - expect(pos1).toEqual(startPosition) - expect(editor.getCursorBufferPosition()).toEqual [0, 1] - pos10 = zsPos(10) - expect(pos10).toEqual(startPosition) - expect(editor.getCursorBufferPosition()).toEqual [0, 4] - - - describe "the ze keybinding", -> - zePos = (pos) -> - editor.setCursorBufferPosition([0, pos]) - keydown('z') - keydown('e') - editor.getScrollLeft() - - startPosition = NaN - - beforeEach -> - startPosition = editor.getScrollLeft() - - it "does nothing near the start of the line", -> - pos1 = zePos(1) - expect(pos1).toEqual(startPosition) - - pos40 = zePos(40) - expect(pos40).toEqual(startPosition) - - it "moves the cursor the nearest it can to the right edge of the editor", -> - pos110 = zePos(110) - expect(pos110).toBeGreaterThan(startPosition) - - pos109 = zePos(109) - expect(pos110 - pos109).toEqual(10) - - it "does nothing when very near the end of the line", -> - posEnd = zePos(399) - expect(editor.getCursorBufferPosition()).toEqual [0, 399] - - pos397 = zePos(397) - expect(pos397).toEqual(posEnd) - expect(editor.getCursorBufferPosition()).toEqual [0, 397] - - pos380 = zePos(380) - expect(pos380).toBeLessThan(posEnd) - - pos382 = zePos(382) - expect(pos382 - pos380).toEqual(20) - - it "does nothing if all lines are short", -> - editor.setText('short') - startPosition = editor.getScrollLeft() - pos1 = zePos(1) - expect(pos1).toEqual(startPosition) - expect(editor.getCursorBufferPosition()).toEqual [0, 1] - pos10 = zePos(10) - expect(pos10).toEqual(startPosition) - expect(editor.getCursorBufferPosition()).toEqual [0, 4] diff --git a/atom/packages/vim-mode/spec/spec-helper.coffee b/atom/packages/vim-mode/spec/spec-helper.coffee deleted file mode 100644 index 7cff2fc..0000000 --- a/atom/packages/vim-mode/spec/spec-helper.coffee +++ /dev/null @@ -1,76 +0,0 @@ -VimState = require '../lib/vim-state' -GlobalVimState = require '../lib/global-vim-state' -VimMode = require '../lib/vim-mode' -StatusBarManager = require '../lib/status-bar-manager' - -[globalVimState, statusBarManager] = [] - -beforeEach -> - atom.workspace ||= {} - statusBarManager = null - globalVimState = null - spyOn(atom, 'beep') - -getEditorElement = (callback) -> - textEditor = null - - waitsForPromise -> - atom.project.open().then (e) -> - textEditor = e - - runs -> - element = document.createElement("atom-text-editor") - element.setModel(textEditor) - element.classList.add('vim-mode') - statusBarManager ?= new StatusBarManager - globalVimState ?= new GlobalVimState - element.vimState = new VimState(element, statusBarManager, globalVimState) - - element.addEventListener "keydown", (e) -> - atom.keymaps.handleKeyboardEvent(e) - - # mock parent element for the text editor - document.createElement('html').appendChild(atom.views.getView(textEditor)) - - callback(element) - -mockPlatform = (editorElement, platform) -> - wrapper = document.createElement('div') - wrapper.className = platform - wrapper.appendChild(editorElement) - -unmockPlatform = (editorElement) -> - editorElement.parentNode.removeChild(editorElement) - -dispatchKeyboardEvent = (target, eventArgs...) -> - e = document.createEvent('KeyboardEvent') - e.initKeyboardEvent(eventArgs...) - # 0 is the default, and it's valid ASCII, but it's wrong. - Object.defineProperty(e, 'keyCode', get: -> undefined) if e.keyCode is 0 - target.dispatchEvent e - -dispatchTextEvent = (target, eventArgs...) -> - e = document.createEvent('TextEvent') - e.initTextEvent(eventArgs...) - target.dispatchEvent e - -keydown = (key, {element, ctrl, shift, alt, meta, raw}={}) -> - key = "U+#{key.charCodeAt(0).toString(16)}" unless key is 'escape' or raw? - element ||= document.activeElement - eventArgs = [ - true, # bubbles - true, # cancelable - null, # view - key, # key - 0, # location - ctrl, alt, shift, meta - ] - - canceled = not dispatchKeyboardEvent(element, 'keydown', eventArgs...) - dispatchKeyboardEvent(element, 'keypress', eventArgs...) - if not canceled - if dispatchTextEvent(element, 'textInput', eventArgs...) - element.value += key - dispatchKeyboardEvent(element, 'keyup', eventArgs...) - -module.exports = {keydown, getEditorElement, mockPlatform, unmockPlatform} diff --git a/atom/packages/vim-mode/spec/text-objects-spec.coffee b/atom/packages/vim-mode/spec/text-objects-spec.coffee deleted file mode 100644 index 92b4a7a..0000000 --- a/atom/packages/vim-mode/spec/text-objects-spec.coffee +++ /dev/null @@ -1,825 +0,0 @@ -helpers = require './spec-helper' - -describe "TextObjects", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - describe "Text Object commands in normal mode not preceded by an operator", -> - beforeEach -> - vimState.activateNormalMode() - - it "selects the appropriate text", -> - editor.setText("<html> text </html>") - editor.setCursorScreenPosition([0, 7]) - # Users could dispatch it via the command palette - atom.commands.dispatch(editorElement, "vim-mode:select-inside-tags") - expect(editor.getSelectedScreenRange()).toEqual [[0, 6], [0, 12]] - - describe "the 'iw' text object", -> - beforeEach -> - editor.setText("12345 abcde ABCDE") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current word in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('w') - - expect(editor.getText()).toBe "12345 ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - expect(vimState.getRegister('"').text).toBe "abcde" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects inside the current word in visual mode", -> - keydown('v') - keydown('i') - keydown('w') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 6], [0, 11]] - - it "expands an existing selection in visual mode", -> - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('w') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 9], [0, 17]] - - it "works with multiple cursors", -> - editor.addCursorAtBufferPosition([0, 1]) - keydown("v") - keydown("i") - keydown("w") - expect(editor.getSelectedBufferRanges()).toEqual [ - [[0, 6], [0, 11]] - [[0, 0], [0, 5]] - ] - - describe "the 'iW' text object", -> - beforeEach -> - editor.setText("12(45 ab'de ABCDE") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current whole word in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('W', shift: true) - - expect(editor.getText()).toBe "12(45 ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - expect(vimState.getRegister('"').text).toBe "ab'de" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects inside the current whole word in visual mode", -> - keydown('v') - keydown('i') - keydown('W', shift: true) - - expect(editor.getSelectedScreenRange()).toEqual [[0, 6], [0, 11]] - - it "expands an existing selection in visual mode", -> - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('W', shift: true) - - expect(editor.getSelectedScreenRange()).toEqual [[0, 9], [0, 17]] - - describe "the 'i(' text object", -> - beforeEach -> - editor.setText("( something in here and in (here) )") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current word in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('(') - expect(editor.getText()).toBe "()" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the current word in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('i') - keydown('(') - expect(editor.getText()).toBe "( something in here and in () )" - expect(editor.getCursorScreenPosition()).toEqual [0, 28] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "works with multiple cursors", -> - editor.setText("( a b ) cde ( f g h ) ijk") - editor.setCursorBufferPosition([0, 2]) - editor.addCursorAtBufferPosition([0, 18]) - - keydown("v") - keydown("i") - keydown("(") - - expect(editor.getSelectedBufferRanges()).toEqual [ - [[0, 1], [0, 6]] - [[0, 13], [0, 20]] - ] - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('(') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 32]] - - describe "the 'i{' text object", -> - beforeEach -> - editor.setText("{ something in here and in {here} }") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current word in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('{') - expect(editor.getText()).toBe "{}" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the current word in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('i') - keydown('{') - expect(editor.getText()).toBe "{ something in here and in {} }" - expect(editor.getCursorScreenPosition()).toEqual [0, 28] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('{') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 32]] - - describe "the 'i<' text object", -> - beforeEach -> - editor.setText("< something in here and in <here> >") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current word in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('<') - expect(editor.getText()).toBe "<>" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the current word in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('i') - keydown('<') - expect(editor.getText()).toBe "< something in here and in <> >" - expect(editor.getCursorScreenPosition()).toEqual [0, 28] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('<') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 32]] - - describe "the 'it' text object", -> - beforeEach -> - editor.setText("<something>here</something><again>") - editor.setCursorScreenPosition([0, 5]) - - it "applies only if in the value of a tag", -> - keydown('d') - keydown('i') - keydown('t') - expect(editor.getText()).toBe "<something>here</something><again>" - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the current word in operator-pending mode", -> - editor.setCursorScreenPosition([0, 13]) - keydown('d') - keydown('i') - keydown('t') - expect(editor.getText()).toBe "<something></something><again>" - expect(editor.getCursorScreenPosition()).toEqual [0, 11] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 7]) - keydown('v') - keydown('6') - keydown('l') - keydown('i') - keydown('t') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 7], [0, 15]] - - describe "the 'ip' text object", -> - beforeEach -> - editor.setText("\nParagraph-1\nParagraph-1\nParagraph-1\n\n") - editor.setCursorBufferPosition([2, 2]) - - it "applies operators inside the current paragraph in operator-pending mode", -> - keydown('y') - keydown('i') - keydown('p') - - expect(editor.getText()).toBe "\nParagraph-1\nParagraph-1\nParagraph-1\n\n" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe "Paragraph-1\nParagraph-1\nParagraph-1\n" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects inside the current paragraph in visual mode", -> - keydown('v') - keydown('i') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[1, 0], [4, 0]] - - it "selects between paragraphs in visual mode if invoked on a empty line", -> - editor.setText("text\n\n\n\ntext\n") - editor.setCursorBufferPosition([1, 0]) - - keydown('v') - keydown('i') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[1, 0], [4, 0]] - - it "selects all the lines", -> - editor.setText("text\ntext\ntext\n") - editor.setCursorBufferPosition([0, 0]) - - keydown('v') - keydown('i') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 0], [3, 0]] - - it "expands an existing selection in visual mode", -> - editor.setText("\nParagraph-1\nParagraph-1\nParagraph-1\n\n\nParagraph-2\nParagraph-2\nParagraph-2\n") - editor.setCursorBufferPosition([2, 2]) - - keydown('v') - keydown('i') - keydown('p') - - keydown('j') - keydown('j') - keydown('j') - keydown('i') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[1, 0], [9, 0]] - - describe "the 'ap' text object", -> - beforeEach -> - editor.setText("text\n\nParagraph-1\nParagraph-1\nParagraph-1\n\n\nmoretext") - editor.setCursorScreenPosition([3, 2]) - - it "applies operators around the current paragraph in operator-pending mode", -> - keydown('y') - keydown('a') - keydown('p') - - expect(editor.getText()).toBe "text\n\nParagraph-1\nParagraph-1\nParagraph-1\n\n\nmoretext" - expect(editor.getCursorScreenPosition()).toEqual [2, 0] - expect(vimState.getRegister('"').text).toBe "Paragraph-1\nParagraph-1\nParagraph-1\n\n\n" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects around the current paragraph in visual mode", -> - keydown('v') - keydown('a') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[2, 0], [7, 0]] - - it "applies operators around the next paragraph in operator-pending mode when started from a blank/only-whitespace line", -> - editor.setText("text\n\n\n\nParagraph-1\nParagraph-1\nParagraph-1\n\n\nmoretext") - editor.setCursorBufferPosition([1, 0]) - - keydown('y') - keydown('a') - keydown('p') - - expect(editor.getText()).toBe "text\n\n\n\nParagraph-1\nParagraph-1\nParagraph-1\n\n\nmoretext" - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - expect(vimState.getRegister('"').text).toBe "\n\n\nParagraph-1\nParagraph-1\nParagraph-1\n" - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects around the next paragraph in visual mode when started from a blank/only-whitespace line", -> - editor.setText("text\n\n\n\nparagraph-1\nparagraph-1\nparagraph-1\n\n\nmoretext") - editor.setCursorBufferPosition([1, 0]) - - keydown('v') - keydown('a') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[1, 0], [7, 0]] - - it "expands an existing selection in visual mode", -> - editor.setText("text\n\n\n\nparagraph-1\nparagraph-1\nparagraph-1\n\n\n\nparagraph-2\nparagraph-2\nparagraph-2\n\n\nmoretext") - editor.setCursorBufferPosition([5, 0]) - - keydown('v') - keydown('a') - keydown('p') - - keydown('j') - keydown('j') - keydown('j') - keydown('i') - keydown('p') - - expect(editor.getSelectedScreenRange()).toEqual [[4, 0], [13, 0]] - - describe "the 'i[' text object", -> - beforeEach -> - editor.setText("[ something in here and in [here] ]") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current word in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('[') - expect(editor.getText()).toBe "[]" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the current word in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('i') - keydown('[') - expect(editor.getText()).toBe "[ something in here and in [] ]" - expect(editor.getCursorScreenPosition()).toEqual [0, 28] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('[') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 32]] - - describe "the 'i\'' text object", -> - beforeEach -> - editor.setText("' something in here and in 'here' ' and over here") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current string in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('\'') - expect(editor.getText()).toBe "''here' ' and over here" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the next string in operator-pending mode (if not in a string)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('i') - keydown('\'') - expect(editor.getText()).toBe "' something in here and in 'here'' and over here" - expect(editor.getCursorScreenPosition()).toEqual [0, 33] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "makes no change if past the last string on a line", -> - editor.setCursorScreenPosition([0, 39]) - keydown('d') - keydown('i') - keydown('\'') - expect(editor.getText()).toBe "' something in here and in 'here' ' and over here" - expect(editor.getCursorScreenPosition()).toEqual [0, 39] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('\'') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 34]] - - describe "the 'i\"' text object", -> - beforeEach -> - editor.setText("\" something in here and in \"here\" \" and over here") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators inside the current string in operator-pending mode", -> - keydown('d') - keydown('i') - keydown('"') - expect(editor.getText()).toBe "\"\"here\" \" and over here" - expect(editor.getCursorScreenPosition()).toEqual [0, 1] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators inside the next string in operator-pending mode (if not in a string)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('i') - keydown('"') - expect(editor.getText()).toBe "\" something in here and in \"here\"\" and over here" - expect(editor.getCursorScreenPosition()).toEqual [0, 33] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "makes no change if past the last string on a line", -> - editor.setCursorScreenPosition([0, 39]) - keydown('d') - keydown('i') - keydown('"') - expect(editor.getText()).toBe "\" something in here and in \"here\" \" and over here" - expect(editor.getCursorScreenPosition()).toEqual [0, 39] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('i') - keydown('"') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 34]] - - describe "the 'aw' text object", -> - beforeEach -> - editor.setText("12345 abcde ABCDE") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators from the start of the current word to the start of the next word in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('w') - - expect(editor.getText()).toBe "12345 ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - expect(vimState.getRegister('"').text).toBe "abcde " - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects from the start of the current word to the start of the next word in visual mode", -> - keydown('v') - keydown('a') - keydown('w') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 6], [0, 12]] - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 2]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('w') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 2], [0, 12]] - - it "doesn't span newlines", -> - editor.setText("12345\nabcde ABCDE") - editor.setCursorBufferPosition([0, 3]) - - keydown("v") - keydown("a") - keydown("w") - - expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 5]]] - - it "doesn't span special characters", -> - editor.setText("1(345\nabcde ABCDE") - editor.setCursorBufferPosition([0, 3]) - - keydown("v") - keydown("a") - keydown("w") - - expect(editor.getSelectedBufferRanges()).toEqual [[[0, 2], [0, 5]]] - - describe "the 'aW' text object", -> - beforeEach -> - editor.setText("12(45 ab'de ABCDE") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators from the start of the current whole word to the start of the next whole word in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('W', shift: true) - - expect(editor.getText()).toBe "12(45 ABCDE" - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - expect(vimState.getRegister('"').text).toBe "ab'de " - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "selects from the start of the current whole word to the start of the next whole word in visual mode", -> - keydown('v') - keydown('a') - keydown('W', shift: true) - - expect(editor.getSelectedScreenRange()).toEqual [[0, 6], [0, 12]] - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 2]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('W', shift: true) - - expect(editor.getSelectedScreenRange()).toEqual [[0, 2], [0, 12]] - - it "doesn't span newlines", -> - editor.setText("12(45\nab'de ABCDE") - editor.setCursorBufferPosition([0, 4]) - - keydown('v') - keydown('a') - keydown('W', shift: true) - - expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 5]]] - - describe "the 'a(' text object", -> - beforeEach -> - editor.setText("( something in here and in (here) )") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators around the current parentheses in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('(') - expect(editor.getText()).toBe "" - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators around the current parentheses in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('a') - keydown('(') - expect(editor.getText()).toBe "( something in here and in )" - expect(editor.getCursorScreenPosition()).toEqual [0, 27] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('(') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 33]] - - describe "the 'a{' text object", -> - beforeEach -> - editor.setText("{ something in here and in {here} }") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators around the current curly brackets in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('{') - expect(editor.getText()).toBe "" - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators around the current curly brackets in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('a') - keydown('{') - expect(editor.getText()).toBe "{ something in here and in }" - expect(editor.getCursorScreenPosition()).toEqual [0, 27] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('{') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 33]] - - describe "the 'a<' text object", -> - beforeEach -> - editor.setText("< something in here and in <here> >") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators around the current angle brackets in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('<') - expect(editor.getText()).toBe "" - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators around the current angle brackets in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('a') - keydown('<') - expect(editor.getText()).toBe "< something in here and in >" - expect(editor.getCursorScreenPosition()).toEqual [0, 27] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('<') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 33]] - - describe "the 'a[' text object", -> - beforeEach -> - editor.setText("[ something in here and in [here] ]") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators around the current square brackets in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('[') - expect(editor.getText()).toBe "" - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators around the current square brackets in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('a') - keydown('[') - expect(editor.getText()).toBe "[ something in here and in ]" - expect(editor.getCursorScreenPosition()).toEqual [0, 27] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('[') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 33]] - - describe "the 'a\'' text object", -> - beforeEach -> - editor.setText("' something in here and in 'here' '") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators around the current single quotes in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('\'') - expect(editor.getText()).toBe "here' '" - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators around the current single quotes in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('a') - keydown('\'') - expect(editor.getText()).toBe "' something in here and in 'here" - expect(editor.getCursorScreenPosition()).toEqual [0, 31] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('\'') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 35]] - - describe "the 'a\"' text object", -> - beforeEach -> - editor.setText("\" something in here and in \"here\" \"") - editor.setCursorScreenPosition([0, 9]) - - it "applies operators around the current double quotes in operator-pending mode", -> - keydown('d') - keydown('a') - keydown('""') - expect(editor.getText()).toBe 'here" "' - expect(editor.getCursorScreenPosition()).toEqual [0, 0] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "applies operators around the current double quotes in operator-pending mode (second test)", -> - editor.setCursorScreenPosition([0, 29]) - keydown('d') - keydown('a') - keydown('"') - expect(editor.getText()).toBe "\" something in here and in \"here" - expect(editor.getCursorScreenPosition()).toEqual [0, 31] - expect(editorElement.classList.contains('operator-pending-mode')).toBe(false) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "expands an existing selection in visual mode", -> - editor.setCursorScreenPosition([0, 25]) - keydown('v') - keydown('l') - keydown('l') - keydown('l') - keydown('l') - keydown('a') - keydown('"') - - expect(editor.getSelectedScreenRange()).toEqual [[0, 25], [0, 35]] diff --git a/atom/packages/vim-mode/spec/vim-mode-spec.coffee b/atom/packages/vim-mode/spec/vim-mode-spec.coffee deleted file mode 100644 index 280e545..0000000 --- a/atom/packages/vim-mode/spec/vim-mode-spec.coffee +++ /dev/null @@ -1,61 +0,0 @@ -describe "VimMode", -> - [editor, editorElement, workspaceElement] = [] - - beforeEach -> - workspaceElement = atom.views.getView(atom.workspace) - - waitsForPromise -> - atom.workspace.open() - - waitsForPromise -> - atom.packages.activatePackage('vim-mode') - - waitsForPromise -> - atom.packages.activatePackage('status-bar') - - runs -> - editor = atom.workspace.getActiveTextEditor() - editorElement = atom.views.getView(editor) - - describe ".activate", -> - it "puts the editor in normal-mode initially by default", -> - expect(editorElement.classList.contains('vim-mode')).toBe(true) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "shows the current vim mode in the status bar", -> - statusBarTile = null - - waitsFor -> - statusBarTile = workspaceElement.querySelector("#status-bar-vim-mode") - - runs -> - expect(statusBarTile.textContent).toBe("Normal") - atom.commands.dispatch(editorElement, "vim-mode:activate-insert-mode") - expect(statusBarTile.textContent).toBe("Insert") - - it "doesn't register duplicate command listeners for editors", -> - editor.setText("12345") - editor.setCursorBufferPosition([0, 0]) - - pane = atom.workspace.getActivePane() - newPane = pane.splitRight() - pane.removeItem(editor) - newPane.addItem(editor) - - atom.commands.dispatch(editorElement, "vim-mode:move-right") - expect(editor.getCursorBufferPosition()).toEqual([0, 1]) - - describe ".deactivate", -> - it "removes the vim classes from the editor", -> - atom.packages.deactivatePackage('vim-mode') - expect(editorElement.classList.contains("vim-mode")).toBe(false) - expect(editorElement.classList.contains("normal-mode")).toBe(false) - - it "removes the vim commands from the editor element", -> - vimCommands = -> - atom.commands.findCommands(target: editorElement).filter (cmd) -> - cmd.name.startsWith("vim-mode:") - - expect(vimCommands().length).toBeGreaterThan(0) - atom.packages.deactivatePackage('vim-mode') - expect(vimCommands().length).toBe(0) diff --git a/atom/packages/vim-mode/spec/vim-state-spec.coffee b/atom/packages/vim-mode/spec/vim-state-spec.coffee deleted file mode 100644 index 8fd3fb0..0000000 --- a/atom/packages/vim-mode/spec/vim-state-spec.coffee +++ /dev/null @@ -1,519 +0,0 @@ -_ = require 'underscore-plus' -helpers = require './spec-helper' -VimState = require '../lib/vim-state' -StatusBarManager = require '../lib/status-bar-manager' - -describe "VimState", -> - [editor, editorElement, vimState] = [] - - beforeEach -> - vimMode = atom.packages.loadPackage('vim-mode') - vimMode.activateResources() - - helpers.getEditorElement (element) -> - editorElement = element - editor = editorElement.getModel() - vimState = editorElement.vimState - vimState.activateNormalMode() - vimState.resetNormalMode() - - keydown = (key, options={}) -> - options.element ?= editorElement - helpers.keydown(key, options) - - normalModeInputKeydown = (key, opts = {}) -> - editor.normalModeInputView.editorElement.getModel().setText(key) - - describe "initialization", -> - it "puts the editor in normal-mode initially by default", -> - expect(editorElement.classList.contains('vim-mode')).toBe(true) - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "puts the editor in insert-mode if startInInsertMode is true", -> - atom.config.set 'vim-mode.startInInsertMode', true - editor.vimState = new VimState(editorElement, new StatusBarManager) - expect(editorElement.classList.contains('insert-mode')).toBe(true) - - describe "::destroy", -> - it "re-enables text input on the editor", -> - expect(editorElement.component.isInputEnabled()).toBeFalsy() - vimState.destroy() - expect(editorElement.component.isInputEnabled()).toBeTruthy() - - it "removes the mode classes from the editor", -> - expect(editorElement.classList.contains("normal-mode")).toBeTruthy() - vimState.destroy() - expect(editorElement.classList.contains("normal-mode")).toBeFalsy() - - it "is a noop when the editor is already destroyed", -> - editorElement.getModel().destroy() - vimState.destroy() - - describe "normal-mode", -> - describe "when entering an insertable character", -> - beforeEach -> keydown('\\') - - it "stops propagation", -> - expect(editor.getText()).toEqual '' - - describe "when entering an operator", -> - beforeEach -> keydown('d') - - describe "with an operator that can't be composed", -> - beforeEach -> keydown('x') - - it "clears the operator stack", -> - expect(vimState.opStack.length).toBe 0 - - describe "the escape keybinding", -> - beforeEach -> keydown('escape') - - it "clears the operator stack", -> - expect(vimState.opStack.length).toBe 0 - - describe "the ctrl-c keybinding", -> - beforeEach -> keydown('c', ctrl: true) - - it "clears the operator stack", -> - expect(vimState.opStack.length).toBe 0 - - describe "the escape keybinding", -> - it "clears any extra cursors", -> - editor.setText("one-two-three") - editor.addCursorAtBufferPosition([0, 3]) - expect(editor.getCursors().length).toBe 2 - keydown('escape') - expect(editor.getCursors().length).toBe 1 - - describe "the v keybinding", -> - beforeEach -> - editor.setText("012345\nabcdef") - editor.setCursorScreenPosition([0, 0]) - keydown('v') - - it "puts the editor into visual characterwise mode", -> - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'characterwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - it "selects the current character", -> - expect(editor.getLastSelection().getText()).toEqual '0' - - describe "the V keybinding", -> - beforeEach -> - editor.setText("012345\nabcdef") - editor.setCursorScreenPosition([0, 0]) - keydown('V', shift: true) - - it "puts the editor into visual linewise mode", -> - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'linewise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - it "selects the current line", -> - expect(editor.getLastSelection().getText()).toEqual '012345\n' - - describe "the ctrl-v keybinding", -> - beforeEach -> - editor.setText("012345\nabcdef") - editor.setCursorScreenPosition([0, 0]) - keydown('v', ctrl: true) - - it "puts the editor into visual blockwise mode", -> - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'blockwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - describe "selecting text", -> - beforeEach -> - editor.setText("abc def") - editor.setCursorScreenPosition([0, 0]) - - it "puts the editor into visual mode", -> - expect(vimState.mode).toEqual 'normal' - atom.commands.dispatch(editorElement, "core:select-right") - - expect(vimState.mode).toEqual 'visual' - expect(vimState.submode).toEqual 'characterwise' - expect(editor.getSelectedBufferRanges()).toEqual([[[0, 0], [0, 1]]]) - - it "handles the editor being destroyed shortly after selecting text", -> - editor.setSelectedBufferRanges([[[0, 0], [0, 3]]]) - editor.destroy() - vimState.destroy() - advanceClock(100) - - it "handles native selection such as core:select-all", -> - atom.commands.dispatch(editorElement, "core:select-all") - expect(editor.getSelectedBufferRanges()).toEqual([[[0, 0], [0, 7]]]) - - describe "the i keybinding", -> - beforeEach -> keydown('i') - - it "puts the editor into insert mode", -> - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - describe "the R keybinding", -> - beforeEach -> keydown('R', shift: true) - - it "puts the editor into replace mode", -> - expect(editorElement.classList.contains('insert-mode')).toBe(true) - expect(editorElement.classList.contains('replace-mode')).toBe(true) - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - describe "with content", -> - beforeEach -> - editor.setText("012345\n\nabcdef") - editor.setCursorScreenPosition([0, 0]) - - describe "on a line with content", -> - it "does not allow atom commands to place the cursor on the \\n character", -> - atom.commands.dispatch(editorElement, "editor:move-to-end-of-line") - expect(editor.getCursorScreenPosition()).toEqual [0, 5] - - describe "on an empty line", -> - beforeEach -> - editor.setCursorScreenPosition([1, 0]) - atom.commands.dispatch(editorElement, "editor:move-to-end-of-line") - - it "allows the cursor to be placed on the \\n character", -> - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - describe 'with character-input operations', -> - beforeEach -> editor.setText('012345\nabcdef') - - it 'properly clears the opStack', -> - keydown('d') - keydown('r') - expect(vimState.mode).toBe 'normal' - expect(vimState.opStack.length).toBe 0 - atom.commands.dispatch(editor.normalModeInputView.editorElement, "core:cancel") - keydown('d') - expect(editor.getText()).toBe '012345\nabcdef' - - describe "insert-mode", -> - beforeEach -> - keydown('i') - - describe "with content", -> - beforeEach -> editor.setText("012345\n\nabcdef") - - describe "when cursor is in the middle of the line", -> - beforeEach -> editor.setCursorScreenPosition([0, 3]) - - it "moves the cursor to the left when exiting insert mode", -> - keydown('escape') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "when cursor is at the beginning of line", -> - beforeEach -> editor.setCursorScreenPosition([1, 0]) - - it "leaves the cursor at the beginning of line", -> - keydown('escape') - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - describe "on a line with content", -> - beforeEach -> - editor.setCursorScreenPosition([0, 0]) - atom.commands.dispatch(editorElement, "editor:move-to-end-of-line") - - it "allows the cursor to be placed on the \\n character", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - it "puts the editor into normal mode when <escape> is pressed", -> - keydown('escape') - - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editorElement.classList.contains('insert-mode')).toBe(false) - expect(editorElement.classList.contains('visual-mode')).toBe(false) - - it "puts the editor into normal mode when <ctrl-c> is pressed", -> - helpers.mockPlatform(editorElement, 'platform-darwin') - keydown('c', ctrl: true) - helpers.unmockPlatform(editorElement) - - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editorElement.classList.contains('insert-mode')).toBe(false) - expect(editorElement.classList.contains('visual-mode')).toBe(false) - - describe "replace-mode", -> - describe "with content", -> - beforeEach -> editor.setText("012345\n\nabcdef") - - describe "when cursor is in the middle of the line", -> - beforeEach -> - editor.setCursorScreenPosition([0, 3]) - keydown('R', shift: true) - - it "moves the cursor to the left when exiting replace mode", -> - keydown('escape') - expect(editor.getCursorScreenPosition()).toEqual [0, 2] - - describe "when cursor is at the beginning of line", -> - beforeEach -> - editor.setCursorScreenPosition([1, 0]) - keydown('R', shift: true) - - it "leaves the cursor at the beginning of line", -> - keydown('escape') - expect(editor.getCursorScreenPosition()).toEqual [1, 0] - - describe "on a line with content", -> - beforeEach -> - keydown('R', shift: true) - editor.setCursorScreenPosition([0, 0]) - atom.commands.dispatch(editorElement, "editor:move-to-end-of-line") - - it "allows the cursor to be placed on the \\n character", -> - expect(editor.getCursorScreenPosition()).toEqual [0, 6] - - it "puts the editor into normal mode when <escape> is pressed", -> - keydown('R', shift: true) - keydown('escape') - - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editorElement.classList.contains('insert-mode')).toBe(false) - expect(editorElement.classList.contains('replace-mode')).toBe(false) - expect(editorElement.classList.contains('visual-mode')).toBe(false) - - it "puts the editor into normal mode when <ctrl-c> is pressed", -> - keydown('R', shift: true) - helpers.mockPlatform(editorElement, 'platform-darwin') - keydown('c', ctrl: true) - helpers.unmockPlatform(editorElement) - - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editorElement.classList.contains('insert-mode')).toBe(false) - expect(editorElement.classList.contains('replace-mode')).toBe(false) - expect(editorElement.classList.contains('visual-mode')).toBe(false) - - describe "visual-mode", -> - beforeEach -> - editor.setText("one two three") - editor.setCursorBufferPosition([0, 4]) - keydown('v') - - it "selects the character under the cursor", -> - expect(editor.getSelectedBufferRanges()).toEqual [[[0, 4], [0, 5]]] - expect(editor.getSelectedText()).toBe("t") - - it "puts the editor into normal mode when <escape> is pressed", -> - keydown('escape') - - expect(editor.getCursorBufferPositions()).toEqual [[0, 4]] - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editorElement.classList.contains('visual-mode')).toBe(false) - - it "puts the editor into normal mode when <escape> is pressed on selection is reversed", -> - expect(editor.getSelectedText()).toBe("t") - keydown("h") - keydown("h") - expect(editor.getSelectedText()).toBe("e t") - expect(editor.getLastSelection().isReversed()).toBe(true) - keydown('escape') - expect(editorElement.classList.contains('normal-mode')).toBe(true) - expect(editor.getCursorBufferPositions()).toEqual [[0, 2]] - - describe "motions", -> - it "transforms the selection", -> - keydown('w') - expect(editor.getLastSelection().getText()).toEqual 'two t' - - it "always leaves the initially selected character selected", -> - keydown("h") - expect(editor.getSelectedText()).toBe(" t") - - keydown("l") - expect(editor.getSelectedText()).toBe("t") - - keydown("l") - expect(editor.getSelectedText()).toBe("tw") - - describe "operators", -> - beforeEach -> - editor.setText("012345\n\nabcdef") - editor.setCursorScreenPosition([0, 0]) - editor.selectLinesContainingCursors() - keydown('d') - - it "operate on the current selection", -> - expect(editor.getText()).toEqual "\nabcdef" - - describe "returning to normal-mode", -> - beforeEach -> - editor.setText("012345\n\nabcdef") - editor.selectLinesContainingCursors() - keydown('escape') - - it "operate on the current selection", -> - expect(editor.getLastSelection().getText()).toEqual '' - - describe "the o keybinding", -> - it "reversed each selection", -> - editor.addCursorAtBufferPosition([0, Infinity]) - keydown("i") - keydown("w") - - expect(editor.getSelectedBufferRanges()).toEqual([ - [[0, 4], [0, 7]], - [[0, 8], [0, 13]] - ]) - expect(editor.getCursorBufferPositions()).toEqual([ - [0, 7] - [0, 13] - ]) - - keydown("o") - - expect(editor.getSelectedBufferRanges()).toEqual([ - [[0, 4], [0, 7]], - [[0, 8], [0, 13]] - ]) - expect(editor.getCursorBufferPositions()).toEqual([ - [0, 4] - [0, 8] - ]) - - it "harmonizes selection directions", -> - keydown("e") - editor.addCursorAtBufferPosition([0, Infinity]) - keydown("h") - keydown("h") - - expect(editor.getSelectedBufferRanges()).toEqual([ - [[0, 4], [0, 5]], - [[0, 11], [0, 13]] - ]) - expect(editor.getCursorBufferPositions()).toEqual([ - [0, 5] - [0, 11] - ]) - - keydown("o") - - expect(editor.getSelectedBufferRanges()).toEqual([ - [[0, 4], [0, 5]], - [[0, 11], [0, 13]] - ]) - expect(editor.getCursorBufferPositions()).toEqual([ - [0, 5] - [0, 13] - ]) - - describe "activate visualmode witin visualmode", -> - beforeEach -> - keydown('escape') - expect(vimState.mode).toEqual 'normal' - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - it "activateVisualMode with same type puts the editor into normal mode", -> - keydown('v') - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'characterwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - keydown('v') - expect(vimState.mode).toEqual 'normal' - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - keydown('V', shift: true) - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'linewise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - keydown('V', shift: true) - expect(vimState.mode).toEqual 'normal' - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - keydown('v', ctrl: true) - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'blockwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - keydown('v', ctrl: true) - expect(vimState.mode).toEqual 'normal' - expect(editorElement.classList.contains('normal-mode')).toBe(true) - - describe "change submode within visualmode", -> - beforeEach -> - editor.setText("line one\nline two\nline three\n") - editor.setCursorBufferPosition([0, 5]) - editor.addCursorAtBufferPosition([2, 5]) - - it "can change submode within visual mode", -> - keydown('v') - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'characterwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - keydown('V', shift: true) - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'linewise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - keydown('v', ctrl: true) - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'blockwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - keydown('v') - expect(editorElement.classList.contains('visual-mode')).toBe(true) - expect(vimState.submode).toEqual 'characterwise' - expect(editorElement.classList.contains('normal-mode')).toBe(false) - - - it "recover original range when shift from linewse to characterwise", -> - keydown('v') - keydown('i') - keydown('w') - - expect(_.map(editor.getSelections(), (selection) -> - selection.getText()) - ).toEqual(['one', 'three']) - - keydown('V', shift: true) - expect(_.map(editor.getSelections(), (selection) -> - selection.getText()) - ).toEqual(["line one\n", "line three\n"]) - - keydown('v', ctrl: true) - expect(_.map(editor.getSelections(), (selection) -> - selection.getText()) - ).toEqual(['one', 'three']) - - describe "marks", -> - beforeEach -> editor.setText("text in line 1\ntext in line 2\ntext in line 3") - - it "basic marking functionality", -> - editor.setCursorScreenPosition([1, 1]) - keydown('m') - normalModeInputKeydown('t') - expect(editor.getText()).toEqual "text in line 1\ntext in line 2\ntext in line 3" - editor.setCursorScreenPosition([2, 2]) - keydown('`') - normalModeInputKeydown('t') - expect(editor.getCursorScreenPosition()).toEqual [1, 1] - - it "real (tracking) marking functionality", -> - editor.setCursorScreenPosition([2, 2]) - keydown('m') - normalModeInputKeydown('q') - editor.setCursorScreenPosition([1, 2]) - keydown('o') - keydown('escape') - keydown('`') - normalModeInputKeydown('q') - expect(editor.getCursorScreenPosition()).toEqual [3, 2] - - it "real (tracking) marking functionality", -> - editor.setCursorScreenPosition([2, 2]) - keydown('m') - normalModeInputKeydown('q') - editor.setCursorScreenPosition([1, 2]) - keydown('d') - keydown('d') - keydown('escape') - keydown('`') - normalModeInputKeydown('q') - expect(editor.getCursorScreenPosition()).toEqual [1, 2] |