Module: RuVim::Git::Diff

Defined in:
lib/ruvim/git/diff.rb

Defined Under Namespace

Modules: HandlerMethods

Class Method Summary collapse

Class Method Details

.parse_location(lines, cursor_y) ⇒ Object

Parse diff output to find file and line number at cursor_y. Returns [filename, line_number] or nil.



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
# File 'lib/ruvim/git/diff.rb', line 26

def parse_location(lines, cursor_y)
  return nil if lines.empty? || cursor_y < 0 || cursor_y >= lines.length

  current_file = nil
  new_line = nil

  (0..cursor_y).each do |i|
    l = lines[i]
    case l
    when /\Adiff --git a\/.+ b\/(.+)/
      current_file = $1
    when /\A\+\+\+ b\/(.+)/
      current_file = $1
    when /\A@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/
      new_line = $1.to_i
    when /\A[ +]/
      # Context or added line: current new_line is this line's number
      new_line += 1 if new_line && i < cursor_y
    end
    # Deleted lines ("-") don't advance new_line
  end

  return nil unless current_file

  l = lines[cursor_y]
  case l
  when /\A@@ /
    # On hunk header: new_line already set
  when /\Adiff --git /, /\A---/, /\A\+\+\+/, /\Aindex /
    new_line ||= 1
  when /\A-/
    # Deleted line: point to current new-side position
  end

  [current_file, new_line || 1]
end

.run(file_path, args: []) ⇒ Object

Run git diff with optional extra args. Returns [lines, root, error_message].



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/ruvim/git/diff.rb', line 12

def run(file_path, args: [])
  root, err = Git.repo_root(file_path)
  return [nil, nil, err] unless root

  cmd = ["git", "diff", *args]
  out, err, status = Open3.capture3(*cmd, chdir: root)
  unless status.success?
    return [nil, nil, err.strip]
  end
  [out.lines(chomp: true), root, nil]
end