   setTextInRangeAndSelect
   insertSpacesToPoint
   extendLastBufferRowToRow
+  countChar
 } = require './utils'
 {inspect} = require 'util'
 


class DuplicateSelectedTextRight extends DuplicateSelectedText
  direction: 'right'
  duplicateCharacterwise: (selection, count) ->
    newText = selection.getText().repeat(count)
    width = newText.length
    {start, end} = selection.getBufferRange()
    range = switch @direction
      when 'left'
        if @isOverwrite()
          [start.translate([0, -width]), start]
        else
          [start, start]
      when 'right'
        if @isOverwrite()
          [end, end.translate([0, +width])]
        else
          [end, end]
    setTextInRangeAndSelect(range, newText, selection)

class DuplicateSelectedTextLeft extends DuplicateSelectedTextRight
  direction: 'left'

            if wasCharacterwise
              @vimState.activate('visual', 'characterwise')

class DuplicateSelectedTextUp extends DuplicateSelectedText
  direction: 'up'

  duplicateLinewise: (selection, count) ->
    getText = ->
      rows = swrap(selection).lineTextForBufferRows()
      _.flatten([1..count].map -> rows).join("\n") + "\n"

    getRangeToInsert = (text) =>
      {start, end} = selection.getBufferRange()
      if @isOverwrite()
        height = text.split("\n").length - 1
        switch @direction
          when 'up' then [start.translate([-height, 0]), start]
          when 'down' then [end, end.translate([+height, 0])]
      else
        switch @direction
          when 'up' then [start, start]
          when 'down' then [end, end]

    text = getText()
    range = getRangeToInsert(text)
    setTextInRangeAndSelect(range, text, selection)

  duplicateBlockwiseSelection: (blockwiseSelection, count) ->
    {selections} = blockwiseSelection
