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)
}