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