Use character based columns Towards #74 Use `Characters` to operate based on grapheme clusters instead of code units.
diff --git a/lib/src/file.dart b/lib/src/file.dart index 473b8c1..047a644 100644 --- a/lib/src/file.dart +++ b/lib/src/file.dart
@@ -5,6 +5,8 @@ import 'dart:math' as math; import 'dart:typed_data'; +import 'package:characters/characters.dart'; + import 'location.dart'; import 'location_mixin.dart'; import 'span.dart'; @@ -184,7 +186,9 @@ throw RangeError('Line $line comes after offset $offset.'); } - return offset - lineStart; + final content = _decodedChars.sublist(lineStart, offset); + final characters = Characters(String.fromCharCodes(content)); + return characters.length; } /// Gets the offset for a [line] and [column]. @@ -202,11 +206,16 @@ throw RangeError('Column may not be negative, was $column.'); } - final result = _lineStarts[line] + column; - if (result > length || - (line + 1 < lines && result >= _lineStarts[line + 1])) { + final content = line < lines - 1 + ? _decodedChars.sublist(_lineStarts[line], _lineStarts[line + 1]) + : _decodedChars.sublist(_lineStarts[line]); + final characters = Characters(String.fromCharCodes(content)); + if (characters.length < column) { throw RangeError("Line $line doesn't have $column columns."); } + final withinLineLength = + characters.take(column).toString().codeUnits.length; + final result = _lineStarts[line] + withinLineLength; return result; }
diff --git a/pubspec.yaml b/pubspec.yaml index 63a64b0..2b4e4f9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml
@@ -7,6 +7,7 @@ sdk: ">=2.14.0 <3.0.0" dependencies: + characters: ^1.2.0 collection: ^1.15.0 path: ^1.8.0 term_glyph: ^1.2.0