Skip to content

Commit 8538f5b

Browse files
author
Kevin Paulisse
committed
Add whitespace handling
1 parent 03ee1be commit 8538f5b

File tree

2 files changed

+62
-6
lines changed
  • lib/octocatalog-diff/catalog-diff/display
  • spec/octocatalog-diff/tests/catalog-diff/display

2 files changed

+62
-6
lines changed

lib/octocatalog-diff/catalog-diff/display/text.rb

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,68 @@ def self.loc_string(loc, compilation_dir, logger)
257257
# @param depth [Fixnum] Depth, for correct indentation
258258
# @return Array<String> Displayable result
259259
def self.diff_two_strings_with_diffy(string1, string2, depth)
260-
# prevent 'No newline at end of file' for single line strings
261-
string1 += "\n" unless string1 =~ /\n/
262-
string2 += "\n" unless string2 =~ /\n/
260+
# Single line strings?
261+
if single_lines?(string1, string2)
262+
string1, string2 = add_trailing_newlines(string1, string2)
263+
diff = Diffy::Diff.new(string1, string2, context: 2, include_diff_info: true).to_s.split("\n")
264+
3.times { diff.shift }
265+
return diff.map { |x| left_pad(2 * depth + 2, make_trailing_whitespace_visible(adjust_position_of_plus_minus(x))) }
266+
end
267+
268+
# Multiple line strings
269+
string1, string2 = add_trailing_newlines(string1, string2)
263270
diff = Diffy::Diff.new(string1, string2, context: 2, include_diff_info: true).to_s.split("\n")
264271
diff.shift # Remove first line of diff info (filename that makes no sense)
265272
diff.shift # Remove second line of diff info (filename that makes no sense)
266-
diff.map { |x| left_pad(2 * depth + 2, x) }
273+
diff.map { |x| left_pad(2 * depth + 2, make_trailing_whitespace_visible(x)) }
274+
end
275+
276+
# Determine if two incoming strings are single lines. Returns true if both
277+
# incoming strings are single lines, false otherwise.
278+
# @param string_1 [String] First string
279+
# @param string_2 [String] Second string
280+
# @return [Boolean] Whether both incoming strings are single lines
281+
def self.single_lines?(string_1, string_2)
282+
string_1.strip !~ /\n/ && string_2.strip !~ /\n/
283+
end
284+
285+
# Add "\n" to the end of both strings, only if both strings are lacking it.
286+
# This prevents "\\ No newline at end of file" for single string comparison.
287+
# @param string_1 [String] First string
288+
# @param string_2 [String] Second string
289+
# @return [Array<String>] Adjusted string_1, string_2
290+
def self.add_trailing_newlines(string_1, string_2)
291+
return [string_1, string_2] unless string_1 !~ /\n\Z/ && string_2 !~ /\n\Z/
292+
[string_1 + "\n", string_2 + "\n"]
293+
end
294+
295+
# Adjust the space after of the `-` / `+` in the diff for single line diffs.
296+
# Diffy prints diffs with no space between the `-` / `+` in the text, but for
297+
# single lines it's easier to read with that space added.
298+
# @param string_in [String] Input string, which is a line of a diff from diffy
299+
# @return [String] Modified string
300+
def self.adjust_position_of_plus_minus(string_in)
301+
string_in.sub(/\A(\e\[\d+m)?([\-\+])/, '\1\2 ')
302+
end
303+
304+
# Convert trailing whitespace to underscore for display purposes. Also convert special
305+
# whitespace (\r, \n, \t, ...) to character representation.
306+
# @param string_in [String] Input string, which might contain trailing whitespace
307+
# @return [String] Modified string
308+
def self.make_trailing_whitespace_visible(string_in)
309+
return string_in unless string_in =~ /\A((?:.|\n)*?)(\s+)(\e\[0m)?\Z/
310+
beginning = Regexp.last_match(1)
311+
trailing_space = Regexp.last_match(2)
312+
end_escape = Regexp.last_match(3)
313+
314+
# Trailing space adjustment for line endings
315+
trailing_space.gsub! "\n", '\n'
316+
trailing_space.gsub! "\r", '\r'
317+
trailing_space.gsub! "\t", '\t'
318+
trailing_space.gsub! "\f", '\f'
319+
trailing_space.tr! ' ', '_'
320+
321+
[beginning, trailing_space, end_escape].join('')
267322
end
268323

269324
# Get the diff of two hashes. Call the 'diffy' gem for this.

spec/octocatalog-diff/tests/catalog-diff/display/text_spec.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,8 @@
337337
' Foo[Bar] =>',
338338
' baz =>',
339339
' buzz =>',
340-
"\e[0;31;49m - old string\e[0m",
341-
"\e[0;32;49m + new string\e[0m",
340+
" \e[31m- old string\e[0m",
341+
" \e[32m+ new string\e[0m",
342342
@separator
343343
]
344344
result = OctocatalogDiff::CatalogDiff::Display::Text.generate(diff, color: true, header: 'header')
@@ -404,6 +404,7 @@
404404
' buzz =>',
405405
" \e[36m@@ -1 +1,2 @@\e[0m",
406406
" \e[31m-old string\e[0m",
407+
' \\ No newline at end of file',
407408
" \e[32m+new string\e[0m",
408409
" \e[32m+new string 2\e[0m",
409410
@separator

0 commit comments

Comments
 (0)