segmentsFor method

List<DiffSegment> segmentsFor(
  1. DiffLine line, [
  2. WordChanges? words
])

line as styled segments, ready to paint. With words, the segments are split where the line's changed words start and end, and those are marked DiffSegment.changed. A line without tokens, such as an expanded line of a parsed patch, is one plain segment.

Implementation

List<DiffSegment> segmentsFor(DiffLine line, [WordChanges? words]) {
  if (line.text.isEmpty) return const [];
  var tokens = tokensFor(line);
  // Not tokenized yet, or outside the hunks: one plain token, so changed
  // words are still marked.
  if (tokens.isEmpty) {
    tokens = [ThemedToken(line.text, 0, _plain, _plainScopes)];
  }
  final ranges = words?.rangesFor(line) ?? const <CharRange>[];
  final segments = <DiffSegment>[];
  var r = 0;
  for (final token in tokens) {
    final end = token.offset + token.text.length;
    var pos = token.offset;
    while (pos < end) {
      while (r < ranges.length && ranges[r].end <= pos) {
        r++;
      }
      final inRange = r < ranges.length && ranges[r].start <= pos;
      final next = inRange
          ? math.min(end, ranges[r].end)
          : (r < ranges.length ? math.min(end, ranges[r].start) : end);
      segments.add(
        DiffSegment(
          token.text.substring(pos - token.offset, next - token.offset),
          token.style,
          changed: inRange,
        ),
      );
      pos = next;
    }
  }
  return segments;
}