         @editor.getSelections().some (selection) ->
           not swrap(selection).isSingleRow()
 
-  duplicateText: (selection) ->
+  duplicateText: (selection, count) ->
     if @isLinewise()
+      rows = swrap(selection).lineTextForBufferRows()
       switch @direction
-        when 'up', 'down'
-          rows = swrap(selection).lineTextForBufferRows()
-          lineTexts = []
-          @countTimes =>
-            lineTexts.push(rows...)
-          lineTexts
-          # console.log inspect(lineTexts)
-        when 'left', 'right'
-          count = @getCount()
-          rows = swrap(selection).lineTextForBufferRows()
-          lineTexts = rows.map (text) ->
-            _.multiplyString(text, count+1)
-          lineTexts
+        when 'up', 'down' then _.flatten([1..count].map -> rows)
+        when 'left', 'right' then rows.map (text) -> text.repeat(count+1)
+    else
+      text = selection.getText()
+      switch @direction
+        when 'up', 'down' then [1..count].map -> text
+        when 'left', 'right' then [text.repeat(count)]
 
 class DuplicateSelectedTextUp extends DuplicateSelectedText
   direction: 'up'

class DuplicateSelectedText extends TransformString
  @commandScope: 'atom-text-editor.vim-mode-plus.visual-mode'
  @commandPrefix: 'vim-mode-plus-user'
  execute: ->
    selections = @editor.getSelectionsOrderedByBufferPosition()
    @editor.transact =>
      for selection in selections # when @isMovable(selection)
        if @isLinewise()
          if @vimState.submode is 'linewise'
            @duplicateLinewise(selection)
          else
            swrap(selection).switchToLinewise =>
              @duplicateLinewise(selection)
        else
          @duplicateCharacterwise(selection)

  isCharacterwise: ->
    not @isLinewise()

  duplicateLinewise: (selection) ->
    lineTexts = @duplicateText(selection)
    console.log inspect(lineTexts)
    switch @direction
      when 'up', 'down'
        reversed = selection.isReversed()

        which = if @direction is 'up' then 'start' else 'end'
        point = selection.getBufferRange()[which]

        text = lineTexts.join("\n") + "\n"
        range = @editor.setTextInBufferRange([point, point], text)
        selection.setBufferRange(range, {reversed})

      when 'left', 'right'
        reversed = selection.isReversed()
        text = lineTexts.join("\n") + "\n"
        range = selection.insertText(text)
        selection.setBufferRange(range, {reversed})

    # selection.insertText(text)
    # console.log "duplicate #{@direction} #{count} times linewise"

  duplicateCharacterwise: (selection) ->
    count = @getCount()
    console.log "duplicate #{@direction} #{count} times characterwise"

  isLinewise: ->
    switch @vimState.submode

    @withUndoJoin =>
      selections = @editor.getSelectionsOrderedByBufferPosition()
      return if @isCharacterwise() and (not @isMovable(selections[0]))
      selections.reverse() if @direction is 'up'
      @editor.transact =>
        @countTimes =>
          @mutateSelections(selections)
