protected fun findNumberInText()

in vim-engine/src/main/kotlin/com/maddyhome/idea/vim/api/VimChangeGroupBase.kt [1697:1787]


  protected fun findNumberInText(
    textInRange: String,
    startPosOnLine: Int,
    alpha: Boolean,
    hex: Boolean,
    octal: Boolean,
  ): Pair<TextRange, NumberType>? {
    if (logger.isDebug()) {
      logger.debug("text=$textInRange")
    }

    var pos = startPosOnLine
    val lineEndOffset = textInRange.length

    while (true) {
      // Skip over current whitespace if any
      while (pos < lineEndOffset && !isNumberChar(textInRange[pos], alpha, hex, octal, true)) {
        pos++
      }

      if (logger.isDebug()) logger.debug("pos=$pos")
      if (pos >= lineEndOffset) {
        logger.debug("no number char on line")
        return null
      }

      val isHexChar = "abcdefABCDEF".indexOf(textInRange[pos]) >= 0

      if (hex) {
        // Ox and OX handling
        if (textInRange[pos] == '0' && pos < lineEndOffset - 1 && "xX".indexOf(textInRange[pos + 1]) >= 0) {
          pos += 2
        } else if ("xX".indexOf(textInRange[pos]) >= 0 && pos > 0 && textInRange[pos - 1] == '0') {
          pos++
        }

        logger.debug("checking hex")
        val range = findRange(textInRange, pos, false, true, false, false)
        val start = range.first
        val end = range.second

        // Ox and OX
        if (start >= 2 && textInRange.substring(start - 2, start).equals("0x", ignoreCase = true)) {
          logger.debug("found hex")
          return Pair(TextRange(start - 2, end), NumberType.HEX)
        }

        if (!isHexChar || alpha) {
          break
        } else {
          pos++
        }
      } else {
        break
      }
    }

    if (octal) {
      logger.debug("checking octal")
      val range = findRange(textInRange, pos, false, false, true, false)
      val start = range.first
      val end = range.second

      if (end - start == 1 && textInRange[start] == '0') {
        return Pair(TextRange(start, end), NumberType.DEC)
      }
      if (textInRange[start] == '0' && end > start &&
        !(start > 0 && isNumberChar(textInRange[start - 1], false, false, false, true))
      ) {
        logger.debug("found octal")
        return Pair(TextRange(start, end), NumberType.OCT)
      }
    }

    if (alpha) {
      if (logger.isDebug()) logger.debug("checking alpha for " + textInRange[pos])
      if (isNumberChar(textInRange[pos], true, false, false, false)) {
        if (logger.isDebug()) logger.debug("found alpha at $pos")
        return Pair(TextRange(pos, pos + 1), NumberType.ALPHA)
      }
    }

    val range = findRange(textInRange, pos, false, false, false, true)
    var start = range.first
    val end = range.second
    if (start > 0 && textInRange[start - 1] == '-') {
      start--
    }

    return Pair(TextRange(start, end), NumberType.DEC)
  }