git_spelunk 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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