@@ -11,7 +11,7 @@ class MotionError
1111 @name = ' Motion Error'
1212
1313class Motion
14- operatesInclusively : true
14+ operatesInclusively : false
1515 operatesLinewise : false
1616
1717 constructor : (@editor , @vimState ) ->
@@ -20,7 +20,9 @@ class Motion
2020 value = for selection in @editor .getSelections ()
2121 if @ isLinewise ()
2222 @ moveSelectionLinewise (selection, count, options)
23- else if @ isInclusive ()
23+ else if @vimState .mode is ' visual'
24+ @ moveSelectionVisual (selection, count, options)
25+ else if @operatesInclusively
2426 @ moveSelectionInclusively (selection, count, options)
2527 else
2628 @ moveSelection (selection, count, options)
@@ -61,17 +63,35 @@ class Motion
6163 selection .setBufferRange ([[newStartRow, 0 ], [newEndRow + 1 , 0 ]])
6264
6365 moveSelectionInclusively : (selection , count , options ) ->
66+ return @ moveSelectionVisual (selection, count, options) unless selection .isEmpty ()
67+
68+ selection .modifySelection =>
69+ @ moveCursor (selection .cursor , count, options)
70+ return if selection .isEmpty ()
71+
72+ if selection .isReversed ()
73+ # for backward motion, add the original starting character of the motion
74+ {start , end } = selection .getBufferRange ()
75+ selection .setBufferRange ([start, [end .row , end .column + 1 ]])
76+ else
77+ # for forward motion, add the ending character of the motion
78+ selection .cursor .moveRight ()
79+
80+ moveSelectionVisual : (selection , count , options ) ->
6481 selection .modifySelection =>
6582 range = selection .getBufferRange ()
6683 [oldStart , oldEnd ] = [range .start , range .end ]
6784
85+ # in visual mode, atom cursor is after the last selected character,
86+ # so here put cursor in the expected place for the following motion
6887 wasEmpty = selection .isEmpty ()
6988 wasReversed = selection .isReversed ()
7089 unless wasEmpty or wasReversed
7190 selection .cursor .moveLeft ()
7291
7392 @ moveCursor (selection .cursor , count, options)
7493
94+ # put cursor back after the last character so it is also selected
7595 isEmpty = selection .isEmpty ()
7696 isReversed = selection .isReversed ()
7797 unless isEmpty or isReversed
@@ -80,10 +100,15 @@ class Motion
80100 range = selection .getBufferRange ()
81101 [newStart , newEnd ] = [range .start , range .end ]
82102
103+ # if we reversed or emptied a normal selection
104+ # we need to select again the last character deselected above the motion
83105 if (isReversed or isEmpty) and not (wasReversed or wasEmpty)
84106 selection .setBufferRange ([newStart, [newEnd .row , oldStart .column + 1 ]])
107+
108+ # if we re-reversed a reversed non-empty selection,
109+ # we need to keep the last character of the old selection selected
85110 if wasReversed and not wasEmpty and not isReversed
86- selection .setBufferRange ([[newStart .row , oldEnd .column - 1 ], newEnd])
111+ selection .setBufferRange ([[oldEnd .row , oldEnd .column - 1 ], newEnd])
87112
88113 # keep a single-character selection non-reversed
89114 range = selection .getBufferRange ()
@@ -104,9 +129,6 @@ class Motion
104129 else
105130 @operatesLinewise
106131
107- isInclusive : ->
108- @vimState .mode is ' visual' or @operatesInclusively
109-
110132class CurrentSelection extends Motion
111133 constructor : (@editor , @vimState ) ->
112134 super (@editor , @vimState )
@@ -159,15 +181,11 @@ class MotionWithInput extends Motion
159181 @complete = true
160182
161183class MoveLeft extends Motion
162- operatesInclusively : false
163-
164184 moveCursor : (cursor , count = 1 ) ->
165185 _ .times count, ->
166186 cursor .moveLeft () if not cursor .isAtBeginningOfLine () or settings .wrapLeftRightMotion ()
167187
168188class MoveRight extends Motion
169- operatesInclusively : false
170-
171189 moveCursor : (cursor , count = 1 ) ->
172190 _ .times count, =>
173191 wrapToNextLine = settings .wrapLeftRightMotion ()
@@ -196,15 +214,11 @@ class MoveDown extends Motion
196214 cursor .moveDown ()
197215
198216class MoveToPreviousWord extends Motion
199- operatesInclusively : false
200-
201217 moveCursor : (cursor , count = 1 ) ->
202218 _ .times count, ->
203219 cursor .moveToBeginningOfWord ()
204220
205221class MoveToPreviousWholeWord extends Motion
206- operatesInclusively : false
207-
208222 moveCursor : (cursor , count = 1 ) ->
209223 _ .times count, =>
210224 cursor .moveToBeginningOfWord ()
@@ -221,7 +235,6 @@ class MoveToPreviousWholeWord extends Motion
221235
222236class MoveToNextWord extends Motion
223237 wordRegex : null
224- operatesInclusively : false
225238
226239 moveCursor : (cursor , count = 1 , options ) ->
227240 _ .times count, =>
@@ -252,6 +265,7 @@ class MoveToNextWholeWord extends MoveToNextWord
252265 wordRegex : WholeWordOrEmptyLineRegex
253266
254267class MoveToEndOfWord extends Motion
268+ operatesInclusively : true
255269 wordRegex : null
256270
257271 moveCursor : (cursor , count = 1 ) ->
@@ -276,8 +290,6 @@ class MoveToEndOfWholeWord extends MoveToEndOfWord
276290 wordRegex : WholeWordRegex
277291
278292class MoveToNextParagraph extends Motion
279- operatesInclusively : false
280-
281293 moveCursor : (cursor , count = 1 ) ->
282294 _ .times count, ->
283295 cursor .moveToBeginningOfNextParagraph ()
@@ -300,8 +312,6 @@ class MoveToAbsoluteLine extends MoveToLine
300312 cursor .moveToEndOfLine () if cursor .getBufferColumn () is 0
301313
302314class MoveToRelativeLine extends MoveToLine
303- operatesLinewise : true
304-
305315 moveCursor : (cursor , count = 1 ) ->
306316 {row , column } = cursor .getBufferPosition ()
307317 cursor .setBufferPosition ([row + (count - 1 ), 0 ])
@@ -316,23 +326,18 @@ class MoveToScreenLine extends MoveToLine
316326 cursor .setScreenPosition ([@ getDestinationRow (count), 0 ])
317327
318328class MoveToBeginningOfLine extends Motion
319- operatesInclusively : false
320-
321329 moveCursor : (cursor , count = 1 ) ->
322330 _ .times count, ->
323331 cursor .moveToBeginningOfLine ()
324332
325333class MoveToFirstCharacterOfLine extends Motion
326- operatesInclusively : false
327-
328334 moveCursor : (cursor , count = 1 ) ->
329335 _ .times count, ->
330336 cursor .moveToBeginningOfLine ()
331337 cursor .moveToFirstCharacterOfLine ()
332338
333339class MoveToFirstCharacterOfLineAndDown extends Motion
334340 operatesLinewise : true
335- operatesInclusively : true
336341
337342 moveCursor : (cursor , count = 0 ) ->
338343 _ .times count- 1 , ->
@@ -341,8 +346,6 @@ class MoveToFirstCharacterOfLineAndDown extends Motion
341346 cursor .moveToFirstCharacterOfLine ()
342347
343348class MoveToLastCharacterOfLine extends Motion
344- operatesInclusively : false
345-
346349 moveCursor : (cursor , count = 1 ) ->
347350 _ .times count, ->
348351 cursor .moveToEndOfLine ()
@@ -369,7 +372,6 @@ class MoveToLastNonblankCharacterOfLineAndDown extends Motion
369372
370373class MoveToFirstCharacterOfLineUp extends Motion
371374 operatesLinewise : true
372- operatesInclusively : true
373375
374376 moveCursor : (cursor , count = 1 ) ->
375377 _ .times count, ->
0 commit comments