diff --git a/CHANGELOG.md b/CHANGELOG.md index 54626310..537596fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Add max major version constraints to dependencies. [#296](https://github.com/splitwise/super_diff/pull/296) - Remove unused `syntax_tree` gems from development. [#297](https://github.com/splitwise/super_diff/pull/297) +- Simplify tiered lines elider. [#302](https://github.com/splitwise/super_diff/pull/302) ## 0.18.0 - 2025-12-05 diff --git a/lib/super_diff/core/tiered_lines_elider.rb b/lib/super_diff/core/tiered_lines_elider.rb index 148ac6be..cdb12c66 100644 --- a/lib/super_diff/core/tiered_lines_elider.rb +++ b/lib/super_diff/core/tiered_lines_elider.rb @@ -41,16 +41,7 @@ def panes_to_consider_for_eliding def panes @panes ||= - BuildPanes.call(dirty_panes: padded_dirty_panes, lines: lines) - end - - def padded_dirty_panes - @padded_dirty_panes ||= - combine_congruent_panes( - dirty_panes - .map(&:padded) - .map { |pane| pane.capped_to(0, lines.size - 1) } - ) + BuildPanes.call(dirty_panes: dirty_panes, lines: lines) end def dirty_panes @@ -162,15 +153,22 @@ def box_groups_at_decreasing_indentation_levels_within(pane) end def filter_out_boxes_fully_contained_in_others(boxes) - sorted_boxes = - boxes.sort_by do |box| - [box.indentation_level, box.range.begin, box.range.end] - end - - boxes.reject do |box2| - sorted_boxes.any? do |box1| - !box1.equal?(box2) && box1.fully_contains?(box2) - end + # First, sorts boxes by beginning ascending, range descending. (Boxes may + # never share beginnings, so the latter may be useless, but this is at least + # sufficient if unnecessary.) + # + # Then, iterate through each box, keeping track of the farthest "end" of any + # box seen so far. If the current box we are on ends before (or on) that farthest + # end, we know there is some box earlier in the sequence that begins <= this one + # (because of the prior sorting), and ends >= this one; that is, the current box + # is fully contained, and we can filter it out. + sorted = boxes.sort_by { |box| [box.range.begin, -box.range.end] } + max_end = -1 + + sorted.reject do |box| + contained = box.range.end <= max_end + max_end = box.range.end if box.range.end > max_end + contained end end @@ -178,10 +176,6 @@ def combine_congruent_boxes(boxes) combine(boxes, on: :indentation_level) end - def combine_congruent_panes(panes) - combine(panes, on: :type) - end - def combine(spannables, on:) criterion = on spannables.reduce([]) do |combined_spannables, spannable| @@ -347,19 +341,6 @@ class Pane def extended_to(new_end) self.class.new(type: type, range: range.begin..new_end) end - - def padded - self.class.new(type: type, range: Range.new(range.begin, range.end)) - end - - def capped_to(beginning, ending) - new_beginning = [range.begin, beginning].max - new_ending = [range.end, ending].min - self.class.new( - type: type, - range: Range.new(new_beginning, new_ending) - ) - end end class BuildBoxes