Skip to content
This repository was archived by the owner on Apr 6, 2018. It is now read-only.

Commit 71be7b0

Browse files
author
Max Brunsfeld
committed
Merge pull request #555 from jacekkopecky/fix-wrapping-of-x
fix wrapping behavior of x
2 parents 14e183e + 3573c64 commit 71be7b0

File tree

4 files changed

+155
-32
lines changed

4 files changed

+155
-32
lines changed

lib/motions/general-motions.coffee

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,14 @@ class MoveRight extends Motion
151151

152152
moveCursor: (cursor, count=1) ->
153153
_.times count, =>
154+
wrapToNextLine = settings.wrapLeftRightMotion()
155+
156+
# when the motion is combined with an operator, we will only wrap to the next line
157+
# if we are already at the end of the line (after the last character)
158+
wrapToNextLine = false if @vimState.mode is 'operator-pending' and not cursor.isAtEndOfLine()
159+
154160
cursor.moveRight() unless cursor.isAtEndOfLine()
155-
cursor.moveRight() if settings.wrapLeftRightMotion() and cursor.isAtEndOfLine()
161+
cursor.moveRight() if wrapToNextLine and cursor.isAtEndOfLine()
156162
@ensureCursorIsWithinLine(cursor)
157163

158164
class MoveUp extends Motion

lib/operators/general-operators.coffee

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class Delete extends Operator
100100
if @motion.isLinewise?()
101101
cursor.moveToBeginningOfLine()
102102
else
103-
cursor.moveLeft() if cursor.isAtEndOfLine()
103+
cursor.moveLeft() if cursor.isAtEndOfLine() and not cursor.isAtBeginningOfLine()
104104

105105
@vimState.activateCommandMode()
106106

lib/vim-state.coffee

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ class VimState
377377

378378
@clearOpStack()
379379
selection.clear(autoscroll: false) for selection in @editor.getSelections()
380+
for cursor in @editor.getCursors()
381+
if cursor.isAtEndOfLine() and not cursor.isAtBeginningOfLine()
382+
cursor.moveLeft()
380383

381384
@updateStatusBar()
382385

spec/operators-spec.coffee

Lines changed: 144 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,65 +37,179 @@ describe "Operators", ->
3737

3838
describe "the x keybinding", ->
3939
describe "on a line with content", ->
40-
beforeEach ->
41-
editor.setText("012345")
42-
editor.setCursorScreenPosition([0, 4])
40+
describe "without vim-mode.wrapLeftRightMotion", ->
41+
beforeEach ->
42+
editor.setText("abc\n012345\n\nxyz")
43+
editor.setCursorScreenPosition([1, 4])
4344

44-
it "deletes a character", ->
45-
keydown('x')
46-
expect(editor.getText()).toBe '01235'
47-
expect(editor.getCursorScreenPosition()).toEqual [0, 4]
48-
expect(vimState.getRegister('"').text).toBe '4'
45+
it "deletes a character", ->
46+
keydown('x')
47+
expect(editor.getText()).toBe 'abc\n01235\n\nxyz'
48+
expect(editor.getCursorScreenPosition()).toEqual [1, 4]
49+
expect(vimState.getRegister('"').text).toBe '4'
4950

50-
keydown('x')
51-
expect(editor.getText()).toBe '0123'
52-
expect(editor.getCursorScreenPosition()).toEqual [0, 3]
53-
expect(vimState.getRegister('"').text).toBe '5'
51+
keydown('x')
52+
expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
53+
expect(editor.getCursorScreenPosition()).toEqual [1, 3]
54+
expect(vimState.getRegister('"').text).toBe '5'
55+
56+
keydown('x')
57+
expect(editor.getText()).toBe 'abc\n012\n\nxyz'
58+
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
59+
expect(vimState.getRegister('"').text).toBe '3'
60+
61+
keydown('x')
62+
expect(editor.getText()).toBe 'abc\n01\n\nxyz'
63+
expect(editor.getCursorScreenPosition()).toEqual [1, 1]
64+
expect(vimState.getRegister('"').text).toBe '2'
65+
66+
keydown('x')
67+
expect(editor.getText()).toBe 'abc\n0\n\nxyz'
68+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
69+
expect(vimState.getRegister('"').text).toBe '1'
70+
71+
keydown('x')
72+
expect(editor.getText()).toBe 'abc\n\n\nxyz'
73+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
74+
expect(vimState.getRegister('"').text).toBe '0'
75+
76+
it "deletes multiple characters with a count", ->
77+
keydown('2')
78+
keydown('x')
79+
expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
80+
expect(editor.getCursorScreenPosition()).toEqual [1, 3]
81+
expect(vimState.getRegister('"').text).toBe '45'
82+
83+
editor.setCursorScreenPosition([0, 1])
84+
keydown('3')
85+
keydown('x')
86+
expect(editor.getText()).toBe 'a\n0123\n\nxyz'
87+
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
88+
expect(vimState.getRegister('"').text).toBe 'bc'
89+
90+
describe "with vim-mode.wrapLeftRightMotion", ->
91+
beforeEach ->
92+
editor.setText("abc\n012345\n\nxyz")
93+
editor.setCursorScreenPosition([1, 4])
94+
atom.config.set('vim-mode.wrapLeftRightMotion', true)
95+
96+
it "deletes a character", ->
97+
# copy of the earlier test because wrapLeftRightMotion should not affect it
98+
keydown('x')
99+
expect(editor.getText()).toBe 'abc\n01235\n\nxyz'
100+
expect(editor.getCursorScreenPosition()).toEqual [1, 4]
101+
expect(vimState.getRegister('"').text).toBe '4'
102+
103+
keydown('x')
104+
expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
105+
expect(editor.getCursorScreenPosition()).toEqual [1, 3]
106+
expect(vimState.getRegister('"').text).toBe '5'
107+
108+
keydown('x')
109+
expect(editor.getText()).toBe 'abc\n012\n\nxyz'
110+
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
111+
expect(vimState.getRegister('"').text).toBe '3'
112+
113+
keydown('x')
114+
expect(editor.getText()).toBe 'abc\n01\n\nxyz'
115+
expect(editor.getCursorScreenPosition()).toEqual [1, 1]
116+
expect(vimState.getRegister('"').text).toBe '2'
117+
118+
keydown('x')
119+
expect(editor.getText()).toBe 'abc\n0\n\nxyz'
120+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
121+
expect(vimState.getRegister('"').text).toBe '1'
122+
123+
keydown('x')
124+
expect(editor.getText()).toBe 'abc\n\n\nxyz'
125+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
126+
expect(vimState.getRegister('"').text).toBe '0'
127+
128+
it "deletes multiple characters and newlines with a count", ->
129+
atom.config.set('vim-mode.wrapLeftRightMotion', true)
130+
keydown('2')
131+
keydown('x')
132+
expect(editor.getText()).toBe 'abc\n0123\n\nxyz'
133+
expect(editor.getCursorScreenPosition()).toEqual [1, 3]
134+
expect(vimState.getRegister('"').text).toBe '45'
135+
136+
editor.setCursorScreenPosition([0, 1])
137+
keydown('3')
138+
keydown('x')
139+
expect(editor.getText()).toBe 'a0123\n\nxyz'
140+
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
141+
expect(vimState.getRegister('"').text).toBe 'bc\n'
142+
143+
keydown('7')
144+
keydown('x')
145+
expect(editor.getText()).toBe 'ayz'
146+
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
147+
expect(vimState.getRegister('"').text).toBe '0123\n\nx'
54148

55-
keydown('x')
56-
expect(editor.getText()).toBe '012'
57-
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
58-
expect(vimState.getRegister('"').text).toBe '3'
59149

60150
describe "on an empty line", ->
61151
beforeEach ->
62-
editor.setText("012345\n\nabcdef")
63-
editor.setCursorScreenPosition([1, 0])
152+
editor.setText("abc\n012345\n\nxyz")
153+
editor.setCursorScreenPosition([2, 0])
154+
155+
it "deletes nothing on an empty line when vim-mode.wrapLeftRightMotion is false", ->
156+
atom.config.set('vim-mode.wrapLeftRightMotion', false)
157+
keydown('x')
158+
expect(editor.getText()).toBe "abc\n012345\n\nxyz"
159+
expect(editor.getCursorScreenPosition()).toEqual [2, 0]
160+
161+
it "deletes an empty line when vim-mode.wrapLeftRightMotion is true", ->
162+
atom.config.set('vim-mode.wrapLeftRightMotion', true)
64163
keydown('x')
164+
expect(editor.getText()).toBe "abc\n012345\nxyz"
165+
expect(editor.getCursorScreenPosition()).toEqual [2, 0]
65166

66-
it "deletes nothing when cursor is on empty line", ->
67-
expect(editor.getText()).toBe "012345\n\nabcdef"
68167

69168
describe "the X keybinding", ->
70169
describe "on a line with content", ->
71170
beforeEach ->
72-
editor.setText("012345")
73-
editor.setCursorScreenPosition([0, 2])
171+
editor.setText("ab\n012345")
172+
editor.setCursorScreenPosition([1, 2])
74173

75174
it "deletes a character", ->
76175
keydown('X', shift: true)
77-
expect(editor.getText()).toBe '02345'
78-
expect(editor.getCursorScreenPosition()).toEqual [0, 1]
176+
expect(editor.getText()).toBe 'ab\n02345'
177+
expect(editor.getCursorScreenPosition()).toEqual [1, 1]
79178
expect(vimState.getRegister('"').text).toBe '1'
80179

81180
keydown('X', shift: true)
82-
expect(editor.getText()).toBe '2345'
83-
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
181+
expect(editor.getText()).toBe 'ab\n2345'
182+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
84183
expect(vimState.getRegister('"').text).toBe '0'
85184

86185
keydown('X', shift: true)
87-
expect(editor.getText()).toBe '2345'
88-
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
186+
expect(editor.getText()).toBe 'ab\n2345'
187+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
89188
expect(vimState.getRegister('"').text).toBe '0'
90189

190+
atom.config.set('vim-mode.wrapLeftRightMotion', true)
191+
keydown('X', shift: true)
192+
expect(editor.getText()).toBe 'ab2345'
193+
expect(editor.getCursorScreenPosition()).toEqual [0, 2]
194+
expect(vimState.getRegister('"').text).toBe '\n'
195+
196+
91197
describe "on an empty line", ->
92198
beforeEach ->
93199
editor.setText("012345\n\nabcdef")
94200
editor.setCursorScreenPosition([1, 0])
95-
keydown('X', shift: true)
96201

97-
it "deletes nothing when cursor is on empty line", ->
202+
it "deletes nothing when vim-mode.wrapLeftRightMotion is false", ->
203+
atom.config.set('vim-mode.wrapLeftRightMotion', false)
204+
keydown('X', shift: true)
98205
expect(editor.getText()).toBe "012345\n\nabcdef"
206+
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
207+
208+
it "deletes the newline when wrapLeftRightMotion is true", ->
209+
atom.config.set('vim-mode.wrapLeftRightMotion', true)
210+
keydown('X', shift: true)
211+
expect(editor.getText()).toBe "012345\nabcdef"
212+
expect(editor.getCursorScreenPosition()).toEqual [0, 5]
99213

100214
describe "the s keybinding", ->
101215
beforeEach ->

0 commit comments

Comments
 (0)