fun getMotionRange2()

in src/main/java/com/maddyhome/idea/vim/group/MotionGroup.kt [179:258]


    fun getMotionRange2(
      editor: Editor,
      caret: Caret,
      context: DataContext?,
      argument: Argument,
      operatorArguments: OperatorArguments,
    ): TextRange? {
      if (argument !is Argument.Motion) {
        throw RuntimeException("Unexpected argument passed to getMotionRange2: $argument")
      }

      var start: Int
      var end: Int

      val action = argument.motion
      when (action) {
        is MotionActionHandler -> {
          // This is where we are now
          start = caret.offset

          // Execute the motion (without moving the cursor) and get where we end
          val motion = action.getHandlerOffset(
            editor.vim,
            caret.vim,
            IjEditorExecutionContext(context!!),
            argument.argument,
            operatorArguments
          )

          // Invalid motion
          if (Motion.Error == motion) return null
          if (Motion.NoMotion == motion) return null
          end = (motion as AbsoluteOffset).offset

          // If inclusive, add the last character to the range
          if (action.motionType === MotionType.INCLUSIVE && end < editor.vim.fileSize()) {
            if (start > end) {
              start++
            } else {
              end++
            }
          }
        }

        is TextObjectActionHandler -> {
          val range = action.getRange(
            editor.vim,
            caret.vim,
            IjEditorExecutionContext(context!!),
            operatorArguments.count1,
            operatorArguments.count0
          ) ?: return null
          start = range.startOffset
          end = range.endOffset
          if (argument.isLinewiseMotion()) end--
        }

        is ExternalActionHandler -> {
          val range = action.getRange(caret.vim) ?: return null
          start = range.startOffset
          end = range.endOffset
        }

        else -> throw RuntimeException("Commands doesn't take " + action.javaClass.simpleName + " as an operator")
      }

      // This is a kludge for dw, dW, and d[w. Without this kludge, an extra newline is operated when it shouldn't be.
      val id = argument.motion.id
      if (id == VimChangeGroupBase.VIM_MOTION_WORD_RIGHT || id == VimChangeGroupBase.VIM_MOTION_BIG_WORD_RIGHT || id == VimChangeGroupBase.VIM_MOTION_CAMEL_RIGHT) {
        val text = editor.document.charsSequence.subSequence(start, end).toString()
        val lastNewLine = text.lastIndexOf('\n')
        if (lastNewLine > 0) {
          if (!editor.vim.anyNonWhitespace(end, -1)) {
            end = start + lastNewLine
          }
        }
      }

      return TextRange(start, end)
    }