Class: DiffLineMapper
- Inherits:
-
Object
- Object
- DiffLineMapper
- Defined in:
- lib/vimamsa/diff_buffer.rb
Overview
Map a “line number in a unified diff output” to the corresponding line number in the *new/changed file* (the + side).
Key idea:
@@ -old_start,old_count +new_start,new_count @@
sets starting counters. Then walk each hunk line:
' ' => old++, new++
'-' => old++
'+' => new++
If the target diff line is:
' ' or '+' => it corresponds to current new line (before increment)
'-' => it has no new-file line (deleted). We return nil.
Constant Summary collapse
- HUNK_RE =
/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@/
Instance Method Summary collapse
-
#initialize(diff_text) ⇒ DiffLineMapper
constructor
A new instance of DiffLineMapper.
-
#new_line_for_diff_lineno(diff_lineno) ⇒ Object
Given a 1-based line number in the diff output, return: - Integer: 1-based line number in the new file - nil: if the diff line is a deletion (‘-’) or cannot be mapped.
Constructor Details
#initialize(diff_text) ⇒ DiffLineMapper
Returns a new instance of DiffLineMapper.
18 19 20 |
# File 'lib/vimamsa/diff_buffer.rb', line 18 def initialize(diff_text) @lines = diff_text.lines end |
Instance Method Details
#new_line_for_diff_lineno(diff_lineno) ⇒ Object
Given a 1-based line number in the diff output, return:
- Integer: 1-based line number in the new file
- nil: if the diff line is a deletion ('-') or cannot be mapped
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/vimamsa/diff_buffer.rb', line 25 def new_line_for_diff_lineno(diff_lineno) raise ArgumentError, "diff line number must be >= 1" if diff_lineno.to_i < 1 idx = diff_lineno.to_i - 1 return nil if idx >= @lines.length old = nil new_ = nil in_hunk = false @lines.each_with_index do |line, i| if (m = line.match(HUNK_RE)) old = m[1].to_i new_ = m[3].to_i in_hunk = true next end next unless in_hunk if line.start_with?('--- ', '+++ ') in_hunk = false old = new_ = nil next end if i == idx return nil unless new_ case line.getbyte(0) when '+'.ord then return new_ when ' '.ord then return new_ when '-'.ord then return nil else return nil end end next unless old && new_ case line.getbyte(0) when ' '.ord then old += 1; new_ += 1 when '-'.ord then old += 1 when '+'.ord then new_ += 1 end end nil end |