diff-lcs 1.3 → 1.6.2
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 +5 -5
- data/CHANGELOG.md +518 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +71 -0
- data/CONTRIBUTORS.md +49 -0
- data/{License.md → LICENCE.md} +21 -20
- data/Manifest.txt +84 -6
- data/README.md +92 -0
- data/Rakefile +104 -46
- data/SECURITY.md +41 -0
- data/bin/htmldiff +9 -6
- data/bin/ldiff +4 -1
- data/docs/artistic.txt +1 -1
- data/lib/diff/lcs/array.rb +2 -2
- data/lib/diff/lcs/backports.rb +13 -0
- data/lib/diff/lcs/block.rb +5 -5
- data/lib/diff/lcs/callbacks.rb +22 -17
- data/lib/diff/lcs/change.rb +44 -51
- data/lib/diff/lcs/htmldiff.rb +25 -14
- data/lib/diff/lcs/hunk.rb +174 -71
- data/lib/diff/lcs/internals.rb +57 -56
- data/lib/diff/lcs/ldiff.rb +101 -79
- data/lib/diff/lcs/string.rb +1 -1
- data/lib/diff/lcs/version.rb +7 -0
- data/lib/diff/lcs.rb +229 -212
- data/lib/diff-lcs.rb +2 -2
- data/mise.toml +5 -0
- data/spec/change_spec.rb +58 -34
- data/spec/diff_spec.rb +13 -9
- data/spec/fixtures/123_x +2 -0
- data/spec/fixtures/456_x +2 -0
- data/spec/fixtures/aX +1 -0
- data/spec/fixtures/bXaX +1 -0
- data/spec/fixtures/empty +0 -0
- data/spec/fixtures/file1.bin +0 -0
- data/spec/fixtures/file2.bin +0 -0
- data/spec/fixtures/four_lines +4 -0
- data/spec/fixtures/four_lines_with_missing_new_line +4 -0
- data/spec/fixtures/ldiff/diff.missing_new_line1-e +1 -0
- data/spec/fixtures/ldiff/diff.missing_new_line1-f +1 -0
- data/spec/fixtures/ldiff/diff.missing_new_line2-e +1 -0
- data/spec/fixtures/ldiff/diff.missing_new_line2-f +1 -0
- data/spec/fixtures/ldiff/error.diff.chef-e +2 -0
- data/spec/fixtures/ldiff/error.diff.chef-f +2 -0
- data/spec/fixtures/ldiff/error.diff.missing_new_line1-e +1 -0
- data/spec/fixtures/ldiff/error.diff.missing_new_line1-f +1 -0
- data/spec/fixtures/ldiff/error.diff.missing_new_line2-e +1 -0
- data/spec/fixtures/ldiff/error.diff.missing_new_line2-f +1 -0
- data/spec/fixtures/ldiff/output.diff +4 -0
- data/spec/fixtures/ldiff/output.diff-c +7 -0
- data/spec/fixtures/ldiff/output.diff-e +3 -0
- data/spec/fixtures/ldiff/output.diff-f +3 -0
- data/spec/fixtures/ldiff/output.diff-u +5 -0
- data/spec/fixtures/ldiff/output.diff.bin1 +0 -0
- data/spec/fixtures/ldiff/output.diff.bin1-c +0 -0
- data/spec/fixtures/ldiff/output.diff.bin1-e +0 -0
- data/spec/fixtures/ldiff/output.diff.bin1-f +0 -0
- data/spec/fixtures/ldiff/output.diff.bin1-u +0 -0
- data/spec/fixtures/ldiff/output.diff.bin2 +1 -0
- data/spec/fixtures/ldiff/output.diff.bin2-c +1 -0
- data/spec/fixtures/ldiff/output.diff.bin2-e +1 -0
- data/spec/fixtures/ldiff/output.diff.bin2-f +1 -0
- data/spec/fixtures/ldiff/output.diff.bin2-u +1 -0
- data/spec/fixtures/ldiff/output.diff.chef +4 -0
- data/spec/fixtures/ldiff/output.diff.chef-c +15 -0
- data/spec/fixtures/ldiff/output.diff.chef-e +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-f +3 -0
- data/spec/fixtures/ldiff/output.diff.chef-u +9 -0
- data/spec/fixtures/ldiff/output.diff.chef2 +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-c +20 -0
- data/spec/fixtures/ldiff/output.diff.chef2-d +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-e +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-f +7 -0
- data/spec/fixtures/ldiff/output.diff.chef2-u +16 -0
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines +5 -0
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e +6 -0
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f +6 -0
- data/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty +5 -0
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e +1 -0
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f +1 -0
- data/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context +4 -0
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e +3 -0
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f +3 -0
- data/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line1 +5 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line1-c +14 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line2 +5 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line2-c +14 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
- data/spec/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
- data/spec/fixtures/new-chef +4 -0
- data/spec/fixtures/new-chef2 +17 -0
- data/spec/fixtures/old-chef +4 -0
- data/spec/fixtures/old-chef2 +14 -0
- data/spec/hunk_spec.rb +49 -38
- data/spec/issues_spec.rb +132 -21
- data/spec/lcs_spec.rb +3 -3
- data/spec/ldiff_spec.rb +83 -30
- data/spec/patch_spec.rb +14 -20
- data/spec/sdiff_spec.rb +83 -81
- data/spec/spec_helper.rb +220 -165
- data/spec/traverse_balanced_spec.rb +138 -136
- data/spec/traverse_sequences_spec.rb +7 -9
- metadata +127 -77
- data/Code-of-Conduct.md +0 -74
- data/Contributing.md +0 -83
- data/History.md +0 -220
- data/README.rdoc +0 -84
- data/autotest/discover.rb +0 -1
data/lib/diff/lcs/hunk.rb
CHANGED
|
@@ -1,30 +1,44 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "diff/lcs/block"
|
|
4
4
|
|
|
5
|
-
# A Hunk is a group of Blocks which overlap because of the context
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# A Hunk is a group of Blocks which overlap because of the context surrounding
|
|
6
|
+
# each block. (So if we're not using context, every hunk will contain one
|
|
7
|
+
# block.) Used in the diff program (bin/ldiff).
|
|
8
8
|
class Diff::LCS::Hunk
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
|
10
|
+
ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
|
11
|
+
|
|
12
|
+
private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant)
|
|
13
|
+
|
|
14
|
+
# Create a hunk using references to both the old and new data, as well as the
|
|
15
|
+
# piece of data.
|
|
11
16
|
def initialize(data_old, data_new, piece, flag_context, file_length_difference)
|
|
12
17
|
# At first, a hunk will have just one Block in it
|
|
13
|
-
@blocks = [
|
|
18
|
+
@blocks = [Diff::LCS::Block.new(piece)]
|
|
19
|
+
|
|
20
|
+
if @blocks[0].remove.empty? && @blocks[0].insert.empty?
|
|
21
|
+
fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions"
|
|
22
|
+
end
|
|
23
|
+
|
|
14
24
|
if String.method_defined?(:encoding)
|
|
15
|
-
@preferred_data_encoding = data_old.fetch(0
|
|
25
|
+
@preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding
|
|
16
26
|
end
|
|
27
|
+
|
|
17
28
|
@data_old = data_old
|
|
18
29
|
@data_new = data_new
|
|
30
|
+
@old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?)
|
|
31
|
+
@new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?)
|
|
19
32
|
|
|
20
33
|
before = after = file_length_difference
|
|
21
34
|
after += @blocks[0].diff_size
|
|
22
35
|
@file_length_difference = after # The caller must get this manually
|
|
36
|
+
@max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
|
|
23
37
|
|
|
24
38
|
# Save the start & end of each array. If the array doesn't exist (e.g.,
|
|
25
|
-
# we're only adding items in this block), then figure out the line
|
|
26
|
-
#
|
|
27
|
-
#
|
|
39
|
+
# we're only adding items in this block), then figure out the line number
|
|
40
|
+
# based on the line number of the other file and the current difference in
|
|
41
|
+
# file lengths.
|
|
28
42
|
if @blocks[0].remove.empty?
|
|
29
43
|
a1 = a2 = nil
|
|
30
44
|
else
|
|
@@ -41,8 +55,8 @@ class Diff::LCS::Hunk
|
|
|
41
55
|
|
|
42
56
|
@start_old = a1 || (b1 - before)
|
|
43
57
|
@start_new = b1 || (a1 + before)
|
|
44
|
-
@end_old
|
|
45
|
-
@end_new
|
|
58
|
+
@end_old = a2 || (b2 - after)
|
|
59
|
+
@end_new = b2 || (a2 + after)
|
|
46
60
|
|
|
47
61
|
self.flag_context = flag_context
|
|
48
62
|
end
|
|
@@ -55,19 +69,24 @@ class Diff::LCS::Hunk
|
|
|
55
69
|
# Change the "start" and "end" fields to note that context should be added
|
|
56
70
|
# to this hunk.
|
|
57
71
|
attr_accessor :flag_context
|
|
58
|
-
undef :flag_context
|
|
59
|
-
def flag_context=(context)
|
|
60
|
-
return if context.nil?
|
|
72
|
+
undef :flag_context=
|
|
73
|
+
def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods
|
|
74
|
+
return if context.nil? || context.zero?
|
|
61
75
|
|
|
62
76
|
add_start = (context > @start_old) ? @start_old : context
|
|
77
|
+
|
|
63
78
|
@start_old -= add_start
|
|
64
79
|
@start_new -= add_start
|
|
65
80
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
old_size = @data_old.size
|
|
82
|
+
|
|
83
|
+
add_end =
|
|
84
|
+
if (@end_old + context) >= old_size
|
|
85
|
+
old_size - @end_old - 1
|
|
86
|
+
else
|
|
87
|
+
context
|
|
88
|
+
end
|
|
89
|
+
|
|
71
90
|
@end_old += add_end
|
|
72
91
|
@end_new += add_end
|
|
73
92
|
end
|
|
@@ -76,13 +95,11 @@ class Diff::LCS::Hunk
|
|
|
76
95
|
# a truthy value so that if there is no overlap, you can know the merge
|
|
77
96
|
# was skipped.
|
|
78
97
|
def merge(hunk)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
nil
|
|
85
|
-
end
|
|
98
|
+
return unless overlaps?(hunk)
|
|
99
|
+
|
|
100
|
+
@start_old = hunk.start_old
|
|
101
|
+
@start_new = hunk.start_new
|
|
102
|
+
blocks.unshift(*hunk.blocks)
|
|
86
103
|
end
|
|
87
104
|
alias_method :unshift, :merge
|
|
88
105
|
|
|
@@ -95,45 +112,59 @@ class Diff::LCS::Hunk
|
|
|
95
112
|
end
|
|
96
113
|
|
|
97
114
|
# Returns a diff string based on a format.
|
|
98
|
-
def diff(format)
|
|
115
|
+
def diff(format, last = false)
|
|
99
116
|
case format
|
|
100
117
|
when :old
|
|
101
|
-
old_diff
|
|
118
|
+
old_diff(last)
|
|
102
119
|
when :unified
|
|
103
|
-
unified_diff
|
|
120
|
+
unified_diff(last)
|
|
104
121
|
when :context
|
|
105
|
-
context_diff
|
|
122
|
+
context_diff(last)
|
|
106
123
|
when :ed
|
|
107
124
|
self
|
|
108
125
|
when :reverse_ed, :ed_finish
|
|
109
|
-
ed_diff(format)
|
|
126
|
+
ed_diff(format, last)
|
|
110
127
|
else
|
|
111
|
-
|
|
128
|
+
fail "Unknown diff format #{format}."
|
|
112
129
|
end
|
|
113
130
|
end
|
|
114
131
|
|
|
115
132
|
# Note that an old diff can't have any context. Therefore, we know that
|
|
116
133
|
# there's only one block in the hunk.
|
|
117
|
-
def old_diff
|
|
134
|
+
def old_diff(last = false)
|
|
118
135
|
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
|
119
|
-
op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
|
|
120
136
|
|
|
121
137
|
block = @blocks[0]
|
|
122
138
|
|
|
139
|
+
if last
|
|
140
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
|
141
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
|
142
|
+
end
|
|
143
|
+
|
|
123
144
|
# Calculate item number range. Old diff range is just like a context
|
|
124
145
|
# diff range, except the ranges are on one line with the action between
|
|
125
146
|
# them.
|
|
126
|
-
s = encode("#{context_range(:old)}#{
|
|
147
|
+
s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n")
|
|
127
148
|
# If removing anything, just print out all the remove lines in the hunk
|
|
128
149
|
# which is just all the remove lines in the block.
|
|
129
|
-
|
|
150
|
+
unless block.remove.empty?
|
|
151
|
+
@data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
s << encode("\\n") if old_missing_newline && !new_missing_newline
|
|
130
155
|
s << encode("---\n") if block.op == "!"
|
|
131
|
-
|
|
156
|
+
|
|
157
|
+
unless block.insert.empty?
|
|
158
|
+
@data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
s << encode("\\n") if new_missing_newline && !old_missing_newline
|
|
162
|
+
|
|
132
163
|
s
|
|
133
164
|
end
|
|
134
165
|
private :old_diff
|
|
135
166
|
|
|
136
|
-
def unified_diff
|
|
167
|
+
def unified_diff(last = false)
|
|
137
168
|
# Calculate item number range.
|
|
138
169
|
s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n")
|
|
139
170
|
|
|
@@ -148,75 +179,132 @@ class Diff::LCS::Hunk
|
|
|
148
179
|
# file -- don't take removed items into account.
|
|
149
180
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
|
150
181
|
|
|
151
|
-
|
|
182
|
+
# standard:disable Performance/UnfreezeString
|
|
183
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
|
184
|
+
# standard:enable Performance/UnfreezeString
|
|
185
|
+
|
|
186
|
+
last_block = blocks[-1]
|
|
187
|
+
|
|
188
|
+
if last
|
|
189
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
|
190
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
|
191
|
+
end
|
|
152
192
|
|
|
153
193
|
@blocks.each do |block|
|
|
154
194
|
block.remove.each do |item|
|
|
155
|
-
op
|
|
195
|
+
op = item.action.to_s # -
|
|
156
196
|
offset = item.position - lo + num_added
|
|
157
197
|
outlist[offset][0, 1] = encode(op)
|
|
158
198
|
num_removed += 1
|
|
159
199
|
end
|
|
200
|
+
|
|
201
|
+
if last && block == last_block && old_missing_newline && !new_missing_newline
|
|
202
|
+
outlist << encode('\')
|
|
203
|
+
num_removed += 1
|
|
204
|
+
end
|
|
205
|
+
|
|
160
206
|
block.insert.each do |item|
|
|
161
|
-
op
|
|
207
|
+
op = item.action.to_s # +
|
|
162
208
|
offset = item.position - @start_new + num_removed
|
|
163
|
-
outlist[offset, 0] = encode(op) + @data_new[item.position]
|
|
209
|
+
outlist[offset, 0] = encode(op) + @data_new[item.position].chomp
|
|
164
210
|
num_added += 1
|
|
165
211
|
end
|
|
166
212
|
end
|
|
167
213
|
|
|
214
|
+
outlist << encode('\') if last && new_missing_newline
|
|
215
|
+
|
|
168
216
|
s << outlist.join(encode("\n"))
|
|
217
|
+
|
|
218
|
+
s
|
|
169
219
|
end
|
|
170
220
|
private :unified_diff
|
|
171
221
|
|
|
172
|
-
def context_diff
|
|
222
|
+
def context_diff(last = false)
|
|
173
223
|
s = encode("***************\n")
|
|
174
|
-
s << encode("*** #{context_range(:old)} ****\n")
|
|
175
|
-
r = context_range(:new)
|
|
224
|
+
s << encode("*** #{context_range(:old, ",")} ****\n")
|
|
225
|
+
r = context_range(:new, ",")
|
|
226
|
+
|
|
227
|
+
if last
|
|
228
|
+
old_missing_newline = missing_last_newline?(@data_old)
|
|
229
|
+
new_missing_newline = missing_last_newline?(@data_new)
|
|
230
|
+
end
|
|
176
231
|
|
|
177
232
|
# Print out file 1 part for each block in context diff format if there
|
|
178
233
|
# are any blocks that remove items
|
|
179
234
|
lo, hi = @start_old, @end_old
|
|
180
|
-
removes = @blocks.
|
|
181
|
-
|
|
182
|
-
|
|
235
|
+
removes = @blocks.reject { |e| e.remove.empty? }
|
|
236
|
+
|
|
237
|
+
unless removes.empty?
|
|
238
|
+
# standard:disable Performance/UnfreezeString
|
|
239
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
|
240
|
+
# standard:enable Performance/UnfreezeString
|
|
241
|
+
|
|
242
|
+
last_block = removes[-1]
|
|
183
243
|
|
|
184
244
|
removes.each do |block|
|
|
185
245
|
block.remove.each do |item|
|
|
186
246
|
outlist[item.position - lo][0, 1] = encode(block.op) # - or !
|
|
187
247
|
end
|
|
248
|
+
|
|
249
|
+
if last && block == last_block && old_missing_newline
|
|
250
|
+
outlist << encode('\')
|
|
251
|
+
end
|
|
188
252
|
end
|
|
189
|
-
|
|
253
|
+
|
|
254
|
+
s << outlist.join(encode("\n")) << encode("\n")
|
|
190
255
|
end
|
|
191
256
|
|
|
192
|
-
s << encode("
|
|
257
|
+
s << encode("--- #{r} ----\n")
|
|
193
258
|
lo, hi = @start_new, @end_new
|
|
194
|
-
inserts = @blocks.
|
|
195
|
-
|
|
196
|
-
|
|
259
|
+
inserts = @blocks.reject { |e| e.insert.empty? }
|
|
260
|
+
|
|
261
|
+
unless inserts.empty?
|
|
262
|
+
# standard:disable Performance/UnfreezeString
|
|
263
|
+
outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
|
264
|
+
# standard:enable Performance/UnfreezeString
|
|
265
|
+
|
|
266
|
+
last_block = inserts[-1]
|
|
267
|
+
|
|
197
268
|
inserts.each do |block|
|
|
198
269
|
block.insert.each do |item|
|
|
199
270
|
outlist[item.position - lo][0, 1] = encode(block.op) # + or !
|
|
200
271
|
end
|
|
272
|
+
|
|
273
|
+
if last && block == last_block && new_missing_newline
|
|
274
|
+
outlist << encode('\')
|
|
275
|
+
end
|
|
201
276
|
end
|
|
202
|
-
s << outlist.join("\n")
|
|
277
|
+
s << outlist.join(encode("\n"))
|
|
203
278
|
end
|
|
279
|
+
|
|
204
280
|
s
|
|
205
281
|
end
|
|
206
282
|
private :context_diff
|
|
207
283
|
|
|
208
|
-
def ed_diff(format)
|
|
209
|
-
op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
|
|
284
|
+
def ed_diff(format, last)
|
|
210
285
|
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
286
|
+
if last
|
|
287
|
+
# ed script doesn't support well incomplete lines
|
|
288
|
+
warn "<old_file>: No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old)
|
|
289
|
+
warn "<new_file>: No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new)
|
|
290
|
+
|
|
291
|
+
if @blocks[0].op == "!"
|
|
292
|
+
return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n"
|
|
293
|
+
return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element
|
|
294
|
+
end
|
|
216
295
|
end
|
|
217
296
|
|
|
297
|
+
s =
|
|
298
|
+
if format == :reverse_ed
|
|
299
|
+
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n")
|
|
300
|
+
else
|
|
301
|
+
encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
|
|
302
|
+
end
|
|
303
|
+
|
|
218
304
|
unless @blocks[0].insert.empty?
|
|
219
|
-
@data_new[@start_new
|
|
305
|
+
@data_new[@start_new..@end_new].each do |e|
|
|
306
|
+
s << e.chomp + encode("\n")
|
|
307
|
+
end
|
|
220
308
|
s << encode(".\n")
|
|
221
309
|
end
|
|
222
310
|
s
|
|
@@ -225,7 +313,7 @@ class Diff::LCS::Hunk
|
|
|
225
313
|
|
|
226
314
|
# Generate a range of item numbers to print. Only print 1 number if the
|
|
227
315
|
# range has only one item in it. Otherwise, it's 'start,end'
|
|
228
|
-
def context_range(mode, op
|
|
316
|
+
def context_range(mode, op)
|
|
229
317
|
case mode
|
|
230
318
|
when :old
|
|
231
319
|
s, e = (@start_old + 1), (@end_old + 1)
|
|
@@ -233,7 +321,7 @@ class Diff::LCS::Hunk
|
|
|
233
321
|
s, e = (@start_new + 1), (@end_new + 1)
|
|
234
322
|
end
|
|
235
323
|
|
|
236
|
-
(s < e) ? "#{s}#{op}#{e}" :
|
|
324
|
+
(s < e) ? "#{s}#{op}#{e}" : e.to_s
|
|
237
325
|
end
|
|
238
326
|
private :context_range
|
|
239
327
|
|
|
@@ -243,17 +331,31 @@ class Diff::LCS::Hunk
|
|
|
243
331
|
def unified_range(mode)
|
|
244
332
|
case mode
|
|
245
333
|
when :old
|
|
334
|
+
return "0,0" if @old_empty
|
|
246
335
|
s, e = (@start_old + 1), (@end_old + 1)
|
|
247
336
|
when :new
|
|
337
|
+
return "0,0" if @new_empty
|
|
248
338
|
s, e = (@start_new + 1), (@end_new + 1)
|
|
249
339
|
end
|
|
250
340
|
|
|
251
341
|
length = e - s + 1
|
|
252
|
-
|
|
253
|
-
(length
|
|
342
|
+
|
|
343
|
+
(length <= 1) ? e.to_s : "#{s},#{length}"
|
|
254
344
|
end
|
|
255
345
|
private :unified_range
|
|
256
346
|
|
|
347
|
+
def missing_last_newline?(data)
|
|
348
|
+
newline = encode("\n")
|
|
349
|
+
|
|
350
|
+
if data[-2]
|
|
351
|
+
data[-2].end_with?(newline) && !data[-1].end_with?(newline)
|
|
352
|
+
elsif data[-1]
|
|
353
|
+
!data[-1].end_with?(newline)
|
|
354
|
+
else
|
|
355
|
+
true
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
257
359
|
if String.method_defined?(:encoding)
|
|
258
360
|
def encode(literal, target_encoding = @preferred_data_encoding)
|
|
259
361
|
literal.encode target_encoding
|
|
@@ -263,10 +365,11 @@ class Diff::LCS::Hunk
|
|
|
263
365
|
args.map { |arg| arg.encode(string.encoding) }
|
|
264
366
|
end
|
|
265
367
|
else
|
|
266
|
-
def encode(literal,
|
|
368
|
+
def encode(literal, _target_encoding = nil)
|
|
267
369
|
literal
|
|
268
370
|
end
|
|
269
|
-
|
|
371
|
+
|
|
372
|
+
def encode_as(_string, *args)
|
|
270
373
|
args
|
|
271
374
|
end
|
|
272
375
|
end
|