diff-lcs 1.5.0 → 1.6.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.
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  unless 0.respond_to?(:positive?)
4
- class Fixnum # rubocop:disable Lint/UnifiedInteger, Style/Documentation
4
+ class Fixnum # standard:disable Lint/UnifiedInteger
5
5
  def positive?
6
- self > 0 # rubocop:disable Style/NumericPredicate
6
+ self > 0
7
7
  end
8
8
  end
9
9
  end
@@ -25,13 +25,13 @@ class Diff::LCS::Block
25
25
  def op
26
26
  case [@remove.empty?, @insert.empty?]
27
27
  when [false, false]
28
- '!'
28
+ "!"
29
29
  when [false, true]
30
- '-'
30
+ "-"
31
31
  when [true, false]
32
- '+'
32
+ "+"
33
33
  else # [true, true]
34
- '^'
34
+ "^"
35
35
  end
36
36
  end
37
37
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'diff/lcs/change'
3
+ require "diff/lcs/change"
4
4
 
5
- module Diff::LCS # rubocop:disable Style/Documentation
5
+ module Diff::LCS
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
@@ -50,7 +50,9 @@ module Diff::LCS # rubocop:disable Style/Documentation
50
50
  BalancedCallbacks = DefaultCallbacks
51
51
 
52
52
  def self.callbacks_for(callbacks)
53
- callbacks.new rescue callbacks
53
+ callbacks.new
54
+ rescue
55
+ callbacks
54
56
  end
55
57
  end
56
58
 
@@ -107,7 +109,7 @@ class Diff::LCS::DiffCallbacks
107
109
  # Returns the difference set collected during the diff process.
108
110
  attr_reader :diffs
109
111
 
110
- def initialize # :yields self:
112
+ def initialize # :yields: self
111
113
  @hunk = []
112
114
  @diffs = []
113
115
 
@@ -131,11 +133,11 @@ class Diff::LCS::DiffCallbacks
131
133
  end
132
134
 
133
135
  def discard_a(event)
134
- @hunk << Diff::LCS::Change.new('-', event.old_position, event.old_element)
136
+ @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element)
135
137
  end
136
138
 
137
139
  def discard_b(event)
138
- @hunk << Diff::LCS::Change.new('+', event.new_position, event.new_element)
140
+ @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element)
139
141
  end
140
142
 
141
143
  def finish_hunk
@@ -302,7 +304,7 @@ class Diff::LCS::SDiffCallbacks
302
304
  # Returns the difference set collected during the diff process.
303
305
  attr_reader :diffs
304
306
 
305
- def initialize #:yields self:
307
+ def initialize # :yields: self
306
308
  @diffs = []
307
309
  yield self if block_given?
308
310
  end
@@ -4,13 +4,13 @@
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 # rubocop:disable Naming/ConstantName
7
+ IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard: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 = %w(+ - = ! > <).freeze
13
+ VALID_ACTIONS = %w[+ - = ! > <].freeze
14
14
 
15
15
  def self.valid_action?(action)
16
16
  VALID_ACTIONS.include? action
@@ -28,7 +28,7 @@ class Diff::LCS::Change
28
28
  @action, @position, @element = *args
29
29
 
30
30
  fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
31
- fail 'Invalid Position Type' unless @position.kind_of? IntClass
31
+ fail "Invalid Position Type" unless @position.is_a? IntClass
32
32
  end
33
33
 
34
34
  def inspect(*_args)
@@ -39,7 +39,7 @@ class Diff::LCS::Change
39
39
  [@action, @position, @element]
40
40
  end
41
41
 
42
- alias to_ary to_a
42
+ alias_method :to_ary, :to_a
43
43
 
44
44
  def self.from_a(arr)
45
45
  arr = arr.flatten(1)
@@ -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
- fail 'Invalid change array format provided.'
52
+ fail "Invalid change array format provided."
53
53
  end
54
54
  end
55
55
 
@@ -70,27 +70,27 @@ class Diff::LCS::Change
70
70
  end
71
71
 
72
72
  def adding?
73
- @action == '+'
73
+ @action == "+"
74
74
  end
75
75
 
76
76
  def deleting?
77
- @action == '-'
77
+ @action == "-"
78
78
  end
79
79
 
80
80
  def unchanged?
81
- @action == '='
81
+ @action == "="
82
82
  end
83
83
 
84
84
  def changed?
85
- @action == '!'
85
+ @action == "!"
86
86
  end
87
87
 
88
88
  def finished_a?
89
- @action == '>'
89
+ @action == ">"
90
90
  end
91
91
 
92
92
  def finished_b?
93
- @action == '<'
93
+ @action == "<"
94
94
  end
95
95
  end
96
96
 
@@ -115,8 +115,8 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
115
115
  @action, @old_position, @old_element, @new_position, @new_element = *args
116
116
 
117
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
118
+ fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass)
119
+ fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass)
120
120
  end
121
121
 
122
122
  def to_a
@@ -127,7 +127,7 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
127
127
  ]
128
128
  end
129
129
 
130
- alias to_ary to_a
130
+ alias_method :to_ary, :to_a
131
131
 
132
132
  def self.from_a(arr)
133
133
  Diff::LCS::Change.from_a(arr)
@@ -139,15 +139,15 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
139
139
  ea = event.to_a
140
140
 
141
141
  case ea[0]
142
- when '-'
142
+ when "-"
143
143
  ea[2][1] = nil
144
- when '<'
145
- ea[0] = '-'
144
+ when "<"
145
+ ea[0] = "-"
146
146
  ea[2][1] = nil
147
- when '+'
147
+ when "+"
148
148
  ea[1][1] = nil
149
- when '>'
150
- ea[0] = '+'
149
+ when ">"
150
+ ea[0] = "+"
151
151
  ea[1][1] = nil
152
152
  end
153
153
 
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
3
+ require "cgi"
4
4
 
5
5
  # Produce a simple HTML diff view.
6
6
  class Diff::LCS::HTMLDiff
7
7
  class << self
8
- attr_accessor :can_expand_tabs #:nodoc:
8
+ # standard:disable ThreadSafety/ClassAndModuleAttributes
9
+ attr_accessor :can_expand_tabs # :nodoc:
10
+ # standard:enable ThreadSafety/ClassAndModuleAttributes
9
11
  end
10
12
  self.can_expand_tabs = true
11
13
 
12
- class Callbacks #:nodoc:
14
+ class Callbacks # :nodoc:
13
15
  attr_accessor :output
14
16
  attr_accessor :match_class
15
17
  attr_accessor :only_a_class
@@ -19,14 +21,14 @@ class Diff::LCS::HTMLDiff
19
21
  @output = output
20
22
  options ||= {}
21
23
 
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
+ @match_class = options[:match_class] || "match"
25
+ @only_a_class = options[:only_a_class] || "only_a"
26
+ @only_b_class = options[:only_b_class] || "only_b"
25
27
  end
26
28
 
27
29
  def htmlize(element, css_class)
28
- element = '&nbsp;' if element.empty?
29
- %Q(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
30
+ element = "&nbsp;" if element.empty?
31
+ %(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
30
32
  end
31
33
  private :htmlize
32
34
 
@@ -46,13 +48,16 @@ class Diff::LCS::HTMLDiff
46
48
  end
47
49
  end
48
50
 
51
+ # standard:disable Style/HashSyntax
49
52
  DEFAULT_OPTIONS = {
50
53
  :expand_tabs => nil,
51
54
  :output => nil,
52
55
  :css => nil,
53
56
  :title => nil
54
57
  }.freeze
58
+ # standard:enable Style/HashSyntax
55
59
 
60
+ # standard:disable Layout/HeredocIndentation
56
61
  DEFAULT_CSS = <<-CSS
57
62
  body { margin: 0; }
58
63
  .diff
@@ -86,11 +91,12 @@ pre
86
91
  }
87
92
  h1 { margin-left: 2em; }
88
93
  CSS
94
+ # standard:enable Layout/HeredocIndentation
89
95
 
90
96
  def initialize(left, right, options = nil)
91
- @left = left
92
- @right = right
93
- @options = options
97
+ @left = left
98
+ @right = right
99
+ @options = options
94
100
 
95
101
  @options = DEFAULT_OPTIONS.dup if @options.nil?
96
102
  end
@@ -103,7 +109,7 @@ h1 { margin-left: 2em; }
103
109
 
104
110
  @options[:css] ||= DEFAULT_CSS.dup
105
111
 
106
- @options[:title] ||= 'diff'
112
+ @options[:title] ||= "diff"
107
113
  end
108
114
  private :verify_options
109
115
 
@@ -116,13 +122,14 @@ h1 { margin-left: 2em; }
116
122
  formatter = Text::Format.new
117
123
  formatter.tabstop = @options[:expand_tabs]
118
124
 
119
- @left.map! do |line| formatter.expand(line.chomp) end
120
- @right.map! do |line| formatter.expand(line.chomp) end
125
+ @left.map! { |line| formatter.expand(line.chomp) }
126
+ @right.map! { |line| formatter.expand(line.chomp) }
121
127
  end
122
128
 
123
- @left.map! do |line| CGI.escapeHTML(line.chomp) end
124
- @right.map! do |line| CGI.escapeHTML(line.chomp) end
129
+ @left.map! { |line| CGI.escapeHTML(line.chomp) }
130
+ @right.map! { |line| CGI.escapeHTML(line.chomp) }
125
131
 
132
+ # standard:disable Layout/HeredocIndentation
126
133
  @options[:output] << <<-OUTPUT
127
134
  <html>
128
135
  <head>
@@ -137,14 +144,17 @@ h1 { margin-left: 2em; }
137
144
  <span class="only_b">Only in New</span></p>
138
145
  <div class="diff">
139
146
  OUTPUT
147
+ # standard:enable Layout/HeredocIndentation
140
148
 
141
149
  callbacks = Callbacks.new(@options[:output])
142
150
  Diff::LCS.traverse_sequences(@left, @right, callbacks)
143
151
 
152
+ # standard:disable Layout/HeredocIndentation
144
153
  @options[:output] << <<-OUTPUT
145
154
  </div>
146
155
  </body>
147
156
  </html>
148
157
  OUTPUT
158
+ # standard:enable Layout/HeredocIndentation
149
159
  end
150
160
  end
data/lib/diff/lcs/hunk.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'diff/lcs/block'
3
+ require "diff/lcs/block"
4
4
 
5
5
  # A Hunk is a group of Blocks which overlap because of the context surrounding
6
6
  # each block. (So if we're not using context, every hunk will contain one
7
7
  # block.) Used in the diff program (bin/ldiff).
8
8
  class Diff::LCS::Hunk
9
- OLD_DIFF_OP_ACTION = { '+' => 'a', '-' => 'd', '!' => 'c' }.freeze #:nodoc:
10
- ED_DIFF_OP_ACTION = { '+' => 'a', '-' => 'd', '!' => 'c' }.freeze #:nodoc:
9
+ OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
10
+ ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
11
11
 
12
12
  private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant)
13
13
 
@@ -22,18 +22,19 @@ class Diff::LCS::Hunk
22
22
  end
23
23
 
24
24
  if String.method_defined?(:encoding)
25
- @preferred_data_encoding = data_old.fetch(0, data_new.fetch(0, '')).encoding
25
+ @preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding
26
26
  end
27
27
 
28
28
  @data_old = data_old
29
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?)
30
32
 
31
33
  before = after = file_length_difference
32
34
  after += @blocks[0].diff_size
33
35
  @file_length_difference = after # The caller must get this manually
34
36
  @max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
35
37
 
36
-
37
38
  # Save the start & end of each array. If the array doesn't exist (e.g.,
38
39
  # we're only adding items in this block), then figure out the line number
39
40
  # based on the line number of the other file and the current difference in
@@ -54,8 +55,8 @@ class Diff::LCS::Hunk
54
55
 
55
56
  @start_old = a1 || (b1 - before)
56
57
  @start_new = b1 || (a1 + before)
57
- @end_old = a2 || (b2 - after)
58
- @end_new = b2 || (a2 + after)
58
+ @end_old = a2 || (b2 - after)
59
+ @end_new = b2 || (a2 + after)
59
60
 
60
61
  self.flag_context = flag_context
61
62
  end
@@ -67,12 +68,12 @@ class Diff::LCS::Hunk
67
68
 
68
69
  # Change the "start" and "end" fields to note that context should be added
69
70
  # to this hunk.
70
- attr_accessor :flag_context # rubocop:disable Layout/EmptyLinesAroundAttributeAccessor
71
+ attr_accessor :flag_context
71
72
  undef :flag_context=
72
- def flag_context=(context) #:nodoc: # rubocop:disable Lint/DuplicateMethods
73
- return if context.nil? or context.zero?
73
+ def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods
74
+ return if context.nil? || context.zero?
74
75
 
75
- add_start = context > @start_old ? @start_old : context
76
+ add_start = (context > @start_old) ? @start_old : context
76
77
 
77
78
  @start_old -= add_start
78
79
  @start_new -= add_start
@@ -80,14 +81,12 @@ class Diff::LCS::Hunk
80
81
  old_size = @data_old.size
81
82
 
82
83
  add_end =
83
- if (@end_old + context) > old_size
84
- old_size - @end_old
84
+ if (@end_old + context) >= old_size
85
+ old_size - @end_old - 1
85
86
  else
86
87
  context
87
88
  end
88
89
 
89
- add_end = @max_diff_size if add_end >= old_size
90
-
91
90
  @end_old += add_end
92
91
  @end_new += add_end
93
92
  end
@@ -102,7 +101,7 @@ class Diff::LCS::Hunk
102
101
  @start_new = hunk.start_new
103
102
  blocks.unshift(*hunk.blocks)
104
103
  end
105
- alias unshift merge
104
+ alias_method :unshift, :merge
106
105
 
107
106
  # Determines whether there is an overlap between this hunk and the
108
107
  # provided hunk. This will be true if the difference between the two hunks
@@ -132,34 +131,42 @@ class Diff::LCS::Hunk
132
131
 
133
132
  # Note that an old diff can't have any context. Therefore, we know that
134
133
  # there's only one block in the hunk.
135
- def old_diff(_last = false)
136
- warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
134
+ def old_diff(last = false)
135
+ warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
137
136
 
138
137
  block = @blocks[0]
139
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
+
140
144
  # Calculate item number range. Old diff range is just like a context
141
145
  # diff range, except the ranges are on one line with the action between
142
146
  # them.
143
- s = encode("#{context_range(:old, ',')}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ',')}\n")
147
+ s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n")
144
148
  # If removing anything, just print out all the remove lines in the hunk
145
149
  # which is just all the remove lines in the block.
146
150
  unless block.remove.empty?
147
- @data_old[@start_old..@end_old].each { |e| s << encode('< ') + e.chomp + encode("\n") }
151
+ @data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") }
148
152
  end
149
153
 
150
- s << encode("---\n") if block.op == '!'
154
+ s << encode("\\n") if old_missing_newline && !new_missing_newline
155
+ s << encode("---\n") if block.op == "!"
151
156
 
152
157
  unless block.insert.empty?
153
- @data_new[@start_new..@end_new].each { |e| s << encode('> ') + e.chomp + encode("\n") }
158
+ @data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") }
154
159
  end
155
160
 
161
+ s << encode("\\n") if new_missing_newline && !old_missing_newline
162
+
156
163
  s
157
164
  end
158
165
  private :old_diff
159
166
 
160
167
  def unified_diff(last = false)
161
168
  # Calculate item number range.
162
- s = encode("@@ -#{unified_range(:old, last)} +#{unified_range(:new, last)} @@\n")
169
+ s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n")
163
170
 
164
171
  # Outlist starts containing the hunk of the old file. Removing an item
165
172
  # just means putting a '-' in front of it. Inserting an item requires
@@ -172,18 +179,20 @@ class Diff::LCS::Hunk
172
179
  # file -- don't take removed items into account.
173
180
  lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
174
181
 
175
- outlist = @data_old[lo..hi].map { |e| String.new("#{encode(' ')}#{e.chomp}") }
182
+ # standard:disable Performance/UnfreezeString
183
+ outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
184
+ # standard:enable Performance/UnfreezeString
176
185
 
177
186
  last_block = blocks[-1]
178
187
 
179
188
  if last
180
- old_missing_newline = missing_last_newline?(@data_old)
181
- new_missing_newline = missing_last_newline?(@data_new)
189
+ old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
190
+ new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
182
191
  end
183
192
 
184
193
  @blocks.each do |block|
185
194
  block.remove.each do |item|
186
- op = item.action.to_s # -
195
+ op = item.action.to_s # -
187
196
  offset = item.position - lo + num_added
188
197
  outlist[offset][0, 1] = encode(op)
189
198
  num_removed += 1
@@ -195,7 +204,7 @@ class Diff::LCS::Hunk
195
204
  end
196
205
 
197
206
  block.insert.each do |item|
198
- op = item.action.to_s # +
207
+ op = item.action.to_s # +
199
208
  offset = item.position - @start_new + num_removed
200
209
  outlist[offset, 0] = encode(op) + @data_new[item.position].chomp
201
210
  num_added += 1
@@ -212,8 +221,8 @@ class Diff::LCS::Hunk
212
221
 
213
222
  def context_diff(last = false)
214
223
  s = encode("***************\n")
215
- s << encode("*** #{context_range(:old, ',', last)} ****\n")
216
- r = context_range(:new, ',', last)
224
+ s << encode("*** #{context_range(:old, ",")} ****\n")
225
+ r = context_range(:new, ",")
217
226
 
218
227
  if last
219
228
  old_missing_newline = missing_last_newline?(@data_old)
@@ -226,7 +235,9 @@ class Diff::LCS::Hunk
226
235
  removes = @blocks.reject { |e| e.remove.empty? }
227
236
 
228
237
  unless removes.empty?
229
- outlist = @data_old[lo..hi].map { |e| String.new("#{encode(' ')}#{e.chomp}") }
238
+ # standard:disable Performance/UnfreezeString
239
+ outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
240
+ # standard:enable Performance/UnfreezeString
230
241
 
231
242
  last_block = removes[-1]
232
243
 
@@ -248,7 +259,9 @@ class Diff::LCS::Hunk
248
259
  inserts = @blocks.reject { |e| e.insert.empty? }
249
260
 
250
261
  unless inserts.empty?
251
- outlist = @data_new[lo..hi].map { |e| String.new("#{encode(' ')}#{e.chomp}") }
262
+ # standard:disable Performance/UnfreezeString
263
+ outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
264
+ # standard:enable Performance/UnfreezeString
252
265
 
253
266
  last_block = inserts[-1]
254
267
 
@@ -268,14 +281,24 @@ class Diff::LCS::Hunk
268
281
  end
269
282
  private :context_diff
270
283
 
271
- def ed_diff(format, _last = false)
272
- warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
284
+ def ed_diff(format, last)
285
+ warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
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
295
+ end
273
296
 
274
297
  s =
275
298
  if format == :reverse_ed
276
- encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, ',')}\n")
299
+ encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n")
277
300
  else
278
- encode("#{context_range(:old, ' ')}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
301
+ encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
279
302
  end
280
303
 
281
304
  unless @blocks[0].insert.empty?
@@ -290,7 +313,7 @@ class Diff::LCS::Hunk
290
313
 
291
314
  # Generate a range of item numbers to print. Only print 1 number if the
292
315
  # range has only one item in it. Otherwise, it's 'start,end'
293
- def context_range(mode, op, last = false)
316
+ def context_range(mode, op)
294
317
  case mode
295
318
  when :old
296
319
  s, e = (@start_old + 1), (@end_old + 1)
@@ -298,28 +321,26 @@ class Diff::LCS::Hunk
298
321
  s, e = (@start_new + 1), (@end_new + 1)
299
322
  end
300
323
 
301
- e -= 1 if last
302
- e = 1 if e.zero?
303
-
304
- s < e ? "#{s}#{op}#{e}" : e.to_s
324
+ (s < e) ? "#{s}#{op}#{e}" : e.to_s
305
325
  end
306
326
  private :context_range
307
327
 
308
328
  # Generate a range of item numbers to print for unified diff. Print number
309
329
  # where block starts, followed by number of lines in the block
310
330
  # (don't print number of lines if it's 1)
311
- def unified_range(mode, last)
331
+ def unified_range(mode)
312
332
  case mode
313
333
  when :old
334
+ return "0,0" if @old_empty
314
335
  s, e = (@start_old + 1), (@end_old + 1)
315
336
  when :new
337
+ return "0,0" if @new_empty
316
338
  s, e = (@start_new + 1), (@end_new + 1)
317
339
  end
318
340
 
319
- length = e - s + (last ? 0 : 1)
341
+ length = e - s + 1
320
342
 
321
- first = length < 2 ? e : s # "strange, but correct"
322
- length <= 1 ? first.to_s : "#{first},#{length}"
343
+ (length <= 1) ? e.to_s : "#{s},#{length}"
323
344
  end
324
345
  private :unified_range
325
346