riffdiff 1.0.36 → 1.0.48
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 +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +4 -3
- data/lib/refiner.rb +39 -12
- data/lib/riff.rb +0 -2
- data/lib/whitespace_lint.rb +34 -0
- data/spec/refiner_spec.rb +46 -0
- data/spec/whitespace_lint_spec.rb +47 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d95f2bec7e95f1926db693ed9995fc867fd387e3
|
4
|
+
data.tar.gz: 9863771e381648a0f786020691e77652948aa14b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37ffcb842e39e386e019d56dff9bcefd5e6720aef94210fe6e325c5286923cdc27f2b70b327e654334697b0c323bf83b535b3399d453461e745f373285bdea4d
|
7
|
+
data.tar.gz: 6e8ff4707345cf558dd5495039dcd6096ad40c0c77ec0e613891a0eeb08da31a26143283be1918e634f76c89f6b979e5052f1b8de0c6d7dd9204b1c5335c22bf
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -25,9 +25,10 @@ Optionally followed by...
|
|
25
25
|
# TODO
|
26
26
|
* Think about highlighting whitespace errors like Git does
|
27
27
|
* OK: Make DiffString.add() take a color as well
|
28
|
-
* Add a whitespace analysis pass to the Refiner
|
29
|
-
* Let the Refiner highlight whitespace errors among the added lines in
|
30
|
-
red.
|
28
|
+
* OK: Add a trailing whitespace analysis pass to the Refiner
|
29
|
+
* OK: Let the Refiner highlight whitespace errors among the added lines in
|
30
|
+
reverse red.
|
31
|
+
* Add highlighting of non-leading tabs to the whitespace analysis
|
31
32
|
* Think about how to visualize an added line break together with some
|
32
33
|
indentation on the following line.
|
33
34
|
* Do "git show 57f27da" and think about what rule we should use to get
|
data/lib/refiner.rb
CHANGED
@@ -2,6 +2,9 @@ require 'set'
|
|
2
2
|
require 'diff/lcs'
|
3
3
|
require 'diff_string'
|
4
4
|
|
5
|
+
require 'colors'
|
6
|
+
require 'whitespace_lint'
|
7
|
+
|
5
8
|
# Compute longest common substring based diff between two strings.
|
6
9
|
#
|
7
10
|
# The diff format is first the old string:
|
@@ -15,6 +18,7 @@ require 'diff_string'
|
|
15
18
|
# * added characters highlighted in inverse video
|
16
19
|
class Refiner
|
17
20
|
include Colors
|
21
|
+
include WhitespaceLint
|
18
22
|
|
19
23
|
attr_reader :refined_old
|
20
24
|
attr_reader :refined_new
|
@@ -33,7 +37,7 @@ class Refiner
|
|
33
37
|
when '+'
|
34
38
|
new_highlights << highlight.position
|
35
39
|
else
|
36
|
-
fail("Unsupported diff
|
40
|
+
fail("Unsupported diff action: <#{action}>")
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -95,28 +99,44 @@ class Refiner
|
|
95
99
|
return try_highlight(old, new)
|
96
100
|
end
|
97
101
|
|
98
|
-
|
99
|
-
|
100
|
-
|
102
|
+
# ws: a set containing the whitespace errors we want to highlight
|
103
|
+
def render_refinement(prefix, base_color, string, highlights,
|
104
|
+
base_index: 0, highlight_color: '',
|
105
|
+
ws: nil)
|
106
|
+
return_me = DiffString.new(prefix, base_color)
|
101
107
|
string.each_char.with_index do |char, index|
|
102
108
|
highlight = highlights.include?(index + base_index)
|
103
|
-
|
109
|
+
color = highlight ? highlight_color : ''
|
110
|
+
|
111
|
+
if !ws.nil? && ws.include?(index + base_index)
|
112
|
+
# Highlight whitespace error in inverse red
|
113
|
+
color = RED
|
114
|
+
highlight = true
|
115
|
+
end
|
116
|
+
|
117
|
+
return_me.add(char, highlight, color)
|
104
118
|
end
|
105
119
|
return return_me.to_s
|
106
120
|
end
|
107
121
|
|
108
122
|
# After returning from this method, both @refined_old and @refined_new must
|
109
123
|
# have been set to reasonable values.
|
110
|
-
def create_refinements(old, new,
|
124
|
+
def create_refinements(old, new,
|
125
|
+
old_highlights, new_highlights,
|
126
|
+
whitespace_highlights)
|
111
127
|
@refined_old = render_refinement('-', RED, old, old_highlights)
|
112
|
-
@refined_new = render_refinement('+', GREEN,
|
128
|
+
@refined_new = render_refinement('+', GREEN,
|
129
|
+
new, new_highlights,
|
130
|
+
ws: whitespace_highlights)
|
113
131
|
end
|
114
132
|
|
115
133
|
# After returning from this method, both @refined_old and @refined_new must
|
116
134
|
# have been set to reasonable values.
|
117
135
|
#
|
118
136
|
# Returns false if the preconditions for using this method aren't fulfilled
|
119
|
-
def create_one_to_many_refinements(old, new,
|
137
|
+
def create_one_to_many_refinements(old, new,
|
138
|
+
old_highlights, new_highlights,
|
139
|
+
whitespace_highlights)
|
120
140
|
# If things have been removed from the first line, the specialized
|
121
141
|
# highlighting won't work
|
122
142
|
return false if old_highlights.count > 0
|
@@ -136,13 +156,15 @@ class Refiner
|
|
136
156
|
|
137
157
|
refined_line_1 =
|
138
158
|
render_refinement(' ', '', lines[0], new_highlights,
|
139
|
-
highlight_color: GREEN
|
159
|
+
highlight_color: GREEN,
|
160
|
+
ws: whitespace_highlights)
|
140
161
|
|
141
162
|
line_2_index_0 = lines[0].length
|
142
163
|
refined_remaining_lines = render_refinement('+', GREEN,
|
143
164
|
lines[1..-1].join,
|
144
165
|
new_highlights,
|
145
|
-
base_index: line_2_index_0
|
166
|
+
base_index: line_2_index_0,
|
167
|
+
ws: whitespace_highlights)
|
146
168
|
|
147
169
|
@refined_new = refined_line_1 + refined_remaining_lines
|
148
170
|
|
@@ -155,10 +177,15 @@ class Refiner
|
|
155
177
|
old_highlights, new_highlights = try_highlight_initial_lines(old, new)
|
156
178
|
end
|
157
179
|
|
180
|
+
whitespace_highlights = collect_ws_highlights(new)
|
181
|
+
|
158
182
|
if !create_one_to_many_refinements(old, new,
|
159
183
|
old_highlights,
|
160
|
-
new_highlights
|
161
|
-
|
184
|
+
new_highlights,
|
185
|
+
whitespace_highlights)
|
186
|
+
create_refinements(old, new,
|
187
|
+
old_highlights, new_highlights,
|
188
|
+
whitespace_highlights)
|
162
189
|
end
|
163
190
|
end
|
164
191
|
end
|
data/lib/riff.rb
CHANGED
@@ -4,8 +4,6 @@ require 'diff_string'
|
|
4
4
|
|
5
5
|
# Call do_stream() with the output of some diff-like tool (diff,
|
6
6
|
# diff3, git diff, ...) and it will highlight that output for you.
|
7
|
-
#
|
8
|
-
# rubocop:disable Metrics/ClassLength
|
9
7
|
class Riff
|
10
8
|
DIFF_HEADER = /^diff /
|
11
9
|
DIFF_HUNK_HEADER = /^@@ /
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Whitespace error linter
|
2
|
+
module WhitespaceLint
|
3
|
+
def add_line_highlights(line, base_index, highlights)
|
4
|
+
last_seen_whitespace = -1
|
5
|
+
last_seen_non_ws = -1
|
6
|
+
line.each_char.with_index do |char, index|
|
7
|
+
break if char == "\n"
|
8
|
+
break if char == "\r"
|
9
|
+
|
10
|
+
if char == ' ' || char == "\t"
|
11
|
+
last_seen_whitespace = index
|
12
|
+
else
|
13
|
+
last_seen_non_ws = index
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if last_seen_non_ws < last_seen_whitespace
|
18
|
+
((last_seen_non_ws + 1)..last_seen_whitespace).each do |index|
|
19
|
+
highlights << (base_index + index)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def collect_ws_highlights(string)
|
25
|
+
highlights = Set.new()
|
26
|
+
line_start_index = 0
|
27
|
+
string.each_line do |line|
|
28
|
+
add_line_highlights(line, line_start_index, highlights)
|
29
|
+
|
30
|
+
line_start_index += line.length
|
31
|
+
end
|
32
|
+
return highlights
|
33
|
+
end
|
34
|
+
end
|
data/spec/refiner_spec.rb
CHANGED
@@ -65,6 +65,52 @@ RSpec.describe Refiner, '#new' do
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
context %(adding line with text + space) do
|
69
|
+
refiner = Refiner.new('', "text \n")
|
70
|
+
|
71
|
+
it %(highlights the final space in inverse red) do
|
72
|
+
expect(refiner.refined_new).to eq(
|
73
|
+
%(#{GREEN}+text#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context %(adding two lines, second with text + space) do
|
78
|
+
refiner = Refiner.new('', "text\ntext \n")
|
79
|
+
|
80
|
+
it %(highlights the final space in inverse red) do
|
81
|
+
expect(refiner.refined_new).to eq(
|
82
|
+
%(#{GREEN}+text\n) +
|
83
|
+
%(#{GREEN}+text#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context %(adding line with only a space) do
|
88
|
+
refiner = Refiner.new('', " \n")
|
89
|
+
|
90
|
+
it %(highlights the space in inverse red) do
|
91
|
+
expect(refiner.refined_new).to eq(
|
92
|
+
%(#{GREEN}+#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context %(adding line with only a tab) do
|
97
|
+
refiner = Refiner.new('', "\t\n")
|
98
|
+
|
99
|
+
it %(highlights the tab in inverse red) do
|
100
|
+
expect(refiner.refined_new).to eq(
|
101
|
+
%(#{GREEN}+#{reversed("#{RED}\t")}#{GREEN}#{RESET}\n))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context %(replacing final char of line with a space) do
|
106
|
+
refiner = Refiner.new("text\n", "tex \n")
|
107
|
+
|
108
|
+
it %(highlights final space of added line in inverse red) do
|
109
|
+
expect(refiner.refined_new).to eq(
|
110
|
+
%(#{GREEN}+tex#{reversed("#{RED} ")}#{GREEN}#{RESET}\n))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
68
114
|
context %(with added ending newline) do
|
69
115
|
refiner = Refiner.new('abcde',
|
70
116
|
"abcde\n")
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'whitespace_lint'
|
2
|
+
|
3
|
+
include WhitespaceLint
|
4
|
+
|
5
|
+
RSpec.describe WhitespaceLint, '#collect_ws_highlights' do
|
6
|
+
context 'empty string' do
|
7
|
+
it 'returns an empty set' do
|
8
|
+
expect(collect_ws_highlights('')).to be_empty
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'a line that is fine' do
|
13
|
+
it 'returns an empty set' do
|
14
|
+
expect(collect_ws_highlights("\t text\n")).to be_empty
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'line with only a space' do
|
19
|
+
it 'highlights the space' do
|
20
|
+
expect(collect_ws_highlights(" \n")).to eq(Set.new [0])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'line with only a tab' do
|
25
|
+
it 'highlights the tab' do
|
26
|
+
expect(collect_ws_highlights("\t\n")).to eq(Set.new [0])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'line with text + space' do
|
31
|
+
it 'highlights the space' do
|
32
|
+
expect(collect_ws_highlights("012 \n")).to eq(Set.new [3])
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'two lines, second ending in space' do
|
37
|
+
string = "012\n345 \n"
|
38
|
+
|
39
|
+
it 'highlights the space' do
|
40
|
+
highlights = collect_ws_highlights(string)
|
41
|
+
expect(highlights.size).to eq(1)
|
42
|
+
|
43
|
+
highlight = highlights.to_a()[0]
|
44
|
+
expect(string[highlight]).to eq(' ')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riffdiff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.48
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johan Walles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- lib/refiner.rb
|
120
120
|
- lib/riff.rb
|
121
121
|
- lib/version.rb
|
122
|
+
- lib/whitespace_lint.rb
|
122
123
|
- riffdiff.gemspec
|
123
124
|
- spec/added-newline-at-eof.diff
|
124
125
|
- spec/colors_spec.rb
|
@@ -129,6 +130,7 @@ files:
|
|
129
130
|
- spec/removed-newline-at-eof.diff
|
130
131
|
- spec/riff_spec.rb
|
131
132
|
- spec/version_spec.rb
|
133
|
+
- spec/whitespace_lint_spec.rb
|
132
134
|
homepage: http://github.com/walles/riff
|
133
135
|
licenses:
|
134
136
|
- MIT
|
@@ -163,3 +165,4 @@ test_files:
|
|
163
165
|
- spec/removed-newline-at-eof.diff
|
164
166
|
- spec/riff_spec.rb
|
165
167
|
- spec/version_spec.rb
|
168
|
+
- spec/whitespace_lint_spec.rb
|