fun storeTextInternal()

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
  }