       when 'linewise' then swrap(s).expandOverLine() for s in selections
       when 'blockwise' then @vimState.operationStack.push new BlockwiseSelect(@vimState)
 
-  deactivateVisualMode: ->
-    @restoreCharacterwiseRange()
-    for s in @editor.getSelections()
-      swrap(s).resetProperties()
-      s.cursor.moveLeft() unless (s.isEmpty() or s.isReversed())
-      s.clear(autoscroll: false)
+    new Disposable =>
+      @restoreCharacterwiseRange()
+      for s in @editor.getSelections()
+        swrap(s).resetProperties()
+        s.cursor.moveLeft() unless (s.isEmpty() or s.isReversed())
+        s.clear(autoscroll: false)
 
   restoreCharacterwiseRange: ->
     switch @submode


  setInsertionCheckpoint: ->
    @insertionCheckpoint ?= @editor.createCheckpoint()

  # Visual
  # -------------------------

  activateNormalMode: ->
    @vimState.reset()
    @editorElement.component.setInputEnabled(false)
    new Disposable

  # Insert
  # -------------------------
  activateInsertMode: (submode=null) ->
    @editorElement.component.setInputEnabled(true)
    @setInsertionCheckpoint()
    replaceModeDeactivator = @activateReplaceMode() if (submode is 'replace')

    new Disposable =>
      checkpoint = @getInsertionCheckpoint()
      @editor.groupChangesSinceCheckpoint(checkpoint)
      changes = getChangesSinceCheckpoint(@editor.buffer, checkpoint)
      @resetInsertionCheckpoint()
      if (item = @vimState.getLastOperation()) and item.isInsert()
        item.confirmChanges(changes)

      replaceModeDeactivator?.dispose()
      replaceModeDeactivator = null

      # Adjust cursor position
      for c in @editor.getCursors() when not c.isAtBeginningOfLine()
        c.moveLeft()

  activateReplaceMode: ->
    @replacedCharsBySelection = {}
    subs = new CompositeDisposable
    subs.add @editor.onWillInsertText ({text, cancel}) =>
      cancel()
      for s in @editor.getSelections()
        for char in text.split('') ? []
