@@ -906,6 +906,90 @@ class TextPosition {
906906 }
907907}
908908
909+ /// A range of characters in a string of text.
910+ class TextRange {
911+ /// Creates a text range.
912+ ///
913+ /// The [start] and [end] arguments must not be null. Both the [start] and
914+ /// [end] must either be greater than or equal to zero or both exactly -1.
915+ ///
916+ /// Instead of creating an empty text range, consider using the [empty]
917+ /// constant.
918+ const TextRange ({
919+ this .start,
920+ this .end,
921+ }) : assert (start != null && start >= - 1 ),
922+ assert (end != null && end >= - 1 );
923+
924+ /// A text range that starts and ends at offset.
925+ ///
926+ /// The [offset] argument must be non-null and greater than or equal to -1.
927+ const TextRange .collapsed (int offset)
928+ : assert (offset != null && offset >= - 1 ),
929+ start = offset,
930+ end = offset;
931+
932+ /// A text range that contains nothing and is not in the text.
933+ static const TextRange empty = TextRange (start: - 1 , end: - 1 );
934+
935+ /// The index of the first character in the range.
936+ ///
937+ /// If [start] and [end] are both -1, the text range is empty.
938+ final int start;
939+
940+ /// The next index after the characters in this range.
941+ ///
942+ /// If [start] and [end] are both -1, the text range is empty.
943+ final int end;
944+
945+ /// Whether this range represents a valid position in the text.
946+ bool get isValid => start >= 0 && end >= 0 ;
947+
948+ /// Whether this range is empty (but still potentially placed inside the text).
949+ bool get isCollapsed => start == end;
950+
951+ /// Whether the start of this range precedes the end.
952+ bool get isNormalized => end >= start;
953+
954+ /// The text before this range.
955+ String textBefore (String text) {
956+ assert (isNormalized);
957+ return text.substring (0 , start);
958+ }
959+
960+ /// The text after this range.
961+ String textAfter (String text) {
962+ assert (isNormalized);
963+ return text.substring (end);
964+ }
965+
966+ /// The text inside this range.
967+ String textInside (String text) {
968+ assert (isNormalized);
969+ return text.substring (start, end);
970+ }
971+
972+ @override
973+ bool operator == (dynamic other) {
974+ if (identical (this , other))
975+ return true ;
976+ if (other is ! TextRange )
977+ return false ;
978+ final TextRange typedOther = other;
979+ return typedOther.start == start
980+ && typedOther.end == end;
981+ }
982+
983+ @override
984+ int get hashCode => hashValues (
985+ start.hashCode,
986+ end.hashCode,
987+ );
988+
989+ @override
990+ String toString () => 'TextRange(start: $start , end: $end )' ;
991+ }
992+
909993/// Layout constraints for [Paragraph] objects.
910994///
911995/// Instances of this class are typically used with [Paragraph.layout] .
0 commit comments