in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/put/VimPutBase.kt [397:496]
protected fun prepareDocumentAndGetStartOffsets(
vimEditor: VimEditor,
vimCaret: VimCaret,
typeInRegister: SelectionType,
data: PutData,
additionalData: Map<String, Any>,
): List<Int> {
val application = injector.application
val visualSelection = data.visualSelection
if (visualSelection != null) {
return when {
visualSelection.typeInEditor.isChar && typeInRegister.isLine -> {
application.runWriteAction { (vimEditor as MutableVimEditor).insertText(vimCaret, vimCaret.offset, "\n") }
listOf(vimCaret.offset + 1)
}
visualSelection.typeInEditor.isBlock -> {
val firstSelectedLine = additionalData["firstSelectedLine"] as Int
val selectedLines = additionalData["selectedLines"] as Int
val startColumnOfSelection = additionalData["startColumnOfSelection"] as Int
val line = (if (data.insertTextBeforeCaret) firstSelectedLine else firstSelectedLine + selectedLines)
.coerceAtMost(vimEditor.lineCount() - 1)
when (typeInRegister) {
SelectionType.LINE_WISE -> when {
data.insertTextBeforeCaret -> listOf(vimEditor.getLineStartOffset(line))
else -> {
val pos = vimEditor.getLineEndOffset(line, true)
application.runWriteAction { (vimEditor as MutableVimEditor).insertText(vimCaret, pos, "\n") }
listOf(pos + 1)
}
}
SelectionType.CHARACTER_WISE -> (firstSelectedLine + selectedLines downTo firstSelectedLine)
.map { vimEditor.bufferPositionToOffset(BufferPosition(it, startColumnOfSelection)) }
SelectionType.BLOCK_WISE -> listOf(
vimEditor.bufferPositionToOffset(
BufferPosition(
firstSelectedLine,
startColumnOfSelection,
),
),
)
}
}
visualSelection.typeInEditor.isLine -> {
val lastChar = if (vimEditor.fileSize() > 0) {
vimEditor.getText(TextRange(vimEditor.fileSize().toInt() - 1, vimEditor.fileSize().toInt()))[0]
} else {
null
}
if (vimCaret.offset == vimEditor.fileSize().toInt() && vimEditor.fileSize()
.toInt() != 0 && lastChar != '\n'
) {
application.runWriteAction { (vimEditor as MutableVimEditor).insertText(vimCaret, vimCaret.offset, "\n") }
listOf(vimCaret.offset + 1)
} else {
listOf(vimCaret.offset)
}
}
else -> listOf(vimCaret.offset)
}
} else {
if (data.insertTextBeforeCaret) {
return when (typeInRegister) {
SelectionType.LINE_WISE -> listOf(injector.motion.moveCaretToCurrentLineStart(vimEditor, vimCaret))
else -> listOf(vimCaret.offset)
}
}
var startOffset: Int
val line = if (data.putToLine < 0) vimCaret.getBufferPosition().line else data.putToLine
when (typeInRegister) {
SelectionType.LINE_WISE -> {
startOffset =
min(vimEditor.text().length, injector.motion.moveCaretToLineEnd(vimEditor, line, true) + 1)
// At the end of a notebook cell the next symbol is a guard,
// so we add a newline to be able to paste. Fixes VIM-2577
if (startOffset > 0 && vimEditor.document.getOffsetGuard(startOffset) != null) {
application.runWriteAction { (vimEditor as MutableVimEditor).insertText(vimCaret, (startOffset - 1), "\n") }
}
if (startOffset > 0 && startOffset == vimEditor.text().length && vimEditor.text()[startOffset - 1] != '\n') {
application.runWriteAction { (vimEditor as MutableVimEditor).insertText(vimCaret, startOffset, "\n") }
startOffset++
}
}
else -> {
startOffset = vimCaret.offset
if (!vimEditor.isLineEmpty(line, false)) {
startOffset++
}
}
}
return if (startOffset > vimEditor.text().length) listOf(vimEditor.text().length) else listOf(startOffset)
}
}