diff-lcs 1.3 → 1.4.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/Contributing.md +1 -0
- data/History.md +196 -153
- data/Manifest.txt +8 -0
- data/README.rdoc +9 -10
- data/Rakefile +4 -21
- data/autotest/discover.rb +3 -1
- data/bin/htmldiff +7 -4
- data/bin/ldiff +4 -1
- data/lib/diff-lcs.rb +1 -1
- data/lib/diff/lcs.rb +177 -170
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +9 -0
- data/lib/diff/lcs/block.rb +2 -2
- data/lib/diff/lcs/callbacks.rb +15 -12
- data/lib/diff/lcs/change.rb +30 -37
- data/lib/diff/lcs/htmldiff.rb +17 -16
- data/lib/diff/lcs/hunk.rb +67 -52
- data/lib/diff/lcs/internals.rb +36 -39
- data/lib/diff/lcs/ldiff.rb +33 -25
- data/lib/diff/lcs/string.rb +1 -1
- data/spec/change_spec.rb +31 -7
- data/spec/diff_spec.rb +16 -12
- data/spec/fixtures/aX +1 -0
- data/spec/fixtures/bXaX +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/hunk_spec.rb +20 -20
- data/spec/issues_spec.rb +59 -10
- data/spec/lcs_spec.rb +10 -10
- data/spec/ldiff_spec.rb +62 -29
- data/spec/patch_spec.rb +93 -99
- data/spec/sdiff_spec.rb +89 -89
- data/spec/spec_helper.rb +115 -63
- data/spec/traverse_balanced_spec.rb +173 -173
- data/spec/traverse_sequences_spec.rb +28 -28
- metadata +30 -30
data/lib/diff/lcs/array.rb
CHANGED
data/lib/diff/lcs/block.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# A block is an operation removing, adding, or changing a group of items.
|
4
4
|
# Basically, this is just a list of changes, where each change adds or
|
@@ -19,7 +19,7 @@ class Diff::LCS::Block
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def diff_size
|
22
|
-
@insert.size - @remove.size
|
22
|
+
(@insert.size - @remove.size).abs
|
23
23
|
end
|
24
24
|
|
25
25
|
def op
|
data/lib/diff/lcs/callbacks.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'diff/lcs/change'
|
4
4
|
|
5
|
-
module Diff::LCS
|
5
|
+
module Diff::LCS # rubocop:disable Style/Documentation
|
6
6
|
# This callback object implements the default set of callback events,
|
7
7
|
# which only returns the event itself. Note that #finished_a and
|
8
8
|
# #finished_b are not implemented -- I haven't yet figured out where they
|
@@ -17,14 +17,17 @@ module Diff::LCS
|
|
17
17
|
def match(event)
|
18
18
|
event
|
19
19
|
end
|
20
|
+
|
20
21
|
# Called when the old value is discarded in favour of the new value.
|
21
22
|
def discard_a(event)
|
22
23
|
event
|
23
24
|
end
|
25
|
+
|
24
26
|
# Called when the new value is discarded in favour of the old value.
|
25
27
|
def discard_b(event)
|
26
28
|
event
|
27
29
|
end
|
30
|
+
|
28
31
|
# Called when both the old and new values have changed.
|
29
32
|
def change(event)
|
30
33
|
event
|
@@ -108,12 +111,12 @@ class Diff::LCS::DiffCallbacks
|
|
108
111
|
@hunk = []
|
109
112
|
@diffs = []
|
110
113
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
return unless block_given?
|
115
|
+
|
116
|
+
begin
|
117
|
+
yield self
|
118
|
+
ensure
|
119
|
+
finish
|
117
120
|
end
|
118
121
|
end
|
119
122
|
|
@@ -123,7 +126,7 @@ class Diff::LCS::DiffCallbacks
|
|
123
126
|
finish_hunk
|
124
127
|
end
|
125
128
|
|
126
|
-
def match(
|
129
|
+
def match(_event)
|
127
130
|
finish_hunk
|
128
131
|
end
|
129
132
|
|
@@ -190,7 +193,7 @@ end
|
|
190
193
|
# Diff::LCS::SDiffCallbacks. They may be compared as:
|
191
194
|
#
|
192
195
|
# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
|
193
|
-
# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
|
196
|
+
# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1)
|
194
197
|
#
|
195
198
|
# s == c # -> true
|
196
199
|
#
|
@@ -241,7 +244,7 @@ end
|
|
241
244
|
# will compute and display the necessary components to show two sequences
|
242
245
|
# and their minimized differences side by side, just like the Unix utility
|
243
246
|
# +sdiff+.
|
244
|
-
#
|
247
|
+
#
|
245
248
|
# same same
|
246
249
|
# before | after
|
247
250
|
# old < -
|
@@ -270,7 +273,7 @@ end
|
|
270
273
|
# Diff::LCS::ContextDiffCallbacks. They may be compared as:
|
271
274
|
#
|
272
275
|
# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
|
273
|
-
# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
|
276
|
+
# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1)
|
274
277
|
#
|
275
278
|
# s == c # -> true
|
276
279
|
#
|
data/lib/diff/lcs/change.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Represents a simplistic (non-contextual) change. Represents the removal or
|
4
4
|
# addition of an element from either the old or the new sequenced
|
5
5
|
# enumerable.
|
6
6
|
class Diff::LCS::Change
|
7
|
-
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4
|
7
|
+
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # rubocop:disable Naming/ConstantName
|
8
8
|
|
9
9
|
# The only actions valid for changes are '+' (add), '-' (delete), '='
|
10
10
|
# (no change), '!' (changed), '<' (tail changes from first sequence), or
|
11
11
|
# '>' (tail changes from second sequence). The last two ('<>') are only
|
12
12
|
# found with Diff::LCS::diff and Diff::LCS::sdiff.
|
13
|
-
VALID_ACTIONS = %
|
13
|
+
VALID_ACTIONS = %w(+ - = ! > <).freeze
|
14
14
|
|
15
15
|
def self.valid_action?(action)
|
16
16
|
VALID_ACTIONS.include? action
|
@@ -27,20 +27,20 @@ class Diff::LCS::Change
|
|
27
27
|
def initialize(*args)
|
28
28
|
@action, @position, @element = *args
|
29
29
|
|
30
|
-
unless Diff::LCS::Change.valid_action?(@action)
|
31
|
-
|
32
|
-
end
|
33
|
-
raise "Invalid Position Type" unless @position.kind_of? IntClass
|
30
|
+
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
31
|
+
fail 'Invalid Position Type' unless @position.kind_of? IntClass
|
34
32
|
end
|
35
33
|
|
36
|
-
def inspect
|
37
|
-
to_a.inspect
|
34
|
+
def inspect(*_args)
|
35
|
+
"#<#{self.class}: #{to_a.inspect}>"
|
38
36
|
end
|
39
37
|
|
40
38
|
def to_a
|
41
|
-
[
|
39
|
+
[@action, @position, @element]
|
42
40
|
end
|
43
41
|
|
42
|
+
alias to_ary to_a
|
43
|
+
|
44
44
|
def self.from_a(arr)
|
45
45
|
arr = arr.flatten(1)
|
46
46
|
case arr.size
|
@@ -49,7 +49,7 @@ class Diff::LCS::Change
|
|
49
49
|
when 3
|
50
50
|
Diff::LCS::Change.new(*(arr[0...3]))
|
51
51
|
else
|
52
|
-
|
52
|
+
fail 'Invalid change array format provided.'
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -57,15 +57,15 @@ class Diff::LCS::Change
|
|
57
57
|
|
58
58
|
def ==(other)
|
59
59
|
(self.class == other.class) and
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
(action == other.action) and
|
61
|
+
(position == other.position) and
|
62
|
+
(element == other.element)
|
63
63
|
end
|
64
64
|
|
65
65
|
def <=>(other)
|
66
|
-
r =
|
67
|
-
r =
|
68
|
-
r =
|
66
|
+
r = action <=> other.action
|
67
|
+
r = position <=> other.position if r.zero?
|
68
|
+
r = element <=> other.element if r.zero?
|
69
69
|
r
|
70
70
|
end
|
71
71
|
|
@@ -114,27 +114,20 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
114
114
|
def initialize(*args)
|
115
115
|
@action, @old_position, @old_element, @new_position, @new_element = *args
|
116
116
|
|
117
|
-
unless Diff::LCS::Change.valid_action?(@action)
|
118
|
-
|
119
|
-
|
120
|
-
unless @old_position.nil? or @old_position.kind_of? IntClass
|
121
|
-
raise "Invalid (Old) Position Type"
|
122
|
-
end
|
123
|
-
unless @new_position.nil? or @new_position.kind_of? IntClass
|
124
|
-
raise "Invalid (New) Position Type"
|
125
|
-
end
|
117
|
+
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
118
|
+
fail 'Invalid (Old) Position Type' unless @old_position.nil? or @old_position.kind_of? IntClass
|
119
|
+
fail 'Invalid (New) Position Type' unless @new_position.nil? or @new_position.kind_of? IntClass
|
126
120
|
end
|
127
121
|
|
128
122
|
def to_a
|
129
|
-
[
|
130
|
-
|
131
|
-
[
|
123
|
+
[
|
124
|
+
@action,
|
125
|
+
[@old_position, @old_element],
|
126
|
+
[@new_position, @new_element]
|
132
127
|
]
|
133
128
|
end
|
134
129
|
|
135
|
-
|
136
|
-
to_a.inspect
|
137
|
-
end
|
130
|
+
alias to_ary to_a
|
138
131
|
|
139
132
|
def self.from_a(arr)
|
140
133
|
Diff::LCS::Change.from_a(arr)
|
@@ -163,11 +156,11 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
163
156
|
|
164
157
|
def ==(other)
|
165
158
|
(self.class == other.class) and
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
159
|
+
(@action == other.action) and
|
160
|
+
(@old_position == other.old_position) and
|
161
|
+
(@new_position == other.new_position) and
|
162
|
+
(@old_element == other.old_element) and
|
163
|
+
(@new_element == other.new_element)
|
171
164
|
end
|
172
165
|
|
173
166
|
def <=>(other)
|
data/lib/diff/lcs/htmldiff.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cgi'
|
4
4
|
|
5
|
+
# Produce a simple HTML diff view.
|
5
6
|
class Diff::LCS::HTMLDiff
|
6
7
|
class << self
|
7
8
|
attr_accessor :can_expand_tabs #:nodoc:
|
8
9
|
end
|
9
10
|
self.can_expand_tabs = true
|
10
11
|
|
11
|
-
class Callbacks
|
12
|
+
class Callbacks #:nodoc:
|
12
13
|
attr_accessor :output
|
13
14
|
attr_accessor :match_class
|
14
15
|
attr_accessor :only_a_class
|
@@ -18,14 +19,14 @@ class Diff::LCS::HTMLDiff
|
|
18
19
|
@output = output
|
19
20
|
options ||= {}
|
20
21
|
|
21
|
-
@match_class = options[:match_class] ||
|
22
|
-
@only_a_class = options[:only_a_class] ||
|
23
|
-
@only_b_class = options[:only_b_class] ||
|
22
|
+
@match_class = options[:match_class] || 'match'
|
23
|
+
@only_a_class = options[:only_a_class] || 'only_a'
|
24
|
+
@only_b_class = options[:only_b_class] || 'only_b'
|
24
25
|
end
|
25
26
|
|
26
27
|
def htmlize(element, css_class)
|
27
|
-
element =
|
28
|
-
%Q
|
28
|
+
element = ' ' if element.empty?
|
29
|
+
%Q(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
|
29
30
|
end
|
30
31
|
private :htmlize
|
31
32
|
|
@@ -49,8 +50,8 @@ class Diff::LCS::HTMLDiff
|
|
49
50
|
:expand_tabs => nil,
|
50
51
|
:output => nil,
|
51
52
|
:css => nil,
|
52
|
-
:title => nil
|
53
|
-
}
|
53
|
+
:title => nil
|
54
|
+
}.freeze
|
54
55
|
|
55
56
|
DEFAULT_CSS = <<-CSS
|
56
57
|
body { margin: 0; }
|
@@ -96,13 +97,13 @@ h1 { margin-left: 2em; }
|
|
96
97
|
|
97
98
|
def verify_options
|
98
99
|
@options[:expand_tabs] ||= 4
|
99
|
-
@options[:expand_tabs] = 4 if @options[:expand_tabs]
|
100
|
+
@options[:expand_tabs] = 4 if @options[:expand_tabs].negative?
|
100
101
|
|
101
102
|
@options[:output] ||= $stdout
|
102
103
|
|
103
104
|
@options[:css] ||= DEFAULT_CSS.dup
|
104
105
|
|
105
|
-
@options[:title] ||=
|
106
|
+
@options[:title] ||= 'diff'
|
106
107
|
end
|
107
108
|
private :verify_options
|
108
109
|
|
@@ -111,16 +112,16 @@ h1 { margin-left: 2em; }
|
|
111
112
|
def run
|
112
113
|
verify_options
|
113
114
|
|
114
|
-
if @options[:expand_tabs]
|
115
|
+
if @options[:expand_tabs].positive? && self.class.can_expand_tabs
|
115
116
|
formatter = Text::Format.new
|
116
117
|
formatter.tabstop = @options[:expand_tabs]
|
117
118
|
|
118
|
-
@left.map!
|
119
|
-
@right.map!
|
119
|
+
@left.map! do |line| formatter.expand(line.chomp) end
|
120
|
+
@right.map! do |line| formatter.expand(line.chomp) end
|
120
121
|
end
|
121
122
|
|
122
|
-
@left.map!
|
123
|
-
@right.map!
|
123
|
+
@left.map! do |line| CGI.escapeHTML(line.chomp) end
|
124
|
+
@right.map! do |line| CGI.escapeHTML(line.chomp) end
|
124
125
|
|
125
126
|
@options[:output] << <<-OUTPUT
|
126
127
|
<html>
|
data/lib/diff/lcs/hunk.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
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
|
-
# Create a hunk using references to both the old and new data, as well as
|
10
|
-
#
|
9
|
+
# Create a hunk using references to both the old and new data, as well as the
|
10
|
+
# piece of data.
|
11
11
|
def initialize(data_old, data_new, piece, flag_context, file_length_difference)
|
12
12
|
# At first, a hunk will have just one Block in it
|
13
|
-
@blocks = [
|
13
|
+
@blocks = [Diff::LCS::Block.new(piece)]
|
14
14
|
if String.method_defined?(:encoding)
|
15
|
-
@preferred_data_encoding = data_old.fetch(0, data_new.fetch(0,'')
|
15
|
+
@preferred_data_encoding = data_old.fetch(0, data_new.fetch(0, '')).encoding
|
16
16
|
end
|
17
17
|
@data_old = data_old
|
18
18
|
@data_new = data_new
|
@@ -20,6 +20,7 @@ class Diff::LCS::Hunk
|
|
20
20
|
before = after = file_length_difference
|
21
21
|
after += @blocks[0].diff_size
|
22
22
|
@file_length_difference = after # The caller must get this manually
|
23
|
+
@max_diff_size = @blocks.lazy.map { |e| e.diff_size }.max
|
23
24
|
|
24
25
|
# Save the start & end of each array. If the array doesn't exist (e.g.,
|
25
26
|
# we're only adding items in this block), then figure out the line
|
@@ -55,19 +56,26 @@ class Diff::LCS::Hunk
|
|
55
56
|
# Change the "start" and "end" fields to note that context should be added
|
56
57
|
# to this hunk.
|
57
58
|
attr_accessor :flag_context
|
58
|
-
undef :flag_context
|
59
|
-
def flag_context=(context) #:nodoc:
|
59
|
+
undef :flag_context=
|
60
|
+
def flag_context=(context) #:nodoc: # rubocop:disable Lint/DuplicateMethods
|
60
61
|
return if context.nil? or context.zero?
|
61
62
|
|
62
|
-
add_start =
|
63
|
+
add_start = context > @start_old ? @start_old : context
|
64
|
+
|
63
65
|
@start_old -= add_start
|
64
66
|
@start_new -= add_start
|
65
67
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
old_size = @data_old.size
|
69
|
+
|
70
|
+
add_end =
|
71
|
+
if (@end_old + context) > old_size
|
72
|
+
old_size - @end_old
|
73
|
+
else
|
74
|
+
context
|
75
|
+
end
|
76
|
+
|
77
|
+
add_end = @max_diff_size if add_end >= old_size
|
78
|
+
|
71
79
|
@end_old += add_end
|
72
80
|
@end_new += add_end
|
73
81
|
end
|
@@ -76,15 +84,13 @@ class Diff::LCS::Hunk
|
|
76
84
|
# a truthy value so that if there is no overlap, you can know the merge
|
77
85
|
# was skipped.
|
78
86
|
def merge(hunk)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
nil
|
85
|
-
end
|
87
|
+
return unless overlaps?(hunk)
|
88
|
+
|
89
|
+
@start_old = hunk.start_old
|
90
|
+
@start_new = hunk.start_new
|
91
|
+
blocks.unshift(*hunk.blocks)
|
86
92
|
end
|
87
|
-
|
93
|
+
alias unshift merge
|
88
94
|
|
89
95
|
# Determines whether there is an overlap between this hunk and the
|
90
96
|
# provided hunk. This will be true if the difference between the two hunks
|
@@ -108,15 +114,15 @@ class Diff::LCS::Hunk
|
|
108
114
|
when :reverse_ed, :ed_finish
|
109
115
|
ed_diff(format)
|
110
116
|
else
|
111
|
-
|
117
|
+
fail "Unknown diff format #{format}."
|
112
118
|
end
|
113
119
|
end
|
114
120
|
|
115
121
|
# Note that an old diff can't have any context. Therefore, we know that
|
116
122
|
# there's only one block in the hunk.
|
117
123
|
def old_diff
|
118
|
-
warn
|
119
|
-
op_act = {
|
124
|
+
warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
|
125
|
+
op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
|
120
126
|
|
121
127
|
block = @blocks[0]
|
122
128
|
|
@@ -126,9 +132,16 @@ class Diff::LCS::Hunk
|
|
126
132
|
s = encode("#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n")
|
127
133
|
# If removing anything, just print out all the remove lines in the hunk
|
128
134
|
# which is just all the remove lines in the block.
|
129
|
-
|
130
|
-
|
131
|
-
|
135
|
+
unless block.remove.empty?
|
136
|
+
@data_old[@start_old..@end_old].each { |e| s << encode('< ') + e + encode("\n") }
|
137
|
+
end
|
138
|
+
|
139
|
+
s << encode("---\n") if block.op == '!'
|
140
|
+
|
141
|
+
unless block.insert.empty?
|
142
|
+
@data_new[@start_new..@end_new].each { |e| s << encode('> ') + e + encode("\n") }
|
143
|
+
end
|
144
|
+
|
132
145
|
s
|
133
146
|
end
|
134
147
|
private :old_diff
|
@@ -148,7 +161,7 @@ class Diff::LCS::Hunk
|
|
148
161
|
# file -- don't take removed items into account.
|
149
162
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
150
163
|
|
151
|
-
outlist = @data_old[lo
|
164
|
+
outlist = @data_old[lo..hi].map { |e| e.insert(0, encode(' ')) }
|
152
165
|
|
153
166
|
@blocks.each do |block|
|
154
167
|
block.remove.each do |item|
|
@@ -177,13 +190,13 @@ class Diff::LCS::Hunk
|
|
177
190
|
# Print out file 1 part for each block in context diff format if there
|
178
191
|
# are any blocks that remove items
|
179
192
|
lo, hi = @start_old, @end_old
|
180
|
-
removes = @blocks.
|
193
|
+
removes = @blocks.reject { |e| e.remove.empty? }
|
181
194
|
if removes
|
182
|
-
outlist = @data_old[lo
|
195
|
+
outlist = @data_old[lo..hi].map { |e| e.insert(0, encode(' ')) }
|
183
196
|
|
184
197
|
removes.each do |block|
|
185
198
|
block.remove.each do |item|
|
186
|
-
outlist[item.position - lo]
|
199
|
+
outlist[item.position - lo].insert(0, encode(block.op)) # - or !
|
187
200
|
end
|
188
201
|
end
|
189
202
|
s << outlist.join("\n")
|
@@ -191,12 +204,12 @@ class Diff::LCS::Hunk
|
|
191
204
|
|
192
205
|
s << encode("\n--- #{r} ----\n")
|
193
206
|
lo, hi = @start_new, @end_new
|
194
|
-
inserts = @blocks.
|
207
|
+
inserts = @blocks.reject { |e| e.insert.empty? }
|
195
208
|
if inserts
|
196
|
-
outlist = @data_new[lo
|
209
|
+
outlist = @data_new[lo..hi].collect { |e| e.insert(0, encode(' ')) }
|
197
210
|
inserts.each do |block|
|
198
211
|
block.insert.each do |item|
|
199
|
-
outlist[item.position - lo]
|
212
|
+
outlist[item.position - lo].insert(0, encode(block.op)) # - or !
|
200
213
|
end
|
201
214
|
end
|
202
215
|
s << outlist.join("\n")
|
@@ -206,17 +219,18 @@ class Diff::LCS::Hunk
|
|
206
219
|
private :context_diff
|
207
220
|
|
208
221
|
def ed_diff(format)
|
209
|
-
op_act = {
|
210
|
-
warn
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
222
|
+
op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
|
223
|
+
warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
|
224
|
+
|
225
|
+
s =
|
226
|
+
if format == :reverse_ed
|
227
|
+
encode("#{op_act[@blocks[0].op]}#{context_range(:old)}\n")
|
228
|
+
else
|
229
|
+
encode("#{context_range(:old, ' ')}#{op_act[@blocks[0].op]}\n")
|
230
|
+
end
|
217
231
|
|
218
232
|
unless @blocks[0].insert.empty?
|
219
|
-
@data_new[@start_new
|
233
|
+
@data_new[@start_new..@end_new].each do |e| s << e + encode("\n") end
|
220
234
|
s << encode(".\n")
|
221
235
|
end
|
222
236
|
s
|
@@ -225,7 +239,7 @@ class Diff::LCS::Hunk
|
|
225
239
|
|
226
240
|
# Generate a range of item numbers to print. Only print 1 number if the
|
227
241
|
# range has only one item in it. Otherwise, it's 'start,end'
|
228
|
-
def context_range(mode, op = ',')
|
242
|
+
def context_range(mode, op = ',') # rubocop:disable Naming/UncommunicativeMethodParamName
|
229
243
|
case mode
|
230
244
|
when :old
|
231
245
|
s, e = (@start_old + 1), (@end_old + 1)
|
@@ -233,7 +247,7 @@ class Diff::LCS::Hunk
|
|
233
247
|
s, e = (@start_new + 1), (@end_new + 1)
|
234
248
|
end
|
235
249
|
|
236
|
-
|
250
|
+
s < e ? "#{s}#{op}#{e}" : e.to_s
|
237
251
|
end
|
238
252
|
private :context_range
|
239
253
|
|
@@ -249,8 +263,8 @@ class Diff::LCS::Hunk
|
|
249
263
|
end
|
250
264
|
|
251
265
|
length = e - s + 1
|
252
|
-
first =
|
253
|
-
|
266
|
+
first = length < 2 ? e : s # "strange, but correct"
|
267
|
+
length == 1 ? first.to_s : "#{first},#{length}"
|
254
268
|
end
|
255
269
|
private :unified_range
|
256
270
|
|
@@ -263,10 +277,11 @@ class Diff::LCS::Hunk
|
|
263
277
|
args.map { |arg| arg.encode(string.encoding) }
|
264
278
|
end
|
265
279
|
else
|
266
|
-
def encode(literal,
|
280
|
+
def encode(literal, _target_encoding = nil)
|
267
281
|
literal
|
268
282
|
end
|
269
|
-
|
283
|
+
|
284
|
+
def encode_as(_string, *args)
|
270
285
|
args
|
271
286
|
end
|
272
287
|
end
|