class SuperDiff::TieredLinesElider
Constants
- SIZE_OF_ELISION
Public Instance Methods
call()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 10 def call if all_lines_are_changed_or_unchanged? lines else elided_lines end end
Private Instance Methods
all_indentation_levels()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 108 def all_indentation_levels lines. map(&:indentation_level). select { |indentation_level| indentation_level > 0 }. uniq end
all_lines_are_changed_or_unchanged?()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 20 def all_lines_are_changed_or_unchanged? panes.size == 1 && panes.first.range == Range.new(0, lines.length - 1) end
box_groups_at_decreasing_indentation_levels_within(pane)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 145 def box_groups_at_decreasing_indentation_levels_within(pane) boxes_within_pane = boxes.select do |box| box.fits_fully_within?(pane) end possible_indentation_levels = boxes_within_pane. map(&:indentation_level). select { |indentation_level| indentation_level > 0 }. uniq. sort. reverse possible_indentation_levels.map do |indentation_level| boxes_within_pane.select do |box| box.indentation_level >= indentation_level end end end
boxes()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 202 def boxes @_boxes ||= BuildBoxes.call(lines) end
boxes_to_elide()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 30 def boxes_to_elide @_boxes_to_elide ||= panes_to_consider_for_eliding.reduce([]) do |array, pane| array + (find_boxes_to_elide_within(pane) || []) end end
combine(spannables, on:)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 184 def combine(spannables, on:) criterion = on spannables.reduce([]) do |combined_spannables, spannable| if ( !combined_spannables.empty? && spannable.range.begin <= combined_spannables.last.range.end + 1 && spannable.public_send(criterion) == combined_spannables.last.public_send(criterion) ) combined_spannables[0..-2] + [ combined_spannables[-1].extended_to(spannable.range.end), ] else combined_spannables + [spannable] end end end
combine_congruent_boxes(boxes)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 176 def combine_congruent_boxes(boxes) combine(boxes, on: :indentation_level) end
combine_congruent_panes(panes)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 180 def combine_congruent_panes(panes) combine(panes, on: :type) end
dirty_panes()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 55 def dirty_panes @_dirty_panes ||= lines. each_with_index. select { |line, index| line.type != :noop }. reduce([]) do |panes, (_, index)| if !panes.empty? && panes.last.range.end == index - 1 panes[0..-2] + [panes[-1].extended_to(index)] else panes + [Pane.new(type: :dirty, range: index..index)] end end end
elided_lines()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 24 def elided_lines boxes_to_elide.reverse.reduce(lines) do |lines_with_elisions, box| with_box_elided(box, lines_with_elisions) end end
filter_out_boxes_fully_contained_in_others(boxes)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 164 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 end end
find_boxes_to_elide_within(pane)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 115 def find_boxes_to_elide_within(pane) set_of_boxes = normalized_box_groups_at_decreasing_indentation_levels_within(pane) total_size_before_eliding = lines[pane.range]. reject(&:complete_bookend?). size if total_size_before_eliding > maximum if maximum > 0 set_of_boxes.find do |boxes| total_size_after_eliding = total_size_before_eliding - boxes.sum { |box| box.range.size - SIZE_OF_ELISION } total_size_after_eliding <= maximum end else set_of_boxes[-1] end else [] end end
maximum()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 278 def maximum SuperDiff.configuration.diff_elision_maximum || 0 end
normalized_box_groups_at_decreasing_indentation_levels_within(pane)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 139 def normalized_box_groups_at_decreasing_indentation_levels_within(pane) box_groups_at_decreasing_indentation_levels_within(pane). map(&method(:filter_out_boxes_fully_contained_in_others)). map(&method(:combine_congruent_boxes)) end
one_dimensional_line_tree?()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 104 def one_dimensional_line_tree? all_indentation_levels.size == 1 end
outermost_box?(box)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 100 def outermost_box?(box) box.indentation_level == all_indentation_levels.min end
padded_dirty_panes()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 47 def padded_dirty_panes @_padded_dirty_panes ||= combine_congruent_panes( dirty_panes. map(&:padded). map { |pane| pane.capped_to(0, lines.size - 1) } ) end
panes()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 43 def panes @_panes ||= BuildPanes.call(dirty_panes: padded_dirty_panes, lines: lines) end
panes_to_consider_for_eliding()
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 37 def panes_to_consider_for_eliding panes.select do |pane| pane.type == :clean && pane.range.size > maximum end end
with_box_elided(box, lines)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 68 def with_box_elided(box, lines) box_at_start_of_lines = if lines.first.complete_bookend? box.range.begin == 1 else box.range.begin == 0 end box_at_end_of_lines = if lines.last.complete_bookend? box.range.end == lines.size - 2 else box.range.end == lines.size - 1 end if one_dimensional_line_tree? && outermost_box?(box) if box_at_start_of_lines with_start_of_box_elided(box, lines) elsif box_at_end_of_lines with_end_of_box_elided(box, lines) else with_middle_of_box_elided(box, lines) end else with_subset_of_lines_elided( lines, range: box.range, indentation_level: box.indentation_level, ) end end
with_end_of_box_elided(box, lines)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 224 def with_end_of_box_elided(box, lines) amount_to_elide = if maximum > 0 box.range.size - maximum + SIZE_OF_ELISION else box.range.size end range = if amount_to_elide > 0 Range.new(box.range.end - amount_to_elide + 1, box.range.end) else box.range end with_subset_of_lines_elided( lines, range: range, indentation_level: box.indentation_level ) end
with_middle_of_box_elided(box, lines)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 246 def with_middle_of_box_elided(box, lines) half_of_maximum, remainder = if maximum > 0 (maximum - SIZE_OF_ELISION).divmod(2) else [0, 0] end opening_length, closing_length = half_of_maximum, half_of_maximum + remainder with_subset_of_lines_elided( lines, range: Range.new( box.range.begin + opening_length, box.range.end - closing_length, ), indentation_level: box.indentation_level ) end
with_start_of_box_elided(box, lines)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 206 def with_start_of_box_elided(box, lines) amount_to_elide = if maximum > 0 box.range.size - maximum + SIZE_OF_ELISION else box.range.size end with_subset_of_lines_elided( lines, range: Range.new( box.range.begin, box.range.begin + amount_to_elide - 1, ), indentation_level: box.indentation_level ) end
with_subset_of_lines_elided(lines, range:, indentation_level:)
click to toggle source
# File lib/super_diff/tiered_lines_elider.rb, line 267 def with_subset_of_lines_elided(lines, range:, indentation_level:) with_slice_of_array_replaced( lines, range, Elision.new( indentation_level: indentation_level, children: lines[range].map(&:as_elided), ), ) end