wrapLineWithAnsi static method

List<List<int>> wrapLineWithAnsi(
  1. List<int> lineBytes,
  2. int maxWidth,
  3. List<int> indentBytes
)

Implementation

static List<List<int>> wrapLineWithAnsi(
  List<int> lineBytes,
  int maxWidth,
  List<int> indentBytes,
) {
  if (maxWidth <= 0) {
    return [
      <int>[...indentBytes, ...lineBytes],
    ];
  }

  final wrapped = <List<int>>[];
  var currentLine = <int>[...indentBytes];
  var visibleLength = indentBytes.length;
  var inAnsi = false;
  var ansiBuffer = <int>[];
  var lastWhitespacePos = -1;
  var lastWhitespaceVisibleLength = 0;

  for (var i = 0; i < lineBytes.length; i++) {
    final byte = lineBytes[i];

    if (byte == 0x1B) {
      inAnsi = true;
      ansiBuffer = [byte];
      currentLine.add(byte);
      continue;
    }

    if (inAnsi) {
      ansiBuffer.add(byte);
      currentLine.add(byte);
      if (byte >= 0x40 && byte <= 0x7E) {
        inAnsi = false;
        ansiBuffer = [];
      }
      continue;
    }

    final isWhitespace = byte == 0x20 || byte == 0x09;
    if (isWhitespace) {
      lastWhitespacePos = currentLine.length;
      lastWhitespaceVisibleLength = visibleLength;
    }

    if (visibleLength >= maxWidth &&
        currentLine.length > indentBytes.length) {
      if (lastWhitespacePos > indentBytes.length &&
          lastWhitespaceVisibleLength > indentBytes.length) {
        final wrappedLine = currentLine.sublist(0, lastWhitespacePos);
        final remainingBytes = currentLine.sublist(lastWhitespacePos + 1);
        wrapped.add(wrappedLine);

        currentLine = <int>[...indentBytes];
        if (ansiBuffer.isNotEmpty) {
          currentLine.addAll(ansiBuffer);
        }
        currentLine.addAll(remainingBytes);
        visibleLength =
            indentBytes.length +
            (visibleLength - lastWhitespaceVisibleLength - 1);
        lastWhitespacePos = -1;
      } else {
        wrapped.add(currentLine);
        currentLine = <int>[...indentBytes];
        if (ansiBuffer.isNotEmpty) {
          currentLine.addAll(ansiBuffer);
        }
        visibleLength = indentBytes.length;
        lastWhitespacePos = -1;
      }
    }

    currentLine.add(byte);
    if (byte == 0x09) {
      visibleLength = ((visibleLength ~/ 8) + 1) * 8;
    } else if (byte >= 0x20) {
      visibleLength++;
    }
  }

  if (currentLine.isNotEmpty) {
    wrapped.add(currentLine);
  }

  return wrapped.isEmpty
      ? [
          <int>[...indentBytes, ...lineBytes],
        ]
      : wrapped;
}