         @editor.getSelections().some (selection) ->
           not swrap(selection).isSingleRow()
 
+  isMovable: (selection) ->
+    switch @direction
+      when 'down', 'right'
+        true
+      when 'up'
+        selection.getBufferRange().start.row isnt 0
+      when 'left'
+        if @isLinewise()
+          true
+        else
+          selection.getBufferRange().start.column isnt 0
+
+  rotateTexts: (selection) ->
+    reversed = selection.isReversed()
+    # Pre mutate
+    translation = switch @direction
+      when 'up' then [[-1, 0], [0, 0]]
+      when 'down' then [[0, 0], [1, 0]]
+      when 'right' then [[0, 0], [0, +1]]
+      when 'left' then [[0, -1], [0, 0]]
+
+    swrap(selection).translate(translation...)
+    range = selection.insertText(@getNewText(selection))
+
+    # Post mutate
+    range = range.translate(translation.reverse()...)
+    selection.setBufferRange(range, {reversed})
+
+  getNewText: (selection) ->
+    # 'up', 'down': rotate row
+    # 'right', 'left': rotate column
+    switch @direction
+      when 'up'
+        [overwritten, rest...] = swrap(selection).lineTextForBufferRows()
+        overwritten = @getOverwrittenForSelection(selection, overwritten) if @isOverwrite()
+        [rest..., overwritten].join("\n") + "\n"
+      when 'down'
+        [rest..., overwritten] = swrap(selection).lineTextForBufferRows()
+        overwritten = @getOverwrittenForSelection(selection, overwritten) if @isOverwrite()
+        [overwritten, rest...].join("\n") + "\n"
+      when 'right' # rotate column
+        [rest..., overwritten] = selection.getText()
+        overwritten = @getOverwrittenForSelection(selection, overwritten) if @isOverwrite()
+        [overwritten, rest...].join('')
+      when 'left' # rotate column
+        [overwritten, rest...] = selection.getText()
+        overwritten = @getOverwrittenForSelection(selection, overwritten) if @isOverwrite()
+        [rest..., overwritten].join('')
+
+
+
 class MoveSelectedTextUp extends MoveSelectedText
   direction: 'up'
   flashTarget: false
 
   mutate: (selection) ->
+    @extendMovingArea(selection)
     if @isLinewise()
       if @vimState.submode is 'linewise'
-        @moveLinewise(selection)
+        @rotateTexts(selection)
       else
         swrap(selection).switchToLinewise =>
-          @moveLinewise(selection)
+          @rotateTexts(selection)
+      @editor.scrollToCursorPosition({center: true})
     else
       @moveCharacterwise(selection)
 

    isSequential = state.selectedTexts is @getSelectedTexts()
    unless isSequential
      state.checkpoint = @editor.createCheckpoint()
      state.overwritten = null

    unless state.overwrittenBySelection?
      state.overwrittenBySelection = @getOverwrittenBySelection()


  mutate: (selection) ->
    if @isLinewise()
      switch @direction
        when 'right' then selection.indentSelectedRows()
        when 'left' then selection.outdentSelectedRows()
    else
      if @direction is 'right'
        # complement space if EOL
        point = selection.getBufferRange().end
        if pointIsAtEndOfLine(@editor, point)
          @editor.setTextInBufferRange([point, point], " ")

      @rotateTexts(selection)
      @editor.scrollToCursorPosition({center: true})

class MoveSelectedTextLeft extends MoveSelectedTextRight
  direction: 'left'
