1 helpers = require './spec-helper'
2 settings = require '../lib/settings'
4 describe "Operators", ->
5 [editor, editorElement, vimState] = []
8 vimMode = atom.packages.loadPackage('vim-mode')
9 vimMode.activateResources()
11 helpers.getEditorElement (element) ->
12 editorElement = element
13 editor = editorElement.getModel()
14 vimState = editorElement.vimState
15 vimState.activateCommandMode()
16 vimState.resetCommandMode()
18 keydown = (key, options={}) ->
19 options.element ?= editorElement
20 helpers.keydown(key, options)
22 commandModeInputKeydown = (key, opts = {}) ->
23 editor.commandModeInputView.editorElement.getModel().setText(key)
25 describe "cancelling operations", ->
26 it "does not throw an error even if no operation is pending", ->
27 # cancel operation pushes an empty input operation
28 # doing this without a pending operation throws an exception
29 expect(-> vimState.pushOperations(new Input(''))).toThrow()
31 # make sure commandModeInputView is created
33 expect(vimState.isOperatorPending()).toBe true
34 editor.commandModeInputView.viewModel.cancel()
36 expect(vimState.isOperatorPending()).toBe false
37 expect(-> editor.commandModeInputView.viewModel.cancel()).not.toThrow()
39 describe "the x keybinding", ->
40 describe "on a line with content", ->
41 describe "without vim-mode.wrapLeftRightMotion", ->
43 editor.setText("abc\n012345\n\nxyz")
44 editor.setCursorScreenPosition([1, 4])
46 it "deletes a character", ->
48 expect(editor.getText()).toBe 'abc\n01235\n\nxyz'
49 expect(editor.getCursorScreenPosition()).toEqual [1, 4]
50 expect(vimState.getRegister('"').text).toBe '4'
53 expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
54 expect(editor.getCursorScreenPosition()).toEqual [1, 3]
55 expect(vimState.getRegister('"').text).toBe '5'
58 expect(editor.getText()).toBe 'abc\n012\n\nxyz'
59 expect(editor.getCursorScreenPosition()).toEqual [1, 2]
60 expect(vimState.getRegister('"').text).toBe '3'
63 expect(editor.getText()).toBe 'abc\n01\n\nxyz'
64 expect(editor.getCursorScreenPosition()).toEqual [1, 1]
65 expect(vimState.getRegister('"').text).toBe '2'
68 expect(editor.getText()).toBe 'abc\n0\n\nxyz'
69 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
70 expect(vimState.getRegister('"').text).toBe '1'
73 expect(editor.getText()).toBe 'abc\n\n\nxyz'
74 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
75 expect(vimState.getRegister('"').text).toBe '0'
77 it "deletes multiple characters with a count", ->
80 expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
81 expect(editor.getCursorScreenPosition()).toEqual [1, 3]
82 expect(vimState.getRegister('"').text).toBe '45'
84 editor.setCursorScreenPosition([0, 1])
87 expect(editor.getText()).toBe 'a\n0123\n\nxyz'
88 expect(editor.getCursorScreenPosition()).toEqual [0, 0]
89 expect(vimState.getRegister('"').text).toBe 'bc'
91 describe "with vim-mode.wrapLeftRightMotion", ->
93 editor.setText("abc\n012345\n\nxyz")
94 editor.setCursorScreenPosition([1, 4])
95 atom.config.set('vim-mode.wrapLeftRightMotion', true)
97 it "deletes a character", ->
98 # copy of the earlier test because wrapLeftRightMotion should not affect it
100 expect(editor.getText()).toBe 'abc\n01235\n\nxyz'
101 expect(editor.getCursorScreenPosition()).toEqual [1, 4]
102 expect(vimState.getRegister('"').text).toBe '4'
105 expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
106 expect(editor.getCursorScreenPosition()).toEqual [1, 3]
107 expect(vimState.getRegister('"').text).toBe '5'
110 expect(editor.getText()).toBe 'abc\n012\n\nxyz'
111 expect(editor.getCursorScreenPosition()).toEqual [1, 2]
112 expect(vimState.getRegister('"').text).toBe '3'
115 expect(editor.getText()).toBe 'abc\n01\n\nxyz'
116 expect(editor.getCursorScreenPosition()).toEqual [1, 1]
117 expect(vimState.getRegister('"').text).toBe '2'
120 expect(editor.getText()).toBe 'abc\n0\n\nxyz'
121 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
122 expect(vimState.getRegister('"').text).toBe '1'
125 expect(editor.getText()).toBe 'abc\n\n\nxyz'
126 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
127 expect(vimState.getRegister('"').text).toBe '0'
129 it "deletes multiple characters and newlines with a count", ->
130 atom.config.set('vim-mode.wrapLeftRightMotion', true)
133 expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
134 expect(editor.getCursorScreenPosition()).toEqual [1, 3]
135 expect(vimState.getRegister('"').text).toBe '45'
137 editor.setCursorScreenPosition([0, 1])
140 expect(editor.getText()).toBe 'a0123\n\nxyz'
141 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
142 expect(vimState.getRegister('"').text).toBe 'bc\n'
146 expect(editor.getText()).toBe 'ayz'
147 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
148 expect(vimState.getRegister('"').text).toBe '0123\n\nx'
151 describe "on an empty line", ->
153 editor.setText("abc\n012345\n\nxyz")
154 editor.setCursorScreenPosition([2, 0])
156 it "deletes nothing on an empty line when vim-mode.wrapLeftRightMotion is false", ->
157 atom.config.set('vim-mode.wrapLeftRightMotion', false)
159 expect(editor.getText()).toBe "abc\n012345\n\nxyz"
160 expect(editor.getCursorScreenPosition()).toEqual [2, 0]
162 it "deletes an empty line when vim-mode.wrapLeftRightMotion is true", ->
163 atom.config.set('vim-mode.wrapLeftRightMotion', true)
165 expect(editor.getText()).toBe "abc\n012345\nxyz"
166 expect(editor.getCursorScreenPosition()).toEqual [2, 0]
169 describe "the X keybinding", ->
170 describe "on a line with content", ->
172 editor.setText("ab\n012345")
173 editor.setCursorScreenPosition([1, 2])
175 it "deletes a character", ->
176 keydown('X', shift: true)
177 expect(editor.getText()).toBe 'ab\n02345'
178 expect(editor.getCursorScreenPosition()).toEqual [1, 1]
179 expect(vimState.getRegister('"').text).toBe '1'
181 keydown('X', shift: true)
182 expect(editor.getText()).toBe 'ab\n2345'
183 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
184 expect(vimState.getRegister('"').text).toBe '0'
186 keydown('X', shift: true)
187 expect(editor.getText()).toBe 'ab\n2345'
188 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
189 expect(vimState.getRegister('"').text).toBe '0'
191 atom.config.set('vim-mode.wrapLeftRightMotion', true)
192 keydown('X', shift: true)
193 expect(editor.getText()).toBe 'ab2345'
194 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
195 expect(vimState.getRegister('"').text).toBe '\n'
198 describe "on an empty line", ->
200 editor.setText("012345\n\nabcdef")
201 editor.setCursorScreenPosition([1, 0])
203 it "deletes nothing when vim-mode.wrapLeftRightMotion is false", ->
204 atom.config.set('vim-mode.wrapLeftRightMotion', false)
205 keydown('X', shift: true)
206 expect(editor.getText()).toBe "012345\n\nabcdef"
207 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
209 it "deletes the newline when wrapLeftRightMotion is true", ->
210 atom.config.set('vim-mode.wrapLeftRightMotion', true)
211 keydown('X', shift: true)
212 expect(editor.getText()).toBe "012345\nabcdef"
213 expect(editor.getCursorScreenPosition()).toEqual [0, 5]
215 describe "the s keybinding", ->
217 editor.setText('012345')
218 editor.setCursorScreenPosition([0, 1])
220 it "deletes the character to the right and enters insert mode", ->
222 expect(editorElement.classList.contains('insert-mode')).toBe(true)
223 expect(editor.getText()).toBe '02345'
224 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
225 expect(vimState.getRegister('"').text).toBe '1'
227 it "is repeatable", ->
228 editor.setCursorScreenPosition([0, 0])
231 editor.insertText("ab")
233 expect(editor.getText()).toBe 'ab345'
234 editor.setCursorScreenPosition([0, 2])
236 expect(editor.getText()).toBe 'abab'
239 editor.setCursorScreenPosition([0, 0])
242 editor.insertText("ab")
244 expect(editor.getText()).toBe 'ab345'
246 expect(editor.getText()).toBe '012345'
247 expect(editor.getSelectedText()).toBe ''
249 describe "in visual mode", ->
255 it "deletes the selected characters and enters insert mode", ->
256 expect(editorElement.classList.contains('insert-mode')).toBe(true)
257 expect(editor.getText()).toBe '0345'
258 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
259 expect(vimState.getRegister('"').text).toBe '12'
261 describe "the S keybinding", ->
263 editor.setText("12345\nabcde\nABCDE")
264 editor.setCursorScreenPosition([1, 3])
266 it "deletes the entire line and enters insert mode", ->
267 keydown('S', shift: true)
268 expect(editorElement.classList.contains('insert-mode')).toBe(true)
269 expect(editor.getText()).toBe "12345\n\nABCDE"
270 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
271 expect(vimState.getRegister('"').text).toBe "abcde\n"
272 expect(vimState.getRegister('"').type).toBe 'linewise'
274 it "is repeatable", ->
275 keydown('S', shift: true)
276 editor.insertText("abc")
278 expect(editor.getText()).toBe "12345\nabc\nABCDE"
279 editor.setCursorScreenPosition([2, 3])
281 expect(editor.getText()).toBe "12345\nabc\nabc\n"
284 keydown('S', shift: true)
285 editor.insertText("abc")
287 expect(editor.getText()).toBe "12345\nabc\nABCDE"
289 expect(editor.getText()).toBe "12345\nabcde\nABCDE"
290 expect(editor.getSelectedText()).toBe ''
292 it "works when the cursor's goal column is greater than its current column", ->
293 editor.setText("\n12345")
294 editor.setCursorBufferPosition([1, Infinity])
296 keydown("S", shift: true)
297 expect(editor.getText()).toBe("\n12345")
299 # Can't be tested without setting grammar of test buffer
300 xit "respects indentation", ->
302 describe "the d keybinding", ->
303 it "enters operator-pending mode", ->
305 expect(editorElement.classList.contains('operator-pending-mode')).toBe(true)
306 expect(editorElement.classList.contains('command-mode')).toBe(false)
308 describe "when followed by a d", ->
309 it "deletes the current line and exits operator-pending mode", ->
310 editor.setText("12345\nabcde\n\nABCDE")
311 editor.setCursorScreenPosition([1, 1])
316 expect(editor.getText()).toBe "12345\n\nABCDE"
317 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
318 expect(vimState.getRegister('"').text).toBe "abcde\n"
319 expect(editorElement.classList.contains('operator-pending-mode')).toBe(false)
320 expect(editorElement.classList.contains('command-mode')).toBe(true)
322 it "deletes the last line", ->
323 editor.setText("12345\nabcde\nABCDE")
324 editor.setCursorScreenPosition([2, 1])
329 expect(editor.getText()).toBe "12345\nabcde\n"
330 expect(editor.getCursorScreenPosition()).toEqual [2, 0]
332 it "leaves the cursor on the first nonblank character", ->
333 editor.setText("12345\n abcde\n")
334 editor.setCursorScreenPosition([0, 4])
339 expect(editor.getText()).toBe " abcde\n"
340 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
342 describe "undo behavior", ->
344 editor.setText("12345\nabcde\nABCDE\nQWERT")
345 editor.setCursorScreenPosition([1, 1])
353 it "undoes both lines", ->
354 expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT"
355 expect(editor.getSelectedText()).toBe ''
357 describe "when followed by a w", ->
358 it "deletes the next word until the end of the line and exits operator-pending mode", ->
359 editor.setText("abcd efg\nabc")
360 editor.setCursorScreenPosition([0, 5])
365 # Incompatibility with VIM. In vim, `w` behaves differently as an
366 # operator than as a motion; it stops at the end of a line.expect(editor.getText()).toBe "abcd abc"
367 expect(editor.getText()).toBe "abcd abc"
368 expect(editor.getCursorScreenPosition()).toEqual [0, 5]
370 expect(editorElement.classList.contains('operator-pending-mode')).toBe(false)
371 expect(editorElement.classList.contains('command-mode')).toBe(true)
373 it "deletes to the beginning of the next word", ->
374 editor.setText('abcd efg')
375 editor.setCursorScreenPosition([0, 2])
380 expect(editor.getText()).toBe 'abefg'
381 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
383 editor.setText('one two three four')
384 editor.setCursorScreenPosition([0, 0])
390 expect(editor.getText()).toBe 'four'
391 expect(editor.getCursorScreenPosition()).toEqual [0, 0]
393 describe "when followed by an iw", ->
394 it "deletes the containing word", ->
395 editor.setText("12345 abcde ABCDE")
396 editor.setCursorScreenPosition([0, 9])
399 expect(editorElement.classList.contains('operator-pending-mode')).toBe(true)
403 expect(editor.getText()).toBe "12345 ABCDE"
404 expect(editor.getCursorScreenPosition()).toEqual [0, 6]
405 expect(vimState.getRegister('"').text).toBe "abcde"
406 expect(editorElement.classList.contains('operator-pending-mode')).toBe(false)
407 expect(editorElement.classList.contains('command-mode')).toBe(true)
409 describe "when followed by an j", ->
411 originalText = "12345\nabcde\nABCDE"
412 editor.setText(originalText)
414 describe "on the beginning of the file", ->
415 editor.setCursorScreenPosition([0, 0])
416 it "deletes the next two lines", ->
419 expect(editor.getText()).toBe("ABCDE")
421 describe "on the end of the file", ->
422 editor.setCursorScreenPosition([4, 2])
423 it "deletes nothing", ->
426 expect(editor.getText()).toBe(originalText)
428 describe "on the middle of second line", ->
429 editor.setCursorScreenPosition([2, 1])
430 it "deletes the last two lines", ->
433 expect(editor.getText()).toBe("12345")
435 describe "when followed by an k", ->
437 originalText = "12345\nabcde\nABCDE"
438 editor.setText(originalText)
440 describe "on the end of the file", ->
441 editor.setCursorScreenPosition([4, 2])
442 it "deletes the bottom two lines", ->
445 expect(editor.getText()).toBe("ABCDE")
447 describe "on the beginning of the file", ->
448 editor.setCursorScreenPosition([0, 0])
449 it "deletes nothing", ->
452 expect(editor.getText()).toBe(originalText)
454 describe "when on the middle of second line", ->
455 editor.setCursorScreenPosition([2, 1])
456 it "deletes the first two lines", ->
459 expect(editor.getText()).toBe("12345")
461 describe "when followed by a G", ->
463 originalText = "12345\nabcde\nABCDE"
464 editor.setText(originalText)
466 describe "on the beginning of the second line", ->
467 it "deletes the bottom two lines", ->
468 editor.setCursorScreenPosition([1, 0])
470 keydown('G', shift: true)
471 expect(editor.getText()).toBe("12345\n")
473 describe "on the middle of the second line", ->
474 it "deletes the bottom two lines", ->
475 editor.setCursorScreenPosition([1, 2])
477 keydown('G', shift: true)
478 expect(editor.getText()).toBe("12345\n")
480 describe "when followed by a goto line G", ->
482 originalText = "12345\nabcde\nABCDE"
483 editor.setText(originalText)
485 describe "on the beginning of the second line", ->
486 it "deletes the bottom two lines", ->
487 editor.setCursorScreenPosition([1, 0])
490 keydown('G', shift: true)
491 expect(editor.getText()).toBe("12345\nABCDE")
493 describe "on the middle of the second line", ->
494 it "deletes the bottom two lines", ->
495 editor.setCursorScreenPosition([1, 2])
498 keydown('G', shift: true)
499 expect(editor.getText()).toBe("12345\nABCDE")
501 describe "when followed by a t)", ->
502 describe "with the entire line yanked before", ->
504 editor.setText("test (xyz)")
505 editor.setCursorScreenPosition([0, 6])
507 it "deletes until the closing parenthesis", ->
512 commandModeInputKeydown(')')
513 expect(editor.getText()).toBe("test ()")
514 expect(editor.getCursorScreenPosition()).toEqual [0, 6]
516 describe "with multiple cursors", ->
517 it "deletes each selection", ->
518 editor.setText("abcd\n1234\nABCD\n")
519 editor.setCursorBufferPosition([0, 1])
520 editor.addCursorAtBufferPosition([1, 2])
521 editor.addCursorAtBufferPosition([2, 3])
526 expect(editor.getText()).toBe "a\n12\nABC"
527 expect(editor.getCursorBufferPositions()).toEqual [
533 it "doesn't delete empty selections", ->
534 editor.setText("abcd\nabc\nabd")
535 editor.setCursorBufferPosition([0, 0])
536 editor.addCursorAtBufferPosition([1, 0])
537 editor.addCursorAtBufferPosition([2, 0])
541 commandModeInputKeydown('d')
543 expect(editor.getText()).toBe "d\nabc\nd"
544 expect(editor.getCursorBufferPositions()).toEqual [
550 describe "the D keybinding", ->
552 editor.getBuffer().setText("012\n")
553 editor.setCursorScreenPosition([0, 1])
554 keydown('D', shift: true)
556 it "deletes the contents until the end of the line", ->
557 expect(editor.getText()).toBe "0\n"
559 describe "the c keybinding", ->
561 editor.setText("12345\nabcde\nABCDE")
563 describe "when followed by a c", ->
564 it "deletes the current line and enters insert mode", ->
565 editor.setCursorScreenPosition([1, 1])
570 expect(editor.getText()).toBe "12345\n\nABCDE"
571 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
572 expect(editorElement.classList.contains('command-mode')).toBe(false)
573 expect(editorElement.classList.contains('insert-mode')).toBe(true)
575 describe "when the cursor is on the last line", ->
576 it "deletes the line's content and enters insert mode on the last line", ->
577 editor.setCursorScreenPosition([2, 1])
582 expect(editor.getText()).toBe "12345\nabcde\n\n"
583 expect(editor.getCursorScreenPosition()).toEqual [2, 0]
584 expect(editorElement.classList.contains('command-mode')).toBe(false)
585 expect(editorElement.classList.contains('insert-mode')).toBe(true)
587 describe "when the cursor is on the only line", ->
588 it "deletes the line's content and enters insert mode", ->
589 editor.setText("12345")
590 editor.setCursorScreenPosition([0, 2])
595 expect(editor.getText()).toBe "\n"
596 expect(editor.getCursorScreenPosition()).toEqual [0, 0]
597 expect(editorElement.classList.contains('command-mode')).toBe(false)
598 expect(editorElement.classList.contains('insert-mode')).toBe(true)
600 describe "when followed by i w", ->
601 it "undo's and redo's completely", ->
602 editor.setCursorScreenPosition([1, 1])
607 expect(editor.getText()).toBe "12345\n\nABCDE"
608 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
609 expect(editorElement.classList.contains('insert-mode')).toBe(true)
611 # Just cannot get "typing" to work correctly in test.
612 editor.setText("12345\nfg\nABCDE")
614 expect(editorElement.classList.contains('command-mode')).toBe(true)
615 expect(editor.getText()).toBe "12345\nfg\nABCDE"
618 expect(editor.getText()).toBe "12345\nabcde\nABCDE"
619 keydown('r', ctrl: true)
620 expect(editor.getText()).toBe "12345\nfg\nABCDE"
622 describe "when followed by a w", ->
623 it "changes the word", ->
624 editor.setText("word1 word2 word3")
625 editor.setCursorBufferPosition([0, "word1 w".length])
631 expect(editor.getText()).toBe "word1 w word3"
633 describe "when followed by a G", ->
635 originalText = "12345\nabcde\nABCDE"
636 editor.setText(originalText)
638 describe "on the beginning of the second line", ->
639 it "deletes the bottom two lines", ->
640 editor.setCursorScreenPosition([1, 0])
642 keydown('G', shift: true)
644 expect(editor.getText()).toBe("12345\n\n")
646 describe "on the middle of the second line", ->
647 it "deletes the bottom two lines", ->
648 editor.setCursorScreenPosition([1, 2])
650 keydown('G', shift: true)
652 expect(editor.getText()).toBe("12345\n\n")
654 describe "when followed by a goto line G", ->
656 editor.setText "12345\nabcde\nABCDE"
658 describe "on the beginning of the second line", ->
659 it "deletes all the text on the line", ->
660 editor.setCursorScreenPosition([1, 0])
663 keydown('G', shift: true)
665 expect(editor.getText()).toBe("12345\n\nABCDE")
667 describe "on the middle of the second line", ->
668 it "deletes all the text on the line", ->
669 editor.setCursorScreenPosition([1, 2])
672 keydown('G', shift: true)
674 expect(editor.getText()).toBe("12345\n\nABCDE")
676 describe "the C keybinding", ->
678 editor.getBuffer().setText("012\n")
679 editor.setCursorScreenPosition([0, 1])
680 keydown('C', shift: true)
682 it "deletes the contents until the end of the line and enters insert mode", ->
683 expect(editor.getText()).toBe "0\n"
684 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
685 expect(editorElement.classList.contains('command-mode')).toBe(false)
686 expect(editorElement.classList.contains('insert-mode')).toBe(true)
688 describe "the y keybinding", ->
690 editor.getBuffer().setText("012 345\nabc\n")
691 editor.setCursorScreenPosition([0, 4])
693 describe "when selected lines in visual linewise mode", ->
695 keydown('V', shift: true)
699 it "is in linewise motion", ->
700 expect(vimState.getRegister('"').type).toEqual "linewise"
702 it "saves the lines to the default register", ->
703 expect(vimState.getRegister('"').text).toBe "012 345\nabc\n"
705 it "places the cursor at the beginning of the selection", ->
706 expect(editor.getCursorBufferPositions()).toEqual([[0, 0]])
708 describe "when followed by a second y ", ->
713 it "saves the line to the default register", ->
714 expect(vimState.getRegister('"').text).toBe "012 345\n"
716 it "leaves the cursor at the starting position", ->
717 expect(editor.getCursorScreenPosition()).toEqual [0, 4]
719 describe "when useClipboardAsDefaultRegister enabled", ->
720 it "writes to clipboard", ->
721 atom.config.set 'vim-mode.useClipboardAsDefaultRegister', true
724 expect(atom.clipboard.read()).toBe '012 345\n'
726 describe "when followed with a repeated y", ->
732 it "copies n lines, starting from the current", ->
733 expect(vimState.getRegister('"').text).toBe "012 345\nabc\n"
735 it "leaves the cursor at the starting position", ->
736 expect(editor.getCursorScreenPosition()).toEqual [0, 4]
738 describe "with a register", ->
745 it "saves the line to the a register", ->
746 expect(vimState.getRegister('a').text).toBe "012 345\n"
748 it "appends the line to the A register", ->
750 keydown('A', shift: true)
753 expect(vimState.getRegister('a').text).toBe "012 345\n012 345\n"
755 describe "with a forward motion", ->
760 it "saves the selected text to the default register", ->
761 expect(vimState.getRegister('"').text).toBe '345'
763 it "leaves the cursor at the starting position", ->
764 expect(editor.getCursorScreenPosition()).toEqual [0, 4]
766 it "does not yank when motion fails", ->
769 commandModeInputKeydown('x')
770 expect(vimState.getRegister('"').text).toBe '345'
772 describe "with a text object", ->
773 it "moves the cursor to the beginning of the text object", ->
774 editor.setCursorBufferPosition([0, 5])
778 expect(editor.getCursorBufferPositions()).toEqual([[0, 4]])
780 describe "with a left motion", ->
785 it "saves the left letter to the default register", ->
786 expect(vimState.getRegister('"').text).toBe " "
788 it "moves the cursor position to the left", ->
789 expect(editor.getCursorScreenPosition()).toEqual [0, 3]
791 describe "with a down motion", ->
796 it "saves both full lines to the default register", ->
797 expect(vimState.getRegister('"').text).toBe "012 345\nabc\n"
799 it "leaves the cursor at the starting position", ->
800 expect(editor.getCursorScreenPosition()).toEqual [0, 4]
802 describe "when followed by a G", ->
804 originalText = "12345\nabcde\nABCDE"
805 editor.setText(originalText)
807 describe "on the beginning of the second line", ->
808 it "deletes the bottom two lines", ->
809 editor.setCursorScreenPosition([1, 0])
811 keydown('G', shift: true)
812 keydown('P', shift: true)
813 expect(editor.getText()).toBe("12345\nabcde\nABCDE\nabcde\nABCDE")
815 describe "on the middle of the second line", ->
816 it "deletes the bottom two lines", ->
817 editor.setCursorScreenPosition([1, 2])
819 keydown('G', shift: true)
820 keydown('P', shift: true)
821 expect(editor.getText()).toBe("12345\nabcde\nABCDE\nabcde\nABCDE")
823 describe "when followed by a goto line G", ->
825 originalText = "12345\nabcde\nABCDE"
826 editor.setText(originalText)
828 describe "on the beginning of the second line", ->
829 it "deletes the bottom two lines", ->
830 editor.setCursorScreenPosition([1, 0])
833 keydown('G', shift: true)
834 keydown('P', shift: true)
835 expect(editor.getText()).toBe("12345\nabcde\nabcde\nABCDE")
837 describe "on the middle of the second line", ->
838 it "deletes the bottom two lines", ->
839 editor.setCursorScreenPosition([1, 2])
842 keydown('G', shift: true)
843 keydown('P', shift: true)
844 expect(editor.getText()).toBe("12345\nabcde\nabcde\nABCDE")
846 describe "with multiple cursors", ->
847 it "moves each cursor and copies the last selection's text", ->
848 editor.setText " abcd\n 1234"
849 editor.setCursorBufferPosition([0, 0])
850 editor.addCursorAtBufferPosition([1, 5])
855 expect(vimState.getRegister('"').text).toBe '123'
856 expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 2]]
858 describe "the yy keybinding", ->
859 describe "on a single line file", ->
861 editor.getBuffer().setText "exclamation!\n"
862 editor.setCursorScreenPosition [0, 0]
864 it "copies the entire line and pastes it correctly", ->
869 expect(vimState.getRegister('"').text).toBe "exclamation!\n"
870 expect(editor.getText()).toBe "exclamation!\nexclamation!\n"
872 describe "on a single line file with no newline", ->
874 editor.getBuffer().setText "no newline!"
875 editor.setCursorScreenPosition [0, 0]
877 it "copies the entire line and pastes it correctly", ->
882 expect(vimState.getRegister('"').text).toBe "no newline!\n"
883 expect(editor.getText()).toBe "no newline!\nno newline!"
885 it "copies the entire line and pastes it respecting count and new lines", ->
891 expect(vimState.getRegister('"').text).toBe "no newline!\n"
892 expect(editor.getText()).toBe "no newline!\nno newline!\nno newline!"
894 describe "the Y keybinding", ->
896 editor.getBuffer().setText "012 345\nabc\n"
897 editor.setCursorScreenPosition [0, 4]
899 it "saves the line to the default register", ->
900 keydown('Y', shift: true)
902 expect(vimState.getRegister('"').text).toBe "012 345\n"
903 expect(editor.getCursorScreenPosition()).toEqual [0, 4]
905 describe "the p keybinding", ->
906 describe "with character contents", ->
908 editor.getBuffer().setText "012\n"
909 editor.setCursorScreenPosition [0, 0]
910 vimState.setRegister('"', text: '345')
911 vimState.setRegister('a', text: 'a')
912 atom.clipboard.write "clip"
914 describe "from the default register", ->
915 beforeEach -> keydown('p')
917 it "inserts the contents", ->
918 expect(editor.getText()).toBe "034512\n"
919 expect(editor.getCursorScreenPosition()).toEqual [0, 3]
921 describe "when useClipboardAsDefaultRegister enabled", ->
922 it "inserts contents from clipboard", ->
923 atom.config.set 'vim-mode.useClipboardAsDefaultRegister', true
925 expect(editor.getText()).toBe "0clip12\n"
927 describe "from a specified register", ->
933 it "inserts the contents of the 'a' register", ->
934 expect(editor.getText()).toBe "0a12\n"
935 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
937 describe "at the end of a line", ->
938 it "inserts before the current line's newline", ->
939 editor.setText("abcde\none two three")
940 editor.setCursorScreenPosition([1, 4])
948 expect(editor.getText()).toBe "abcdetwo three\none "
950 describe "with a selection", ->
955 it "replaces the current selection", ->
956 expect(editor.getText()).toBe "34512\n"
957 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
959 describe "with linewise contents", ->
960 describe "on a single line", ->
962 editor.getBuffer().setText("012")
963 editor.setCursorScreenPosition([0, 1])
964 vimState.setRegister('"', text: " 345\n", type: 'linewise')
966 it "inserts the contents of the default register", ->
969 expect(editor.getText()).toBe "012\n 345"
970 expect(editor.getCursorScreenPosition()).toEqual [1, 1]
972 it "replaces the current selection", ->
976 expect(editor.getText()).toBe "0 345\n2"
977 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
979 describe "on multiple lines", ->
981 editor.getBuffer().setText("012\n 345")
982 vimState.setRegister('"', text: " 456\n", type: 'linewise')
984 it "inserts the contents of the default register at middle line", ->
985 editor.setCursorScreenPosition([0, 1])
988 expect(editor.getText()).toBe "012\n 456\n 345"
989 expect(editor.getCursorScreenPosition()).toEqual [1, 1]
991 it "inserts the contents of the default register at end of line", ->
992 editor.setCursorScreenPosition([1, 1])
995 expect(editor.getText()).toBe "012\n 345\n 456"
996 expect(editor.getCursorScreenPosition()).toEqual [2, 1]
998 describe "with multiple linewise contents", ->
1000 editor.getBuffer().setText("012\nabc")
1001 editor.setCursorScreenPosition([1, 0])
1002 vimState.setRegister('"', text: " 345\n 678\n", type: 'linewise')
1005 it "inserts the contents of the default register", ->
1006 expect(editor.getText()).toBe "012\nabc\n 345\n 678"
1007 expect(editor.getCursorScreenPosition()).toEqual [2, 1]
1009 describe "pasting twice", ->
1011 editor.setText("12345\nabcde\nABCDE\nQWERT")
1012 editor.setCursorScreenPosition([1, 1])
1013 vimState.setRegister('"', text: '123')
1017 it "inserts the same line twice", ->
1018 expect(editor.getText()).toBe "12345\nab123123cde\nABCDE\nQWERT"
1020 describe "when undone", ->
1024 it "removes both lines", ->
1025 expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT"
1027 describe "the P keybinding", ->
1028 describe "with character contents", ->
1030 editor.getBuffer().setText("012\n")
1031 editor.setCursorScreenPosition([0, 0])
1032 vimState.setRegister('"', text: '345')
1033 vimState.setRegister('a', text: 'a')
1034 keydown('P', shift: true)
1036 it "inserts the contents of the default register above", ->
1037 expect(editor.getText()).toBe "345012\n"
1038 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1040 describe "the O keybinding", ->
1042 spyOn(editor, 'shouldAutoIndent').andReturn(true)
1043 spyOn(editor, 'autoIndentBufferRow').andCallFake (line) ->
1046 editor.getBuffer().setText(" abc\n 012\n")
1047 editor.setCursorScreenPosition([1, 1])
1049 it "switches to insert and adds a newline above the current one", ->
1050 keydown('O', shift: true)
1051 expect(editor.getText()).toBe " abc\n \n 012\n"
1052 expect(editor.getCursorScreenPosition()).toEqual [1, 2]
1053 expect(editorElement.classList.contains('insert-mode')).toBe(true)
1055 it "is repeatable", ->
1056 editor.getBuffer().setText(" abc\n 012\n 4spaces\n")
1057 editor.setCursorScreenPosition([1, 1])
1058 keydown('O', shift: true)
1059 editor.insertText "def"
1061 expect(editor.getText()).toBe " abc\n def\n 012\n 4spaces\n"
1062 editor.setCursorScreenPosition([1, 1])
1064 expect(editor.getText()).toBe " abc\n def\n def\n 012\n 4spaces\n"
1065 editor.setCursorScreenPosition([4, 1])
1067 expect(editor.getText()).toBe " abc\n def\n def\n 012\n def\n 4spaces\n"
1069 it "is undoable", ->
1070 keydown('O', shift: true)
1071 editor.insertText "def"
1073 expect(editor.getText()).toBe " abc\n def\n 012\n"
1075 expect(editor.getText()).toBe " abc\n 012\n"
1077 describe "the o keybinding", ->
1079 spyOn(editor, 'shouldAutoIndent').andReturn(true)
1080 spyOn(editor, 'autoIndentBufferRow').andCallFake (line) ->
1083 editor.getBuffer().setText("abc\n 012\n")
1084 editor.setCursorScreenPosition([1, 2])
1086 it "switches to insert and adds a newline above the current one", ->
1088 expect(editor.getText()).toBe "abc\n 012\n \n"
1089 expect(editorElement.classList.contains('insert-mode')).toBe(true)
1090 expect(editor.getCursorScreenPosition()).toEqual [2, 2]
1092 # This works in practice, but the editor doesn't respect the indentation
1093 # rules without a syntax grammar. Need to set the editor's grammar
1095 xit "is repeatable", ->
1096 editor.getBuffer().setText(" abc\n 012\n 4spaces\n")
1097 editor.setCursorScreenPosition([1, 1])
1099 editor.insertText "def"
1101 expect(editor.getText()).toBe " abc\n 012\n def\n 4spaces\n"
1103 expect(editor.getText()).toBe " abc\n 012\n def\n def\n 4spaces\n"
1104 editor.setCursorScreenPosition([4, 1])
1106 expect(editor.getText()).toBe " abc\n def\n def\n 012\n 4spaces\n def\n"
1108 it "is undoable", ->
1110 editor.insertText "def"
1112 expect(editor.getText()).toBe "abc\n 012\n def\n"
1114 expect(editor.getText()).toBe "abc\n 012\n"
1116 describe "the a keybinding", ->
1118 editor.getBuffer().setText("012\n")
1120 describe "at the beginning of the line", ->
1122 editor.setCursorScreenPosition([0, 0])
1125 it "switches to insert mode and shifts to the right", ->
1126 expect(editor.getCursorScreenPosition()).toEqual [0, 1]
1127 expect(editorElement.classList.contains('insert-mode')).toBe(true)
1129 describe "at the end of the line", ->
1131 editor.setCursorScreenPosition([0, 3])
1134 it "doesn't linewrap", ->
1135 expect(editor.getCursorScreenPosition()).toEqual [0, 3]
1137 describe "the A keybinding", ->
1139 editor.getBuffer().setText("11\n22\n")
1141 describe "at the beginning of a line", ->
1142 it "switches to insert mode at the end of the line", ->
1143 editor.setCursorScreenPosition([0, 0])
1144 keydown('A', shift: true)
1146 expect(editorElement.classList.contains('insert-mode')).toBe(true)
1147 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1149 it "repeats always as insert at the end of the line", ->
1150 editor.setCursorScreenPosition([0, 0])
1151 keydown('A', shift: true)
1152 editor.insertText("abc")
1154 editor.setCursorScreenPosition([1, 0])
1157 expect(editor.getText()).toBe "11abc\n22abc\n"
1158 expect(editorElement.classList.contains('insert-mode')).toBe(false)
1159 expect(editor.getCursorScreenPosition()).toEqual [1, 4]
1161 describe "the I keybinding", ->
1163 editor.getBuffer().setText("11\n 22\n")
1165 describe "at the end of a line", ->
1166 it "switches to insert mode at the beginning of the line", ->
1167 editor.setCursorScreenPosition([0, 2])
1168 keydown('I', shift: true)
1170 expect(editorElement.classList.contains('insert-mode')).toBe(true)
1171 expect(editor.getCursorScreenPosition()).toEqual [0, 0]
1173 it "switches to insert mode after leading whitespace", ->
1174 editor.setCursorScreenPosition([1, 4])
1175 keydown('I', shift: true)
1177 expect(editorElement.classList.contains('insert-mode')).toBe(true)
1178 expect(editor.getCursorScreenPosition()).toEqual [1, 2]
1180 it "repeats always as insert at the first character of the line", ->
1181 editor.setCursorScreenPosition([0, 2])
1182 keydown('I', shift: true)
1183 editor.insertText("abc")
1185 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1186 editor.setCursorScreenPosition([1, 4])
1189 expect(editor.getText()).toBe "abc11\n abc22\n"
1190 expect(editorElement.classList.contains('insert-mode')).toBe(false)
1191 expect(editor.getCursorScreenPosition()).toEqual [1, 4]
1193 describe "the J keybinding", ->
1195 editor.getBuffer().setText("012\n 456\n")
1196 editor.setCursorScreenPosition([0, 1])
1198 describe "without repeating", ->
1199 beforeEach -> keydown('J', shift: true)
1201 it "joins the contents of the current line with the one below it", ->
1202 expect(editor.getText()).toBe "012 456\n"
1204 describe "with repeating", ->
1206 editor.setText("12345\nabcde\nABCDE\nQWERT")
1207 editor.setCursorScreenPosition([1, 1])
1209 keydown('J', shift: true)
1211 describe "undo behavior", ->
1212 beforeEach -> keydown('u')
1214 it "handles repeats", ->
1215 expect(editor.getText()).toBe "12345\nabcde\nABCDE\nQWERT"
1217 describe "the > keybinding", ->
1219 editor.setText("12345\nabcde\nABCDE")
1221 describe "on the last line", ->
1223 editor.setCursorScreenPosition([2, 0])
1225 describe "when followed by a >", ->
1230 it "indents the current line", ->
1231 expect(editor.getText()).toBe "12345\nabcde\n ABCDE"
1232 expect(editor.getCursorScreenPosition()).toEqual [2, 2]
1234 describe "on the first line", ->
1236 editor.setCursorScreenPosition([0, 0])
1238 describe "when followed by a >", ->
1243 it "indents the current line", ->
1244 expect(editor.getText()).toBe " 12345\nabcde\nABCDE"
1245 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1247 describe "when followed by a repeating >", ->
1253 it "indents multiple lines at once", ->
1254 expect(editor.getText()).toBe " 12345\n abcde\n ABCDE"
1255 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1257 describe "undo behavior", ->
1258 beforeEach -> keydown('u')
1260 it "outdents all three lines", ->
1261 expect(editor.getText()).toBe "12345\nabcde\nABCDE"
1263 describe "in visual mode", ->
1265 editor.setCursorScreenPosition([0, 0])
1266 keydown('v', shift: true)
1269 it "indents the current line and remains in visual mode", ->
1270 expect(editorElement.classList.contains('visual-mode')).toBe(true)
1271 expect(editor.getText()).toBe " 12345\nabcde\nABCDE"
1272 expect(editor.getSelectedText()).toBe " 12345\n"
1274 it "allows repeating the operation", ->
1277 expect(editorElement.classList.contains('command-mode')).toBe(true)
1278 expect(editor.getText()).toBe " 12345\nabcde\nABCDE"
1280 describe "the < keybinding", ->
1282 editor.setText(" 12345\n abcde\nABCDE")
1283 editor.setCursorScreenPosition([0, 0])
1285 describe "when followed by a <", ->
1290 it "indents the current line", ->
1291 expect(editor.getText()).toBe "12345\n abcde\nABCDE"
1292 expect(editor.getCursorScreenPosition()).toEqual [0, 0]
1294 describe "when followed by a repeating <", ->
1300 it "indents multiple lines at once", ->
1301 expect(editor.getText()).toBe "12345\nabcde\nABCDE"
1302 expect(editor.getCursorScreenPosition()).toEqual [0, 0]
1304 describe "undo behavior", ->
1305 beforeEach -> keydown('u')
1307 it "indents both lines", ->
1308 expect(editor.getText()).toBe " 12345\n abcde\nABCDE"
1310 describe "in visual mode", ->
1312 keydown('v', shift: true)
1315 it "indents the current line and remains in visual mode", ->
1316 expect(editorElement.classList.contains('visual-mode')).toBe(true)
1317 expect(editor.getText()).toBe "12345\n abcde\nABCDE"
1318 expect(editor.getSelectedText()).toBe "12345\n"
1320 describe "the = keybinding", ->
1325 atom.packages.activatePackage('language-javascript')
1327 oldGrammar = editor.getGrammar()
1328 editor.setText("foo\n bar\n baz")
1329 editor.setCursorScreenPosition([1, 0])
1331 describe "when used in a scope that supports auto-indent", ->
1333 jsGrammar = atom.grammars.grammarForScopeName('source.js')
1334 editor.setGrammar(jsGrammar)
1337 editor.setGrammar(oldGrammar)
1339 describe "when followed by a =", ->
1344 it "indents the current line", ->
1345 expect(editor.indentationForBufferRow(1)).toBe 0
1347 describe "when followed by a repeating =", ->
1353 it "autoindents multiple lines at once", ->
1354 expect(editor.getText()).toBe "foo\nbar\nbaz"
1355 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
1357 describe "undo behavior", ->
1358 beforeEach -> keydown('u')
1360 it "indents both lines", ->
1361 expect(editor.getText()).toBe "foo\n bar\n baz"
1363 describe "the . keybinding", ->
1365 editor.setText("12\n34\n56\n78")
1366 editor.setCursorScreenPosition([0, 0])
1368 it "repeats the last operation", ->
1374 expect(editor.getText()).toBe ""
1376 it "composes with motions", ->
1382 expect(editor.getText()).toBe "78"
1384 describe "the r keybinding", ->
1386 editor.setText("12\n34\n\n")
1387 editor.setCursorBufferPosition([0, 0])
1388 editor.addCursorAtBufferPosition([1, 0])
1390 it "replaces a single character", ->
1392 commandModeInputKeydown('x')
1393 expect(editor.getText()).toBe 'x2\nx4\n\n'
1395 it "does nothing when cancelled", ->
1397 expect(editorElement.classList.contains('operator-pending-mode')).toBe(true)
1399 expect(editor.getText()).toBe '12\n34\n\n'
1400 expect(editorElement.classList.contains('command-mode')).toBe(true)
1402 it "replaces a single character with a line break", ->
1404 atom.commands.dispatch(editor.commandModeInputView.editorElement, 'core:confirm')
1405 expect(editor.getText()).toBe '\n2\n\n4\n\n'
1406 expect(editor.getCursorBufferPositions()).toEqual [[1, 0], [3, 0]]
1408 it "composes properly with motions", ->
1411 commandModeInputKeydown('x')
1412 expect(editor.getText()).toBe 'xx\nxx\n\n'
1414 it "does nothing on an empty line", ->
1415 editor.setCursorBufferPosition([2, 0])
1417 commandModeInputKeydown('x')
1418 expect(editor.getText()).toBe '12\n34\n\n'
1420 it "does nothing if asked to replace more characters than there are on a line", ->
1423 commandModeInputKeydown('x')
1424 expect(editor.getText()).toBe '12\n34\n\n'
1426 describe "when in visual mode", ->
1431 it "replaces the entire selection with the given character", ->
1433 commandModeInputKeydown('x')
1434 expect(editor.getText()).toBe 'xx\nxx\n\n'
1436 it "leaves the cursor at the beginning of the selection", ->
1438 commandModeInputKeydown('x')
1439 expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 0]]
1441 describe 'the m keybinding', ->
1443 editor.setText('12\n34\n56\n')
1444 editor.setCursorBufferPosition([0, 1])
1446 it 'marks a position', ->
1448 commandModeInputKeydown('a')
1449 expect(vimState.getMark('a')).toEqual [0, 1]
1451 describe 'the ~ keybinding', ->
1453 editor.setText('aBc\nXyZ')
1454 editor.setCursorBufferPosition([0, 0])
1455 editor.addCursorAtBufferPosition([1, 0])
1457 it 'toggles the case and moves right', ->
1459 expect(editor.getText()).toBe 'ABc\nxyZ'
1460 expect(editor.getCursorScreenPositions()).toEqual [[0, 1], [1, 1]]
1463 expect(editor.getText()).toBe 'Abc\nxYZ'
1464 expect(editor.getCursorScreenPositions()).toEqual [[0, 2], [1, 2]]
1467 expect(editor.getText()).toBe 'AbC\nxYz'
1468 expect(editor.getCursorScreenPositions()).toEqual [[0, 2], [1, 2]]
1470 it 'takes a count', ->
1474 expect(editor.getText()).toBe 'AbC\nxYz'
1475 expect(editor.getCursorScreenPositions()).toEqual [[0, 2], [1, 2]]
1477 describe "in visual mode", ->
1478 it "toggles the case of the selected text", ->
1479 editor.setCursorBufferPosition([0, 0])
1480 keydown("V", shift: true)
1482 expect(editor.getText()).toBe 'AbC\nXyZ'
1484 describe "with g and motion", ->
1485 it "toggles the case of text", ->
1486 editor.setCursorBufferPosition([0, 0])
1491 expect(editor.getText()).toBe 'Abc\nXyZ'
1493 describe 'the U keybinding', ->
1495 editor.setText('aBc\nXyZ')
1496 editor.setCursorBufferPosition([0, 0])
1498 it "makes text uppercase with g and motion", ->
1500 keydown("U", shift: true)
1502 expect(editor.getText()).toBe 'ABc\nXyZ'
1505 keydown("U", shift: true)
1507 expect(editor.getText()).toBe 'ABC\nXyZ'
1509 editor.setCursorBufferPosition([1, 0])
1511 keydown("U", shift: true)
1513 expect(editor.getText()).toBe 'ABC\nXYZ'
1514 expect(editor.getCursorScreenPosition()).toEqual [1, 2]
1516 it "makes the selected text uppercase in visual mode", ->
1517 keydown("V", shift: true)
1518 keydown("U", shift: true)
1519 expect(editor.getText()).toBe 'ABC\nXyZ'
1521 describe 'the u keybinding', ->
1523 editor.setText('aBc\nXyZ')
1524 editor.setCursorBufferPosition([0, 0])
1526 it "makes text lowercase with g and motion", ->
1530 expect(editor.getText()).toBe 'abc\nXyZ'
1531 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1533 it "makes the selected text lowercase in visual mode", ->
1534 keydown("V", shift: true)
1536 expect(editor.getText()).toBe 'abc\nXyZ'
1538 describe "the i keybinding", ->
1540 editor.setText('123\n4567')
1541 editor.setCursorBufferPosition([0, 0])
1542 editor.addCursorAtBufferPosition([1, 0])
1544 it "allows undoing an entire batch of typing", ->
1546 editor.insertText("abcXX")
1550 expect(editor.getText()).toBe "abc123\nabc4567"
1553 editor.insertText "d"
1554 editor.insertText "e"
1555 editor.insertText "f"
1557 expect(editor.getText()).toBe "abdefc123\nabdefc4567"
1560 expect(editor.getText()).toBe "abc123\nabc4567"
1563 expect(editor.getText()).toBe "123\n4567"
1565 it "allows repeating typing", ->
1567 editor.insertText("abcXX")
1571 expect(editor.getText()).toBe "abc123\nabc4567"
1574 expect(editor.getText()).toBe "ababcc123\nababcc4567"
1577 expect(editor.getText()).toBe "abababccc123\nabababccc4567"
1579 describe 'with nonlinear input', ->
1582 editor.setCursorBufferPosition [0, 0]
1584 it 'deals with auto-matched brackets', ->
1586 # this sequence simulates what the bracket-matcher package does
1587 # when the user types (a)b<enter>
1588 editor.insertText '()'
1590 editor.insertText 'a'
1592 editor.insertText 'b\n'
1594 expect(editor.getCursorScreenPosition()).toEqual [1, 0]
1597 expect(editor.getText()).toBe '(a)b\n(a)b\n'
1598 expect(editor.getCursorScreenPosition()).toEqual [2, 0]
1600 it 'deals with autocomplete', ->
1602 # this sequence simulates autocompletion of 'add' to 'addFoo'
1603 editor.insertText 'a'
1604 editor.insertText 'd'
1605 editor.insertText 'd'
1606 editor.setTextInBufferRange [[0, 0], [0, 3]], 'addFoo'
1608 expect(editor.getCursorScreenPosition()).toEqual [0, 5]
1609 expect(editor.getText()).toBe 'addFoo'
1612 expect(editor.getText()).toBe 'addFoaddFooo'
1613 expect(editor.getCursorScreenPosition()).toEqual [0, 10]
1615 describe 'the a keybinding', ->
1618 editor.setCursorBufferPosition([0, 0])
1620 it "can be undone in one go", ->
1622 editor.insertText("abc")
1624 expect(editor.getText()).toBe "abc"
1626 expect(editor.getText()).toBe ""
1628 it "repeats correctly", ->
1630 editor.insertText("abc")
1632 expect(editor.getText()).toBe "abc"
1633 expect(editor.getCursorScreenPosition()).toEqual [0, 2]
1635 expect(editor.getText()).toBe "abcabc"
1636 expect(editor.getCursorScreenPosition()).toEqual [0, 5]
1638 describe "the ctrl-a/ctrl-x keybindings", ->
1640 atom.config.set 'vim-mode.numberRegex', settings.config.numberRegex.default
1641 editor.setText('123\nab45\ncd-67ef\nab-5\na-bcdef')
1642 editor.setCursorBufferPosition [0, 0]
1643 editor.addCursorAtBufferPosition [1, 0]
1644 editor.addCursorAtBufferPosition [2, 0]
1645 editor.addCursorAtBufferPosition [3, 3]
1646 editor.addCursorAtBufferPosition [4, 0]
1648 describe "increasing numbers", ->
1649 it "increases the next number", ->
1650 keydown('a', ctrl: true)
1651 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]]
1652 expect(editor.getText()).toBe '124\nab46\ncd-66ef\nab-4\na-bcdef'
1654 it "repeats with .", ->
1655 keydown 'a', ctrl: true
1657 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]]
1658 expect(editor.getText()).toBe '125\nab47\ncd-65ef\nab-3\na-bcdef'
1660 it "can have a count", ->
1662 keydown 'a', ctrl: true
1663 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 2], [4, 0]]
1664 expect(editor.getText()).toBe '128\nab50\ncd-62ef\nab0\na-bcdef'
1666 it "can make a negative number positive, change number of digits", ->
1669 keydown 'a', ctrl: true
1670 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 4], [2, 3], [3, 3], [4, 0]]
1671 expect(editor.getText()).toBe '222\nab144\ncd32ef\nab94\na-bcdef'
1673 it "does nothing when cursor is after the number", ->
1674 editor.setCursorBufferPosition [2, 5]
1675 keydown 'a', ctrl: true
1676 expect(editor.getCursorBufferPositions()).toEqual [[2, 5]]
1677 expect(editor.getText()).toBe '123\nab45\ncd-67ef\nab-5\na-bcdef'
1679 it "does nothing on an empty line", ->
1680 editor.setText('\n')
1681 editor.setCursorBufferPosition [0, 0]
1682 editor.addCursorAtBufferPosition [1, 0]
1683 keydown 'a', ctrl: true
1684 expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 0]]
1685 expect(editor.getText()).toBe '\n'
1687 it "honours the vim-mode:numberRegex setting", ->
1688 editor.setText('123\nab45\ncd -67ef\nab-5\na-bcdef')
1689 editor.setCursorBufferPosition [0, 0]
1690 editor.addCursorAtBufferPosition [1, 0]
1691 editor.addCursorAtBufferPosition [2, 0]
1692 editor.addCursorAtBufferPosition [3, 3]
1693 editor.addCursorAtBufferPosition [4, 0]
1694 atom.config.set('vim-mode.numberRegex', '(?:\\B-)?[0-9]+')
1695 keydown('a', ctrl: true)
1696 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 5], [3, 3], [4, 0]]
1697 expect(editor.getText()).toBe '124\nab46\ncd -66ef\nab-6\na-bcdef'
1699 describe "decreasing numbers", ->
1700 it "decreases the next number", ->
1701 keydown('x', ctrl: true)
1702 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]]
1703 expect(editor.getText()).toBe '122\nab44\ncd-68ef\nab-6\na-bcdef'
1705 it "repeats with .", ->
1706 keydown 'x', ctrl: true
1708 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 3], [4, 0]]
1709 expect(editor.getText()).toBe '121\nab43\ncd-69ef\nab-7\na-bcdef'
1711 it "can have a count", ->
1713 keydown 'x', ctrl: true
1714 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 4], [3, 4], [4, 0]]
1715 expect(editor.getText()).toBe '118\nab40\ncd-72ef\nab-10\na-bcdef'
1717 it "can make a positive number negative, change number of digits", ->
1720 keydown 'x', ctrl: true
1721 expect(editor.getCursorBufferPositions()).toEqual [[0, 1], [1, 4], [2, 5], [3, 5], [4, 0]]
1722 expect(editor.getText()).toBe '24\nab-54\ncd-166ef\nab-104\na-bcdef'
1724 it "does nothing when cursor is after the number", ->
1725 editor.setCursorBufferPosition [2, 5]
1726 keydown 'x', ctrl: true
1727 expect(editor.getCursorBufferPositions()).toEqual [[2, 5]]
1728 expect(editor.getText()).toBe '123\nab45\ncd-67ef\nab-5\na-bcdef'
1730 it "does nothing on an empty line", ->
1731 editor.setText('\n')
1732 editor.setCursorBufferPosition [0, 0]
1733 editor.addCursorAtBufferPosition [1, 0]
1734 keydown 'x', ctrl: true
1735 expect(editor.getCursorBufferPositions()).toEqual [[0, 0], [1, 0]]
1736 expect(editor.getText()).toBe '\n'
1738 it "honours the vim-mode:numberRegex setting", ->
1739 editor.setText('123\nab45\ncd -67ef\nab-5\na-bcdef')
1740 editor.setCursorBufferPosition [0, 0]
1741 editor.addCursorAtBufferPosition [1, 0]
1742 editor.addCursorAtBufferPosition [2, 0]
1743 editor.addCursorAtBufferPosition [3, 3]
1744 editor.addCursorAtBufferPosition [4, 0]
1745 atom.config.set('vim-mode.numberRegex', '(?:\\B-)?[0-9]+')
1746 keydown('x', ctrl: true)
1747 expect(editor.getCursorBufferPositions()).toEqual [[0, 2], [1, 3], [2, 5], [3, 3], [4, 0]]
1748 expect(editor.getText()).toBe '122\nab44\ncd -68ef\nab-4\na-bcdef'