in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/register/VimRegisterGroupBase.kt [170:277]
fun storeTextInternal(
editor: VimEditor,
context: ExecutionContext,
range: TextRange,
text: String,
type: SelectionType,
register: Char,
isDelete: Boolean,
): Boolean {
// Null register doesn't get saved, but acts like it was
if (lastRegisterChar == BLACK_HOLE_REGISTER) return true
var start = range.startOffset
var end = range.endOffset
if (isDelete && start == end) {
return true
}
// Normalize the start and end
if (start > end) {
val t = start
start = end
end = t
}
val copiedText =
if (start != -1) { // FIXME: so, we had invalid ranges all the time?.. I've never handled such cases
injector.clipboardManager.collectCopiedText(editor, context, range, text)
} else {
injector.clipboardManager.dumbCopiedText(text)
}
logger.debug { "Copy to '$lastRegisterChar' with copied text: $copiedText" }
// If this is an uppercase register, we need to append the text to the corresponding lowercase register
if (Character.isUpperCase(register)) {
val lreg = Character.toLowerCase(register)
val r = myRegisters[lreg]
// Append the text if the lowercase register existed
if (r != null) {
myRegisters[lreg] = r.addText(copiedText.text)
} else {
myRegisters[lreg] = Register(lreg, copiedText, type)
logger.debug { "register '$register' contains: \"$copiedText\"" }
} // Set the text if the lowercase register didn't exist yet
} else {
myRegisters[register] = Register(register, copiedText, type)
logger.debug { "register '$register' contains: \"$copiedText\"" }
} // Put the text in the specified register
if (register == CLIPBOARD_REGISTER) {
injector.clipboardManager.setClipboardContent(editor, context, copiedText)
if (!isRegisterSpecifiedExplicitly && !isDelete && isPrimaryRegisterSupported() && OptionConstants.clipboard_unnamedplus in injector.globalOptions().clipboard) {
injector.clipboardManager.setPrimaryContent(editor, context, copiedText)
}
}
if (register == PRIMARY_REGISTER) {
if (isPrimaryRegisterSupported()) {
injector.clipboardManager.setPrimaryContent(editor, context, copiedText)
if (!isRegisterSpecifiedExplicitly && !isDelete && OptionConstants.clipboard_unnamed in injector.globalOptions().clipboard) {
injector.clipboardManager.setClipboardContent(editor, context, copiedText)
}
} else {
injector.clipboardManager.setClipboardContent(editor, context, copiedText)
}
}
// Also add it to the unnamed register if the default wasn't specified
if (register != UNNAMED_REGISTER && ".:/".indexOf(register) == -1) {
myRegisters[UNNAMED_REGISTER] = Register(UNNAMED_REGISTER, copiedText, type)
logger.debug { "register '$UNNAMED_REGISTER' contains: \"$copiedText\"" }
}
if (isDelete) {
val smallInlineDeletion =
(
(type === SelectionType.CHARACTER_WISE || type === SelectionType.BLOCK_WISE) && (
editor.offsetToBufferPosition(
start,
).line == editor.offsetToBufferPosition(end).line
)
)
// Deletes go into numbered registers only if text is smaller than a line, register is used or it's a special case
if (!smallInlineDeletion && register == defaultRegister || isSmallDeletionSpecialCase()) {
// Old 1 goes to 2, etc. Old 8 to 9, old 9 is lost
var d = '8'
while (d >= '1') {
val t = myRegisters[d]
if (t != null) {
val incName = (d.code + 1).toChar()
myRegisters[incName] = Register(incName, t.copiedText, t.type)
}
d--
}
myRegisters['1'] = Register('1', copiedText, type)
}
// Deletes smaller than one line and without specified register go the the "-" register
if (smallInlineDeletion && register == defaultRegister) {
myRegisters[SMALL_DELETION_REGISTER] =
Register(SMALL_DELETION_REGISTER, copiedText, type)
}
} else if (register == defaultRegister) {
myRegisters['0'] = Register('0', copiedText, type)
logger.debug { "register '0' contains: \"$copiedText\"" }
} // Yanks also go to register 0 if the default register was used
return true
}