findTextQueryHighlights function

List<TextHighlightRange> findTextQueryHighlights({
  1. required TextDocument document,
  2. required String query,
  3. bool caseSensitive = false,
})

Implementation

List<TextHighlightRange> findTextQueryHighlights({
  required TextDocument document,
  required String query,
  bool caseSensitive = false,
}) {
  final needle = query.characters.toList(growable: false);
  if (needle.isEmpty) {
    return const [];
  }

  final normalizedNeedle = needle
      .map((token) => _normalizeHighlightToken(token, caseSensitive))
      .toList(growable: false);
  final ranges = <TextHighlightRange>[];
  var lineOffset = 0;

  for (var lineIndex = 0; lineIndex < document.lineCount; lineIndex++) {
    final line = document.lineGraphemesAt(lineIndex);
    final normalizedLine = line
        .map((token) => _normalizeHighlightToken(token, caseSensitive))
        .toList(growable: false);

    var cursor = 0;
    while (cursor <= normalizedLine.length - normalizedNeedle.length) {
      var matched = true;
      for (var index = 0; index < normalizedNeedle.length; index++) {
        if (normalizedLine[cursor + index] != normalizedNeedle[index]) {
          matched = false;
          break;
        }
      }

      if (!matched) {
        cursor++;
        continue;
      }

      ranges.add(
        TextHighlightRange(
          startOffset: lineOffset + cursor,
          endOffset: lineOffset + cursor + normalizedNeedle.length,
        ),
      );
      cursor += normalizedNeedle.length;
    }

    lineOffset += line.length;
    if (lineIndex < document.lineCount - 1) {
      lineOffset += 1;
    }
  }

  return List<TextHighlightRange>.unmodifiable(ranges);
}