diff --git a/lib/src/code_field/code_controller.dart b/lib/src/code_field/code_controller.dart index ea97f591..23d52f9d 100644 --- a/lib/src/code_field/code_controller.dart +++ b/lib/src/code_field/code_controller.dart @@ -505,8 +505,6 @@ class CodeController extends TextEditingController { super.value = _getValueWithCode(_code); } - - /// The value with [newCode] preserving the current selection. TextEditingValue _getValueWithCode(Code newCode) { return TextEditingValue( diff --git a/lib/src/hidden_ranges/hidden_line_ranges.dart b/lib/src/hidden_ranges/hidden_line_ranges.dart index 3bfa3ecd..38361519 100644 --- a/lib/src/hidden_ranges/hidden_line_ranges.dart +++ b/lib/src/hidden_ranges/hidden_line_ranges.dart @@ -5,18 +5,15 @@ import 'line_numbering_breakpoint.dart'; class HiddenLineRanges with EquatableMixin { final List breakpoints; final int fullLineCount; - final int visibleLineCount; const HiddenLineRanges({ required this.breakpoints, required this.fullLineCount, - required this.visibleLineCount, }); static const empty = HiddenLineRanges( breakpoints: [], fullLineCount: 1, - visibleLineCount: 1, ); /// Returns the visible line index to which the full [lineIndex] maps @@ -34,6 +31,14 @@ class HiddenLineRanges with EquatableMixin { if (breakpoints.isEmpty) { return lineIndex; } + if (lineIndex <= breakpoints.first.full) { + return breakpoints.first.cutLineIndexIfVisible(lineIndex); + } + if (lineIndex >= breakpoints.last.full) { + return breakpoints.last.cutLineIndexIfVisible(lineIndex); + } + + // At this point, we always have a breakpoint before and after. int lower = 0; int upper = breakpoints.length - 1; @@ -49,20 +54,24 @@ class HiddenLineRanges with EquatableMixin { (upper - lower)) .floor(); - if (index < lower) { - return breakpoints[lower].cutLineIndexIfVisible(lineIndex); - } - if (index > upper) { - return breakpoints[upper].cutLineIndexIfVisible(lineIndex); - } - final breakpoint = breakpoints[index]; switch ((breakpoint.full - lineIndex).sign) { - case -1: + case -1: // We are after this breakpoint. + final nextBreakpoint = breakpoints[index + 1]; + if (nextBreakpoint.full > lineIndex) { + // ... and before the next one. + return nextBreakpoint.cutLineIndexIfVisible(lineIndex); + } lower = index + 1; continue; - case 1: + + case 1: // We are before this breakpoint. + final previousBreakpoint = breakpoints[index - 1]; + if (previousBreakpoint.full < lineIndex) { + // ... and after the previous one. + return breakpoint.cutLineIndexIfVisible(lineIndex); + } upper = index - 1; continue; } @@ -70,9 +79,9 @@ class HiddenLineRanges with EquatableMixin { return breakpoint.visible; } - // upper == lower - final breakpoint = breakpoints[upper]; - return breakpoint.cutLineIndexIfVisible(lineIndex); + throw Exception( + 'Never get here. upper == lower without finding a breakpoint', + ); } Iterable get visibleLineNumbers sync* { diff --git a/lib/src/hidden_ranges/hidden_line_ranges_builder.dart b/lib/src/hidden_ranges/hidden_line_ranges_builder.dart index 8791bdd2..eef189ea 100644 --- a/lib/src/hidden_ranges/hidden_line_ranges_builder.dart +++ b/lib/src/hidden_ranges/hidden_line_ranges_builder.dart @@ -60,7 +60,6 @@ class HiddenLineRangesBuilder { hiddenLineRanges: HiddenLineRanges( breakpoints: breakpoints, fullLineCount: codeLines.lines.length, - visibleLineCount: codeLines.lines.length - spread, ), ); } diff --git a/lib/src/hidden_ranges/hidden_ranges.dart b/lib/src/hidden_ranges/hidden_ranges.dart index 050b480f..27a9b8cc 100644 --- a/lib/src/hidden_ranges/hidden_ranges.dart +++ b/lib/src/hidden_ranges/hidden_ranges.dart @@ -307,7 +307,7 @@ class HiddenRanges { } } - /// Translates the [selection] of the full text + /// Translates the [selection] of the full text /// to selection of the visible text. TextSelection cutSelection(TextSelection selection) { if (selection.isCollapsed) { diff --git a/test/src/hidden_ranges/hidden_line_ranges_builder_test.dart b/test/src/hidden_ranges/hidden_line_ranges_builder_test.dart index b3e727bb..f5f17023 100644 --- a/test/src/hidden_ranges/hidden_line_ranges_builder_test.dart +++ b/test/src/hidden_ranges/hidden_line_ranges_builder_test.dart @@ -29,7 +29,6 @@ void main() { const HiddenLineRanges( breakpoints: [], fullLineCount: 1, - visibleLineCount: 1, ), ); }); @@ -45,7 +44,6 @@ void main() { const HiddenLineRanges( breakpoints: [], fullLineCount: 15, - visibleLineCount: 15, ), ); }); @@ -86,7 +84,6 @@ void main() { const HiddenLineRanges( breakpoints: [], fullLineCount: 15, - visibleLineCount: 15, ), ); }); @@ -130,7 +127,6 @@ void main() { LineNumberingBreakpoint(full: 14, visible: 10, spreadBefore: 2), ], fullLineCount: 15, - visibleLineCount: 11, ), ); }); @@ -174,7 +170,6 @@ void main() { LineNumberingBreakpoint(full: 15, visible: 10, spreadBefore: 2), ], fullLineCount: 15, - visibleLineCount: 9, ), ); }); diff --git a/test/src/hidden_ranges/hidden_line_ranges_test.dart b/test/src/hidden_ranges/hidden_line_ranges_test.dart index 036aba86..7f5f7842 100644 --- a/test/src/hidden_ranges/hidden_line_ranges_test.dart +++ b/test/src/hidden_ranges/hidden_line_ranges_test.dart @@ -6,7 +6,6 @@ void main() { const noBreakpointsRanges = HiddenLineRanges( breakpoints: [], fullLineCount: 10, - visibleLineCount: 10, ); const midBreakpointsRanges = HiddenLineRanges( @@ -14,9 +13,11 @@ void main() { LineNumberingBreakpoint(full: 4, visible: 2, spreadBefore: 0), LineNumberingBreakpoint(full: 9, visible: 5, spreadBefore: 2), LineNumberingBreakpoint(full: 100, visible: 12, spreadBefore: 4), + LineNumberingBreakpoint(full: 210, visible: 113, spreadBefore: 88), + LineNumberingBreakpoint(full: 220, visible: 115, spreadBefore: 97), + LineNumberingBreakpoint(full: 230, visible: 118, spreadBefore: 105), ], - fullLineCount: 110, - visibleLineCount: 22, + fullLineCount: 231, ); const startEndHiddenRanges = HiddenLineRanges( @@ -25,7 +26,6 @@ void main() { LineNumberingBreakpoint(full: 10, visible: 5, spreadBefore: 3), ], fullLineCount: 10, - visibleLineCount: 5, ); group('HiddenLineRanges.', () { @@ -56,6 +56,9 @@ void main() { expect(midBreakpointsRanges.cutLineIndexIfVisible(100), 12); expect(midBreakpointsRanges.cutLineIndexIfVisible(101), 13); expect(midBreakpointsRanges.cutLineIndexIfVisible(200), 112); + expect(midBreakpointsRanges.cutLineIndexIfVisible(209), null); + expect(midBreakpointsRanges.cutLineIndexIfVisible(219), null); + expect(midBreakpointsRanges.cutLineIndexIfVisible(229), null); }); }); @@ -75,7 +78,10 @@ void main() { 0, 1, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + ...List.generate(200 - 100 + 1, (i) => i + 100), // 100-200 + 210, 211, + 220, 221, 222, + 230, ], ); });