Module: Rvim::Diff
- Defined in:
- lib/rvim/diff.rb
Class Method Summary collapse
-
.compute(a, b) ⇒ Object
Compute per-line diff statuses for a vs b.
-
.hunk_starts(status) ⇒ Object
Returns an array of hunk start indices in the given status array.
- .lcs(a, b) ⇒ Object
Class Method Details
.compute(a, b) ⇒ Object
Compute per-line diff statuses for a vs b. Returns [a_status, b_status], each an array same length as its source where each entry is :common or :differs. Common lines are those that participate in the longest common subsequence between the two; everything else is marked :differs.
9 10 11 12 13 14 15 16 17 |
# File 'lib/rvim/diff.rb', line 9 def self.compute(a, b) a_status = Array.new(a.size, :differs) b_status = Array.new(b.size, :differs) lcs(a, b).each do |(i, j)| a_status[i] = :common b_status[j] = :common end [a_status, b_status] end |
.hunk_starts(status) ⇒ Object
Returns an array of hunk start indices in the given status array. A hunk starts at any :differs line that is preceded by :common (or at index 0 if the buffer starts with a differing line).
55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rvim/diff.rb', line 55 def self.hunk_starts(status) starts = [] status.each_with_index do |s, i| next unless s == :differs next if i.positive? && status[i - 1] == :differs starts << i end starts end |
.lcs(a, b) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rvim/diff.rb', line 19 def self.lcs(a, b) m = a.size n = b.size return [] if m.zero? || n.zero? dp = Array.new(m + 1) { Array.new(n + 1, 0) } (1..m).each do |i| (1..n).each do |j| dp[i][j] = if a[i - 1] == b[j - 1] dp[i - 1][j - 1] + 1 else [dp[i - 1][j], dp[i][j - 1]].max end end end pairs = [] i = m j = n while i > 0 && j > 0 if a[i - 1] == b[j - 1] pairs.unshift([i - 1, j - 1]) i -= 1 j -= 1 elsif dp[i - 1][j] >= dp[i][j - 1] i -= 1 else j -= 1 end end pairs end |