readFileForEdit function

FileReadMetadata readFileForEdit(
  1. String absoluteFilePath
)

Read a file with encoding and line-ending detection.

Implementation

FileReadMetadata readFileForEdit(String absoluteFilePath) {
  try {
    final file = File(absoluteFilePath);
    final bytes = file.readAsBytesSync();
    // Detect encoding from BOM
    String encoding = 'utf-8';
    String content;
    if (bytes.length >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) {
      encoding = 'utf16le';
      // Decode UTF-16LE
      final buffer = StringBuffer();
      for (var i = 2; i < bytes.length - 1; i += 2) {
        buffer.writeCharCode(bytes[i] | (bytes[i + 1] << 8));
      }
      content = buffer.toString();
    } else {
      content = utf8.decode(bytes, allowMalformed: true);
    }
    content = content.replaceAll('\r\n', '\n');

    // Detect line endings from the raw bytes
    final rawContent = utf8.decode(bytes, allowMalformed: true);
    LineEndingType lineEndings = LineEndingType.lf;
    final crlfCount = '\r\n'.allMatches(rawContent).length;
    final lfCount = '\n'.allMatches(rawContent).length - crlfCount;
    final crCount = '\r'.allMatches(rawContent).length - crlfCount;
    if (crlfCount > lfCount && crlfCount > crCount) {
      lineEndings = LineEndingType.crlf;
    } else if (crCount > lfCount) {
      lineEndings = LineEndingType.cr;
    }

    return FileReadMetadata(
      content: content,
      fileExists: true,
      encoding: encoding,
      lineEndings: lineEndings,
    );
  } on FileSystemException {
    return const FileReadMetadata(
      content: '',
      fileExists: false,
      encoding: 'utf-8',
      lineEndings: LineEndingType.lf,
    );
  }
}