class TTY::File::Differ

Public Class Methods

new(format: :unified, context_lines: 3) click to toggle source

Create a Differ

@api public

# File lib/tty/file/differ.rb, line 12
def initialize(format: :unified, context_lines: 3)
  @format = format
  @context_lines = context_lines
end

Public Instance Methods

add_char() click to toggle source

Diff add char

@api public

# File lib/tty/file/differ.rb, line 37
def add_char
  case @format
  when :old
    ">"
  when :unified
    "+"
  else
    "*"
  end
end
call(string_a, string_b) click to toggle source

Find character difference between two strings

@return [String]

the difference between content or empty if no
difference found

@api public

# File lib/tty/file/differ.rb, line 24
def call(string_a, string_b)
  string_a_lines = convert_to_lines(string_a)
  string_b_lines = convert_to_lines(string_b)
  diffs = Diff::LCS.diff(string_a_lines, string_b_lines)
  return "" if diffs.empty?

  hunks = extract_hunks(diffs, string_a_lines, string_b_lines)
  format_hunks(hunks)
end
delete_char() click to toggle source

Diff delete char

@api public

# File lib/tty/file/differ.rb, line 51
def delete_char
  case @format
  when :old
    "<"
  when :unified
    "-"
  else
    "*"
  end
end

Private Instance Methods

convert_to_lines(string) click to toggle source

@api private

# File lib/tty/file/differ.rb, line 65
def convert_to_lines(string)
  string.split(/\n/).map(&:chomp)
end
extract_hunks(diffs, string_a_lines, string_b_lines) click to toggle source

@api private

# File lib/tty/file/differ.rb, line 70
def extract_hunks(diffs, string_a_lines, string_b_lines)
  file_length_difference = 0

  diffs.map do |piece|
    hunk = Diff::LCS::Hunk.new(string_a_lines, string_b_lines, piece,
                               @context_lines, file_length_difference)
    file_length_difference = hunk.file_length_difference
    hunk
  end
end
format_hunks(hunks) click to toggle source

@api private

# File lib/tty/file/differ.rb, line 82
def format_hunks(hunks)
  output = []
  hunks.each_cons(2) do |prev_hunk, current_hunk|
    begin
      if current_hunk.overlaps?(prev_hunk)
        current_hunk.unshift(prev_hunk)
      else
        output << prev_hunk.diff(@format).to_s
      end
    ensure
      output << "\n"
    end
  end
  output << hunks.last.diff(@format) << "\n" if hunks.last
  output.join
end