   select: ->
     for selection in @editor.getSelections()
       if @isInclusive() or @isLinewise()
-        @switchCharacterwise selection, =>
-          @selectInclusive selection
+        @normalizeVisualMode(selection) if @isMode('visual')
+        @selectInclusively(selection)
+        @selectLine(selection) if @isLinewise()
       else
         selection.modifySelection =>
           @moveCursor selection.cursor

  find: ->
    @point = super

  selectInclusive: (selection) ->
    super
    if selection.isEmpty() and (@point? and not @backwards)
      selection.modifySelection ->

    @editor.mergeIntersectingSelections()
    @emitDidSelect()

  selectLine: (selection) ->
    if @isMode('visual', 'linewise')
      swrap(selection).preserveCharacterwise()
    swrap(selection).expandOverLine(preserveGoalColumn: true)

  # Modify selection with keeping tailRange(= range under cursor in most case.).
  # -------------------------
  # * Why we need to allowWrap when moveCursorLeft/Right?
  # When 'linewise' selection, cursor is at column '0' of NEXT line, so we need to moveLeft
  # by wrapping, to put cursor on row which actually be selected(from UX point of view).
  # This adjustment is important so that j, k works without special care in moveCursor.
  selectInclusively: (selection) ->
    {cursor} = selection
    selection.modifySelection =>
      tailRange = swrap(selection).getTailBufferRange()
      @moveCursor(cursor)
      if @isMode('visual') and cursor.isAtEndOfLine()
        moveCursorLeft(cursor)

      # When mode isnt 'visual' selection.isEmpty() at this point means no movement happened.
      return if not @isMode('visual') and selection.isEmpty()
      unless selection.isReversed()
        allowWrap = cursorIsAtEmptyRow(cursor)
        moveCursorRight(cursor, {allowWrap, preserveGoalColumn: true})
      # Finally merge tailRange(= under cursor range where you start selection)
      newRange = selection.getBufferRange().union(tailRange)
      selection.setBufferRange(newRange, {autoscroll: false, preserveFolds: true})

  # Normalize visual-mode specific cursor position before/after modifySelection
  # The purpose of this normalization is callbacked function,
  # moveCursor works consistently both normal and visual mode.
  normalizeVisualMode: (selection) ->
    {cursor} = selection
    {submode} = @vimState
    if submode is 'linewise'
      swrap(selection).restoreCharacterwise(preserveGoalColumn: true)
    # We selectRight()ed in visual-mode, so reset this effect here.
    unless selection.isReversed()
      selection.modifySelection ->
        moveCursorLeft(cursor, {allowWrap: true, preserveGoalColumn: true})

  # Utils
  # -------------------------
