             @extendMovingArea(selection)
             @mutate(selection) if @isMovable(selection)
 
-  initOverwrittenByEditor: ->
-    unless overwrittenByEditor.has(@editor)
+  initOverwrittenArea: ->
+    state = stateByEditor.get(@editor)
+    unless state.overwritten?
       if @isLinewise()
         overwrittenArea = @editor.getSelections().map (selection) ->
           _.multiplyString("\n", swrap(selection).getRowCount()-1)
       else
         overwrittenArea = @editor.getSelections().map (selection) ->
           _.multiplyString(' ', selection.getBufferRange().getExtent().column)
-      overwrittenByEditor.set(@editor, overwrittenArea)
+      state.overwritten = overwrittenArea
 
   getSelectedTexts: ->
     @editor.getSelections().map((selection) -> selection.getText()).join("\n")

    atom.config.get('vim-mode-plus-move-selected-text.overwrite')

  withUndoJoin: (fn) ->
    unless disposableByEditor.has(@editor)
      disposable = @vimState.modeManager.onDidDeactivateMode ({mode}) ->
        if mode is 'visual'
          stateByEditor.delete(@editor)
          overwrittenByEditor.delete(@editor)

      disposableByEditor.set @editor, @editor.onDidDestroy =>
        checkPointByEditor.delete(@editor)
        stateByEditor.delete(@editor)
        disposableByEditor.delete(@editor)
        overwrittenByEditor.delete(@editor)
        disposable.dispose()

    isSequential = stateByEditor.get(@editor) is @getSelectedTexts()
    unless isSequential
      checkPointByEditor.set(@editor, @editor.createCheckpoint())
      overwrittenByEditor.delete(@editor)
    fn()

    stateByEditor.set(@editor, @getSelectedTexts())
    if isSequential and (checkpoint = checkPointByEditor.get(@editor))
      @editor.groupChangesSinceCheckpoint(checkpoint)

  getOverwrittenText: (replacedText) ->
    overwrittenArea = overwrittenByEditor.get(@editor)[@selectionIndex]
    replacedText = switch @direction
      when 'up'
        [overwritten, rest...] = overwrittenArea.split("\n")

swrap = requireFrom('vim-mode-plus', 'selection-wrapper')

CommandPrefix = 'vim-mode-plus-user'

newState = ->
  {
    selectedTexts: null
    checkpoint: null
    overwritten: null
  }

stateByEditor = new Map
disposableByEditor = new Map

# -------------------------
class MoveSelectedText extends TransformString
