Class: PatienceDiff::Differ
- Inherits:
-
Object
- Object
- PatienceDiff::Differ
- Defined in:
- lib/patience_diff/differ.rb
Instance Attribute Summary collapse
-
#all_context ⇒ Object
Returns the value of attribute all_context.
-
#ignore_whitespace ⇒ Object
Returns the value of attribute ignore_whitespace.
-
#line_ending ⇒ Object
Returns the value of attribute line_ending.
-
#matcher ⇒ Object
readonly
Returns the value of attribute matcher.
Instance Method Summary collapse
-
#diff_files(left_file, right_file, formatter = Formatter.new) ⇒ Object
Generates a unified diff from the contents of the files at the paths specified.
-
#diff_sequences(left, right, left_name = nil, right_name = nil, left_timestamp = nil, right_timestamp = nil, formatter = Formatter.new) ⇒ Object
Generate a unified diff of the data specified.
-
#initialize(opts = {}) ⇒ Differ
constructor
Options: * :all_context: Output the entirety of each file.
Constructor Details
#initialize(opts = {}) ⇒ Differ
Options:
* :all_context: Output the entirety of each file. This overrides the sequence matcher's context setting.
* :line_ending: Delimiter to use when joining diff output. Defaults to $RS.
* :ignore_whitespace: Before comparing lines, strip trailing whitespace, and treat leading whitespace
as either present or not. Does not affect output.
Any additional options (e.g. :context) are passed on to the sequence matcher.
16 17 18 19 20 21 |
# File 'lib/patience_diff/differ.rb', line 16 def initialize(opts = {}) @all_context = opts.delete(:all_context) @line_ending = opts.delete(:line_ending) || $RS @ignore_whitespace = opts.delete(:ignore_whitespace) @matcher = SequenceMatcher.new(opts) end |
Instance Attribute Details
#all_context ⇒ Object
Returns the value of attribute all_context.
8 9 10 |
# File 'lib/patience_diff/differ.rb', line 8 def all_context @all_context end |
#ignore_whitespace ⇒ Object
Returns the value of attribute ignore_whitespace.
8 9 10 |
# File 'lib/patience_diff/differ.rb', line 8 def ignore_whitespace @ignore_whitespace end |
#line_ending ⇒ Object
Returns the value of attribute line_ending.
8 9 10 |
# File 'lib/patience_diff/differ.rb', line 8 def line_ending @line_ending end |
#matcher ⇒ Object (readonly)
Returns the value of attribute matcher.
7 8 9 |
# File 'lib/patience_diff/differ.rb', line 7 def matcher @matcher end |
Instance Method Details
#diff_files(left_file, right_file, formatter = Formatter.new) ⇒ Object
Generates a unified diff from the contents of the files at the paths specified.
24 25 26 27 28 29 30 31 32 |
# File 'lib/patience_diff/differ.rb', line 24 def diff_files(left_file, right_file, formatter=Formatter.new) (left_data, ), (right_data, ) = [left_file, right_file].map do |filename| # Read in binary encoding, so that we can diff any encoding and split() won't complain File.open(filename, :external_encoding => Encoding::BINARY) do |file| [file.read.split($RS), file.mtime] end end diff_sequences(left_data, right_data, left_file, right_file, , , formatter) end |
#diff_sequences(left, right, left_name = nil, right_name = nil, left_timestamp = nil, right_timestamp = nil, formatter = Formatter.new) ⇒ Object
Generate a unified diff of the data specified. The left and right values should be strings, or any other indexable, sortable data. File names and timestamps do not affect the diff algorithm, but are used in the header text.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/patience_diff/differ.rb', line 36 def diff_sequences(left, right, left_name=nil, right_name=nil, =nil, =nil, formatter=Formatter.new) if @ignore_whitespace a = left.map { |line| line.rstrip.gsub(/^\s+/, ' ') } b = right.map { |line| line.rstrip.gsub(/^\s+/, ' ') } else a = left b = right end if @all_context hunks = [@matcher.diff_opcodes(a, b)] else hunks = @matcher.grouped_opcodes(a, b) end return nil unless hunks.any? lines = [] lines << formatter.render_header(left_name, right_name, , ) last_hunk_end = -1 hunks.each do |opcodes| lines << formatter.render_hunk(a, b, opcodes, last_hunk_end) last_hunk_end = opcodes.last[4] end lines.flatten.compact.join(@line_ending) + @line_ending end |