               newText = selection.getText().repeat(@getCount())
               width = newText.length
               {start, end} = selection.getBufferRange()
-              switch @direction
+              range = switch @direction
                 when 'left'
-                  range = if @isOverwrite()
+                  if @isOverwrite()
                     [start.translate([0, -width]), start]
                   else
                     [start, start]
-                  range = @editor.setTextInBufferRange(range, newText)
-                  selection.setBufferRange(range)
-
                 when 'right'
-                  range = if @isOverwrite()
+                  if @isOverwrite()
                     [end, end.translate([0, +width])]
                   else
                     [end, end]
-                  range = @editor.setTextInBufferRange(range, newText)
-                  selection.setBufferRange(range)
+              @setTextInRangeAndSelect(range, newText, selection)
 
           when 'up', 'down'
             getBaseTexts = (blockwiseSelection) ->

  flashTarget: false

  moveLinewise: (selection) ->
    # console.log @direction, "HELLO"
    switch @direction
      when 'right' then selection.indentSelectedRows()
      when 'left' then selection.outdentSelectedRows()

        when 'up', 'down' then _.flatten([1..count].map -> rows)
        when 'left', 'right' then rows.map (text) -> text.repeat(count+1)

    reversed = selection.isReversed()
    lineTexts = duplicateText(selection, @direction, @getCount())
    newText = lineTexts.join("\n") + "\n"

    switch @direction
      when 'up', 'down'
        if @isOverwrite()
          [startRow, endRow] = selection.getBufferRowRange()
          height = lineTexts.length
          range = switch @direction
            when 'up' then [[startRow - height, 0], [startRow, 0]]
            when 'down' then [[endRow + 1, 0], [endRow + 1 + height, 0]]
          @setTextInRangeAndSelect(range, newText, selection)
        else
          point = switch @direction
            when 'up' then selection.getBufferRange().start
            when 'down' then selection.getBufferRange().end
          @setTextInRangeAndSelect([point, point], newText, selection)
      when 'left', 'right'
        range = selection.insertText(newText)
        selection.setBufferRange(range, {reversed})

class DuplicateSelectedTextUp extends DuplicateSelectedText
  direction: 'up'
