override fun updateMarksFromDelete()

in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimMarkServiceBase.kt [401:445]


  override fun updateMarksFromDelete(editor: VimEditor, delStartOffset: Int, delLength: Int) {
    val caretToMarks = getAllMarksForFile(editor)
    if (caretToMarks.isEmpty()) return

    val delEndOffset = delStartOffset + delLength - 1
    val delStart = editor.offsetToBufferPosition(delStartOffset)
    val delEnd = editor.offsetToBufferPosition(delEndOffset + 1)
    logger.debug { "mark delete. delStart = $delStart, delEnd = $delEnd" }

    for ((caret, marks) in caretToMarks) {
      for (mark in marks.filterIsInstance<VimMark>()) {
        logger.debug { "mark = $mark" }
        if (delEnd.line < mark.line) {
          val lines = delEnd.line - delStart.line
          logger.debug { "Shifting mark by $lines lines" }
          mark.line = mark.line - lines
        } else if (delStart.line <= mark.line) {
          val markLineStartOffset = editor.getLineStartOffset(mark.line)
          val markLineEndOffset = editor.getLineEndOffset(mark.line, true)

          val command = injector.vimState.executingCommand
          // If text is being changed from the start of the mark line (a special case for mark deletion)
          val changeFromMarkLineStart =
            (command != null && command.type === Command.Type.CHANGE && delStartOffset == markLineStartOffset)
          // If the marked line is completely within the deleted text, remove the mark (except the special case)
          if (delStartOffset <= markLineStartOffset && delEndOffset >= markLineEndOffset && !changeFromMarkLineStart) {
            if (caret == null) {
              removeGlobalMark(mark.key)
            } else {
              injector.markService.removeLocalMark(caret, mark.key)
            }
            logger.debug("Removed mark")
          } else if (delStart.line < mark.line) {
            // shift mark
            mark.line = delStart.line
            if ((mark.key == SELECTION_START_MARK || mark.key == SELECTION_END_MARK) && caret != null) {
              setMark(caret, mark)
            }
            logger.debug { "Shifting mark to line " + delStart.line }
          } // The deletion only covers part of the marked line so shift the mark only if the deletion begins
          // on a line prior to the marked line (which means the deletion must end on the marked line).
        } // If the deleted text begins before the mark and ends after the mark then it may be shifted or deleted
      }
    }
  }