export function getTagNearestTrigger()

in src/language/providers/elementCompletion.ts [477:562]


export function getTagNearestTrigger(
  document: vscode.TextDocument,
  position: vscode.Position,
  triggerText: string,
  triggerLine: number,
  triggerPos: number,
  itemsOnLine: number,
  nsPrefix: string
): [string, vscode.Position] {
  let [startLine, startPos] = [triggerLine, triggerPos]
  let tagNearestTrigger = 'none'

  if (
    itemsOnLine === 0 &&
    document.lineCount === 1 &&
    position.character === 0
  ) {
    return ['emptySchema', position]
  }

  while (true) {
    let [foundTag, foundLine, foundPos] = nearestTag(
      document,
      position,
      nsPrefix,
      startLine,
      startPos
    )

    if (itemsOnLine > 1) {
      const afterTriggerText = triggerText.substring(triggerPos)
      const afterTriggerPos = afterTriggerText.indexOf('<') + triggerPos
      const beforeTriggerText = triggerText.substring(0, triggerPos)
      const lastOpenTagBeforeTriggerPos = beforeTriggerText.lastIndexOf('<')
      const beforeTriggerPos = beforeTriggerText.lastIndexOf('>')
      const beforeTriggerTag = beforeTriggerText.substring(
        lastOpenTagBeforeTriggerPos
      )

      if (
        triggerPos === afterTriggerPos &&
        triggerPos === beforeTriggerPos + 1 &&
        !beforeTriggerTag.startsWith('</')
      ) {
        tagNearestTrigger = foundTag
        return [tagNearestTrigger, new vscode.Position(foundLine, foundPos)]
      }
    }

    startLine = foundLine

    let [endTag, endTagLine, endTagPos] = getCloseTag(
      document,
      position,
      nsPrefix,
      foundTag,
      foundLine,
      foundPos
    )

    if (itemsOnLine > 1 && foundLine === triggerLine) {
      if (foundTag === endTag && endTagPos >= triggerPos) {
        tagNearestTrigger = foundTag
        return [tagNearestTrigger, new vscode.Position(foundLine, foundPos)]
      }

      if (endTag === 'none') {
        startLine = foundLine - 1
      } else {
        startPos = foundPos - 1
      }
    }

    if (itemsOnLine < 2) {
      if (
        (foundTag === endTag && endTagLine >= triggerLine) ||
        endTag === 'xml version'
      ) {
        tagNearestTrigger = foundTag
        return [tagNearestTrigger, new vscode.Position(foundLine, foundPos)]
      }

      startLine = foundLine - 1
    }
  }
}