vimState: null
motion: null
complete: null
- selectOptions: null
- # selectOptions - The options object to pass through to the motion when
- # selecting.
- constructor: (@editor, @vimState, {@selectOptions}={}) ->
+ constructor: (@editor, @vimState) ->
@complete = false
# Public: Determines when the command can be executed.
#
class Delete extends Operator
register: null
- allowEOL: null
- # allowEOL - Determines whether the cursor should be allowed to rest on the
- # end of line character or not.
- constructor: (@editor, @vimState, {@allowEOL, @selectOptions}={}) ->
+ constructor: (@editor, @vimState) ->
@complete = false
- @selectOptions ?= {}
- @selectOptions.requireEOL ?= true
@register = settings.defaultRegister()
# Public: Deletes the text selected by the given motion.
#
# Returns nothing.
execute: (count) ->
- if _.contains(@motion.select(count, @selectOptions), true)
+ if _.contains(@motion.select(count), true)
@setTextRegister(@register, @editor.getSelectedText())
- for selection in @editor.getSelections()
- selection.deleteSelectedText()
+ @editor.transact =>
+ for selection in @editor.getSelections()
+ selection.deleteSelectedText()
for cursor in @editor.getCursors()
if @motion.isLinewise?()
cursor.skipLeadingWhitespace()
else
cursor.moveLeft() if cursor.isAtEndOfLine() and not cursor.isAtBeginningOfLine()
- @vimState.activateCommandMode()
+ @vimState.activateNormalMode()
#
# It toggles the case of everything selected by the following motion
#
class ToggleCase extends Operator
- constructor: (@editor, @vimState, {@complete, @selectOptions}={}) ->
+ constructor: (@editor, @vimState, {@complete}={}) ->
- execute: (count=1) ->
+ execute: (count) ->
if @motion?
- if _.contains(@motion.select(count, @selectOptions), true)
+ if _.contains(@motion.select(count), true)
@editor.replaceSelectedText {}, (text) ->
text.split('').map((char) ->
lower = char.toLowerCase()
for cursor in @editor.getCursors()
point = cursor.getBufferPosition()
lineLength = @editor.lineTextForBufferRow(point.row).length
- cursorCount = Math.min(count, lineLength - point.column)
+ cursorCount = Math.min(count ? 1, lineLength - point.column)
_.times cursorCount, =>
point = cursor.getBufferPosition()
cursor.moveRight() unless point.column >= lineLength - 1
- @vimState.activateCommandMode()
+ @vimState.activateNormalMode()
#
# In visual mode or after `g` with a motion, it makes the selection uppercase
#
class UpperCase extends Operator
- constructor: (@editor, @vimState, {@selectOptions}={}) ->
+ constructor: (@editor, @vimState) ->
@complete = false
- execute: (count=1) ->
- if _.contains(@motion.select(count, @selectOptions), true)
+ execute: (count) ->
+ if _.contains(@motion.select(count), true)
@editor.replaceSelectedText {}, (text) ->
text.toUpperCase()
- @vimState.activateCommandMode()
+ @vimState.activateNormalMode()
#
# In visual mode or after `g` with a motion, it makes the selection lowercase
#
class LowerCase extends Operator
- constructor: (@editor, @vimState, {@selectOptions}={}) ->
+ constructor: (@editor, @vimState) ->
@complete = false
- execute: (count=1) ->
- if _.contains(@motion.select(count, @selectOptions), true)
+ execute: (count) ->
+ if _.contains(@motion.select(count), true)
@editor.replaceSelectedText {}, (text) ->
text.toLowerCase()
- @vimState.activateCommandMode()
+ @vimState.activateNormalMode()
#
# It copies everything selected by the following motion.
class Yank extends Operator
register: null
- constructor: (@editor, @vimState, {@allowEOL, @selectOptions}={}) ->
+ constructor: (@editor, @vimState) ->
@register = settings.defaultRegister()
# Public: Copies the text selected by the given motion.
#
# Returns nothing.
execute: (count) ->
+ oldTop = @editor.getScrollTop()
+ oldLeft = @editor.getScrollLeft()
+ oldLastCursorPosition = @editor.getCursorBufferPosition()
+
originalPositions = @editor.getCursorBufferPositions()
if _.contains(@motion.select(count), true)
text = @editor.getSelectedText()
startPositions = _.pluck(@editor.getSelectedBufferRanges(), "start")
newPositions = for originalPosition, i in originalPositions
- if startPositions[i] and (@vimState.mode is 'visual' or not @motion.isLinewise?())
- Point.min(startPositions[i], originalPositions[i])
+ if startPositions[i]
+ position = Point.min(startPositions[i], originalPositions[i])
+ if @vimState.mode isnt 'visual' and @motion.isLinewise?()
+ position = new Point(position.row, originalPositions[i].column)
+ position
else
originalPosition
else
@setTextRegister(@register, text)
@editor.setSelectedBufferRanges(newPositions.map (p) -> new Range(p, p))
- @vimState.activateCommandMode()
+
+ if oldLastCursorPosition.isEqual(@editor.getCursorBufferPosition())
+ @editor.setScrollLeft(oldLeft)
+ @editor.setScrollTop(oldTop)
+
+ @vimState.activateNormalMode()
#
# It combines the current line with the following line.
#
class Join extends Operator
- constructor: (@editor, @vimState, {@selectOptions}={}) -> @complete = true
+ constructor: (@editor, @vimState) -> @complete = true
# Public: Combines the current with the following lines
#
@editor.transact =>
_.times count, =>
@editor.joinLines()
- @vimState.activateCommandMode()
+ @vimState.activateNormalMode()
#
# Repeat the last operation
#
class Repeat extends Operator
- constructor: (@editor, @vimState, {@selectOptions}={}) -> @complete = true
+ constructor: (@editor, @vimState) -> @complete = true
isRecordable: -> false
# It creates a mark at the current cursor position
#
class Mark extends OperatorWithInput
- constructor: (@editor, @vimState, {@selectOptions}={}) ->
+ constructor: (@editor, @vimState) ->
super(@editor, @vimState)
@viewModel = new ViewModel(this, class: 'mark', singleChar: true, hidden: true)
# Returns nothing.
execute: ->
@vimState.setMark(@input.characters, @editor.getCursorBufferPosition())
- @vimState.activateCommandMode()
+ @vimState.activateNormalMode()
module.exports = {
Operator, OperatorWithInput, OperatorError, Delete, ToggleCase,