git_spelunk 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d134035b13ff89d17adbfcf99948fbb3d2dbea8f
4
- data.tar.gz: 6c11e700075909ed8c9784d442437f1ac9ef8d09
3
+ metadata.gz: 4a7fa06da8d61e779a69fb28667bf618cf067a15
4
+ data.tar.gz: 0e60161a7aea4de66fec9a6f64d7a164be6a4aba
5
5
  SHA512:
6
- metadata.gz: 9b7870d7e485b8d8010256e8128ed7e0488d767043fc229017c6b274c52225900f914b5d89996f90d0ba823d2281847a26e08ab16286817c5abd035333f5f2d0
7
- data.tar.gz: 2904e99c0ea0c88bf39e9082656b6481cd2a0b61c8d069dc1f6596aeb720d5f2654cde84aebf2413e7d5763597e2486d081d8699befb396eb606ac7b1c153e9e
6
+ metadata.gz: 52d04a313b56ea8297514a270d62af51c10985cbc600361ad5e4ecf1ed603f312c41da7fd97a0e54fe7be2c2c1b1a52fe1253479ccb882b51ea0d8aad3af4424
7
+ data.tar.gz: 9841ab6897ab0bfbc3abbbee1cf59331591393cfc6a13f0d9ac60d2af3711cf8c25a4623b5b8a34d66d273d1160d01ed0120f12a5c4eaaf23cd7e3d054ebe153
@@ -47,121 +47,134 @@ module GitSpelunk
47
47
  true
48
48
  end
49
49
 
50
- def chunks
51
- @chunks ||= diff_chunks(@repo.diff(@parent.id, @sha, @file_name))
52
- end
53
-
54
- def at_beginning_of_time?
55
- @parent.nil?
56
- end
57
-
58
- def unable_to_trace_lineage?
59
- @parent && (@chunks.nil? || target_chunk.nil?)
60
- end
50
+ STATS_PATTERN=/@@ \-(\d+),(\d+) \+(\d+),(\d+) @@/
51
+ class Chunk
52
+ attr_reader :minus_offset, :minus_length, :plus_offset, :plus_length, :lines
61
53
 
62
- def first_commit_for_file?
54
+ def initialize(data)
55
+ @minus_offset, @minus_length, @plus_offset, @plus_length = *extract_stats(data[0])
56
+ @lines = data[1..-1]
57
+ end
63
58
 
64
- end
59
+ def has_line?(line_number)
60
+ plus_offset <= line_number && line_number <= (plus_offset + plus_length)
61
+ end
65
62
 
66
- def line_number_to_parent
67
- return :at_beginning_of_time unless @parent && chunks
68
- chunk = target_chunk(@line_number)
69
- return :unable_to_trace unless chunk
63
+ LineBlock = Struct.new(:offset, :data) do
64
+ def initialize(offset, line)
65
+ super(offset, [line])
66
+ end
70
67
 
71
- parent_starting_line, parent_total_lines = parent_start_and_total(stats_line(chunk))
72
- return :first_commit_for_file if parent_starting_line == 0 && parent_total_lines == 0
68
+ def type
69
+ data.first[0]
70
+ end
73
71
 
74
- chunk_starting_line, chunk_total_lines = src_start_and_total(stats_line(chunk))
75
- parent_line_offset = find_parent_line_number(diff_lines(chunk), @line_number, chunk_starting_line, chunk_total_lines)
76
- parent_starting_line + parent_line_offset
77
- end
72
+ def size
73
+ data.size
74
+ end
78
75
 
79
- private
76
+ def <<(other)
77
+ data << other
78
+ end
79
+ end
80
80
 
81
- def diff_chunks(diffs)
82
- return nil if diffs.empty?
83
- # split it into chunks: [["@@ -10,13 +10,18 @@", diffs], ["@@ -20,13 +20,18 @@", diffs, diff]]
84
- multiple_chunks = diffs[0].diff.split(/(@@ \-\d+,\d+ \+\d+,\d+ @@.*?\n)/)
85
- # Discard file name line
86
- multiple_chunks[1..multiple_chunks.length].each_slice(2).to_a
87
- end
81
+ def find_parent_line_number(target)
82
+ # separate in blocks of lines with the same prefix
88
83
 
84
+ old_line_number = minus_offset
85
+ new_line_number = plus_offset
89
86
 
90
- def target_chunk(line_number)
91
- chunks.select {|chunk| has_line?(chunk, line_number)}[0]
92
- end
87
+ blocks = []
88
+ lines.each do |l|
89
+ next if l =~ /\/
90
+ last_block = blocks.last
93
91
 
94
- def has_line?(chunk, line_number)
95
- starting_line, total_lines = src_start_and_total(stats_line(chunk))
96
- starting_line + total_lines >= line_number
97
- end
92
+ if last_block.nil? || last_block.type != l[0]
93
+ blocks << LineBlock.new(old_line_number, l)
94
+ else
95
+ last_block << l
96
+ end
98
97
 
99
- def src_start_and_total(line)
100
- # Get the offset and line number where lines were added
101
- # @@ -3,10 +3,17 @@ optionally a line\n unchnaged_line_1\n- deleted_line_1\n+ new_line_1"
102
- line.scan(/\+(\d+),(\d+)/).first.map { |str| str.to_i }
103
- end
98
+ if l[0] == "+" || l[0] == " "
99
+ if new_line_number == target
100
+ # important: we don't finish building the structure.
101
+ break
102
+ end
104
103
 
105
- def parent_start_and_total(line)
106
- line.scan(/\-(\d+),(\d+)/).first.map { |str| str.to_i }
107
- end
104
+ new_line_number += 1
105
+ end
108
106
 
109
- def find_parent_line_number(lines, src_line_number, src_starting_line, src_number_of_lines)
110
- target_line_offset = src_line_number - src_starting_line
111
- current_line_offset = parent_line_offset = diff_index = 0
107
+ if l[0] == "-" || l[0] == " "
108
+ old_line_number += 1
109
+ end
110
+ end
112
111
 
113
- lines.each do |line|
114
- break if current_line_offset == target_line_offset && src_line?(line)
112
+ addition_block = blocks.pop
113
+ last_old_block = blocks.last
115
114
 
116
- if src_line?(line)
117
- current_line_offset += 1
115
+ if last_old_block.type == " "
116
+ last_old_block.offset + (last_old_block.size - 1)
117
+ else
118
+ # offset N lines into last block, but don't go beyond the edge of it.
119
+ last_old_block.offset + [addition_block.size - 1, last_old_block.size].min
118
120
  end
121
+ end
119
122
 
120
- if parent_line?(line)
121
- parent_line_offset += 1
122
- end
123
+ private
123
124
 
124
- diff_index += 1
125
+ def extract_stats(l)
126
+ #@@ -1,355 +1,355 @@
127
+ l.scan(STATS_PATTERN).first.map(&:to_i)
125
128
  end
126
129
 
127
- # find last contiguous bit of diff, and try to offset into that.
128
- removals = additions = 0
129
- diff_index -= 1
130
-
131
- while diff_index > 0
132
- line = lines[diff_index]
130
+ def old_has?(line)
131
+ # Src line will either have a "+" or will be an unchanged line
132
+ line[0] == '-' || line[0] == " "
133
+ end
133
134
 
134
- break unless ["-", "+"].include?(line[0])
135
+ def new_has?(line)
136
+ # Src line will either have a "-" or will be an unchanged line
137
+ line[0] == '+' || line[0] == " "
138
+ end
139
+ end
135
140
 
136
- if parent_line?(line)
137
- removals += 1
138
- else
139
- additions += 1
141
+ def chunks
142
+ @chunks ||= begin
143
+ diffs = @repo.diff(@parent.id, @sha, @file_name)
144
+ return nil if diffs.empty?
145
+
146
+ chunks = diffs[0].diff.split(/\n/).inject([[]]) do |arr, line|
147
+ arr.push([]) if line =~ STATS_PATTERN
148
+ arr.last << line
149
+ arr
140
150
  end
141
151
 
142
- diff_index -= 1
152
+ chunks[1..-1].map { |c| Chunk.new(c) } # slice off first chunk -- it's just the filename
143
153
  end
144
-
145
- forward_push = [additions, removals - 1].min
146
- (parent_line_offset - removals) + forward_push
147
154
  end
148
155
 
149
- def src_line?(line)
150
- # Src line will either have a "+" or will be an unchanged line
151
- line[0] != '-'
156
+ def at_beginning_of_time?
157
+ @parent.nil?
152
158
  end
153
159
 
154
- def parent_line?(line)
155
- # Src line will either have a "-" or will be an unchanged line
156
- line[0] != '+'
160
+ def unable_to_trace_lineage?
161
+ @parent && (@chunks.nil? || target_chunk.nil?)
157
162
  end
158
163
 
159
- def stats_line(chunk)
160
- chunk[0]
164
+ def line_number_to_parent
165
+ return :at_beginning_of_time unless @parent && chunks
166
+ chunk = target_chunk(@line_number)
167
+ return :unable_to_trace unless chunk
168
+
169
+ return :first_commit_for_file if chunk.minus_offset == 0 && chunk.minus_length == 0
170
+
171
+ chunk.find_parent_line_number(@line_number)
161
172
  end
162
173
 
163
- def diff_lines(chunk)
164
- chunk[1].split("\n")
174
+ private
175
+
176
+ def target_chunk(line_number)
177
+ chunks.find { |c| c.has_line?(line_number) }
165
178
  end
166
179
  end
167
180
  end
@@ -74,6 +74,7 @@ module GitSpelunk
74
74
  @file_context.line_number = @pager.cursor
75
75
  @history.push(@file_context)
76
76
 
77
+
77
78
  @file_context = @file_context.clone_for_blame_line(@pager.blame_line)
78
79
  @pager.data = @file_context.get_blame
79
80
  @pager.go_to(goto)
@@ -29,8 +29,8 @@ module GitSpelunk
29
29
 
30
30
  view = Array.new(@height)
31
31
 
32
- data[@top - 1,@height].each_with_index.map do |b, i|
33
- line = view[i] = ""
32
+ data[@top - 1, @height].each_with_index do |b, i|
33
+ line = ""
34
34
  sha, content = b.sha, b.content
35
35
 
36
36
  line_number = i + @top
@@ -47,7 +47,8 @@ module GitSpelunk
47
47
  line << sha_abbrev
48
48
 
49
49
  line << " %*s " % [line_number_width, line_number]
50
- line << content
50
+ line << content.gsub(/\r/, '')
51
+
51
52
 
52
53
  content_start = (sha_abbrev.size + line_number_width + 2)
53
54
 
@@ -57,8 +58,8 @@ module GitSpelunk
57
58
  styles.add(FOUND_COLOR, i, found...(found + @search_term.size))
58
59
  end
59
60
  end
60
- end.join("\n")
61
-
61
+ view[i] = line
62
+ end
62
63
  [view, styles]
63
64
  end
64
65
 
@@ -1,3 +1,3 @@
1
1
  module GitSpelunk
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_spelunk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Osheroff
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-05-20 00:00:00.000000000 Z
12
+ date: 2015-09-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: grit