di 0.3.2 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/HISTORY +28 -0
- data/LICENSE +1 -1
- data/di.gemspec +2 -0
- data/lib/di.rb +315 -118
- metadata +31 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 38a6ebb27f63c158a2281c8084a8b7e9f863c0694a27c65e046041dd417cb513
|
4
|
+
data.tar.gz: '05084a0031eb646d6250c9d479f23b8f438ac1ce6106f6c1b32d28fd4d02590b'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d410883c4714053d447fb99d320ebc5f451b3fab559f65b782e4d31d5885c6960b269e000377c0738c895063a93cadbecfb772aa7997acb4af300766ee14089c
|
7
|
+
data.tar.gz: e880ee0456c03170f1ca9276ee50864366b773bfa0b6182f1692251e5ae8438878fb3b06174ffc4ba22037fbfe9bae2ba04d37615133bc2976aa82089a8d6f5d
|
data/HISTORY
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
== 0.4.4 2021-04-06
|
2
|
+
|
3
|
+
* Fix a fatal conflict when -p is specified.
|
4
|
+
("error: conflicting output format options.")
|
5
|
+
|
6
|
+
== 0.4.3 2015-01-05
|
7
|
+
|
8
|
+
* Do not use colors if the terminal does not support colors.
|
9
|
+
|
10
|
+
* Do not invoke a pager when on a dumb terminal.
|
11
|
+
|
12
|
+
== 0.4.2 2013-08-16
|
13
|
+
|
14
|
+
* Do not close inherited file descriptors on invoking diff(1) so that
|
15
|
+
`di file <(command)` works.
|
16
|
+
|
17
|
+
== 0.4.1 2013-04-11
|
18
|
+
|
19
|
+
* Set better labels and disable pager if invoked by git difftool.
|
20
|
+
|
21
|
+
* Enhance the --color option like Git.
|
22
|
+
|
23
|
+
== 0.4.0 2013-04-04
|
24
|
+
|
25
|
+
* Add inline word-diff highlighting.
|
26
|
+
|
27
|
+
* Improve suspicious whitespace highlighting.
|
28
|
+
|
1
29
|
== 0.3.2 2013-01-09
|
2
30
|
|
3
31
|
* Do not choke on encoding errors when colorizing on Ruby 1.9+.
|
data/LICENSE
CHANGED
data/di.gemspec
CHANGED
@@ -14,6 +14,7 @@ default settings and some original features.
|
|
14
14
|
EOS
|
15
15
|
gem.summary = %q{A wrapper around GNU diff(1)}
|
16
16
|
gem.homepage = "https://github.com/knu/di"
|
17
|
+
gem.license = "2-clause BSDL"
|
17
18
|
|
18
19
|
gem.files = `git ls-files`.split($/)
|
19
20
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -25,4 +26,5 @@ EOS
|
|
25
26
|
gem.require_paths = ["lib"]
|
26
27
|
|
27
28
|
gem.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
|
29
|
+
gem.add_runtime_dependency("diff-lcs", ["~> 1.2.2"])
|
28
30
|
end
|
data/lib/di.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
#
|
4
4
|
# di - a wrapper around GNU diff(1)
|
5
5
|
#
|
6
|
-
# Copyright (c) 2008
|
6
|
+
# Copyright (c) 2008-2021 Akinori MUSHA
|
7
7
|
#
|
8
8
|
# All rights reserved.
|
9
9
|
#
|
@@ -28,9 +28,9 @@
|
|
28
28
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
29
29
|
# SUCH DAMAGE.
|
30
30
|
|
31
|
-
MYVERSION = "0.
|
31
|
+
MYVERSION = "0.4.4"
|
32
32
|
MYNAME = File.basename($0)
|
33
|
-
MYCOPYRIGHT = "Copyright (c) 2008
|
33
|
+
MYCOPYRIGHT = "Copyright (c) 2008-2021 Akinori MUSHA"
|
34
34
|
|
35
35
|
DIFF_CMD = ENV.fetch('DIFF', 'diff')
|
36
36
|
ENV_NAME = "#{MYNAME.tr('-a-z', '_A-Z')}_OPTIONS"
|
@@ -59,6 +59,10 @@ FIGNORE_GLOBS = ENV.fetch('FIGNORE', '').split(':').map { |pat|
|
|
59
59
|
|
60
60
|
IO::NULL = '/dev/null' unless defined? IO::NULL
|
61
61
|
|
62
|
+
PLUS_SIGN = '+'
|
63
|
+
MINUS_SIGN = '-'
|
64
|
+
EQUAL_SIGN = '='
|
65
|
+
|
62
66
|
def main(args)
|
63
67
|
setup
|
64
68
|
|
@@ -75,30 +79,47 @@ def warn(*lines)
|
|
75
79
|
}
|
76
80
|
end
|
77
81
|
|
82
|
+
def xsystem(*args)
|
83
|
+
args << { :close_others => false } unless RUBY_VERSION < '1.9'
|
84
|
+
system(*args)
|
85
|
+
end
|
86
|
+
|
78
87
|
def setup
|
79
88
|
require 'ostruct'
|
80
|
-
$diff = OpenStruct.new
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
89
|
+
$diff = OpenStruct.new({
|
90
|
+
:exclude => [],
|
91
|
+
:include => [],
|
92
|
+
:flags => [],
|
93
|
+
:format_flags => [],
|
94
|
+
:format => :normal,
|
95
|
+
:colors => OpenStruct.new({
|
96
|
+
:comment => "\e[1m",
|
97
|
+
:file1 => "\e[1m",
|
98
|
+
:file2 => "\e[1m",
|
99
|
+
:header => "\e[36m",
|
100
|
+
:function => "\e[m",
|
101
|
+
:new => "\e[32m",
|
102
|
+
:old => "\e[31m",
|
103
|
+
:new_word => "\e[7;32m",
|
104
|
+
:old_word => "\e[7;31m",
|
105
|
+
:changed => "\e[33m",
|
106
|
+
:unchanged => "",
|
107
|
+
:whitespace => "\e[40m",
|
108
|
+
:off => "\e[m",
|
109
|
+
:open_inv => "\e[7m",
|
110
|
+
:close_inv => "\e[27m",
|
111
|
+
}),
|
112
|
+
:reversed => false,
|
113
|
+
:word_regex => /([@$%]*[[:alnum:]_]+|[^\n])/,
|
114
|
+
})
|
115
|
+
end
|
116
|
+
|
117
|
+
def tty_color?
|
118
|
+
$stdout.tty? && `tput colors`.to_i >= 8
|
119
|
+
end
|
120
|
+
|
121
|
+
def tty_dumb?
|
122
|
+
!$stdout.tty? || ENV['TERM'] == 'dumb'
|
102
123
|
end
|
103
124
|
|
104
125
|
def parse_args!(args)
|
@@ -120,14 +141,23 @@ usage: #{MYNAME} [flags] [files]
|
|
120
141
|
|
121
142
|
opts.on('--[no-]pager',
|
122
143
|
'Pipe output into pager if stdout is a terminal. [+][*]') { |val|
|
123
|
-
$diff.use_pager = val
|
144
|
+
$diff.use_pager = val unless val && tty_dumb?
|
124
145
|
}
|
125
|
-
opts.on('--[no-]color',
|
146
|
+
opts.on('--[no-]color[=WHEN]',
|
126
147
|
'Colorize output if stdout is a terminal and the format is unified or context. [+][*]') { |val|
|
127
|
-
|
148
|
+
case val
|
149
|
+
when true, 'always'
|
150
|
+
$diff.colorize = true
|
151
|
+
when 'auto'
|
152
|
+
$diff.colorize = tty_color?
|
153
|
+
when false, 'never'
|
154
|
+
$diff.colorize = false
|
155
|
+
else
|
156
|
+
raise OptionParser::ParseError, "unknown value for --color: #{val}"
|
157
|
+
end
|
128
158
|
}
|
129
159
|
opts.on('--[no-]highlight-whitespace',
|
130
|
-
'Highlight
|
160
|
+
'Highlight whitespace differences in colorized output. [+][*]') { |val|
|
131
161
|
$diff.highlight_whitespace = val
|
132
162
|
}
|
133
163
|
opts.on('--[no-]rsync-exclude', '--[no-]cvs-exclude',
|
@@ -358,7 +388,7 @@ usage: #{MYNAME} [flags] [files]
|
|
358
388
|
|
359
389
|
----
|
360
390
|
EOF
|
361
|
-
|
391
|
+
xsystem(DIFF_CMD, '--version')
|
362
392
|
exit
|
363
393
|
}
|
364
394
|
opts.on('--help',
|
@@ -384,9 +414,16 @@ EOS
|
|
384
414
|
|
385
415
|
begin
|
386
416
|
opts.parse('--rsync-exclude', '--fignore-exclude', '--ignore-cvs-lines',
|
387
|
-
'--pager', '--color', '--highlight-whitespace',
|
417
|
+
'--pager', '--color=auto', '--highlight-whitespace',
|
388
418
|
'-U3', '-N', '-r', '-p', '-d')
|
389
419
|
|
420
|
+
if ENV['GIT_DIFFTOOL_EXTCMD']
|
421
|
+
if base = ENV['BASE']
|
422
|
+
opts.parse('--label', File.join('a', base), '--label', File.join('b', base))
|
423
|
+
end
|
424
|
+
opts.parse('--no-pager')
|
425
|
+
end
|
426
|
+
|
390
427
|
if value = ENV[ENV_NAME]
|
391
428
|
require 'shellwords'
|
392
429
|
opts.parse(*value.shellsplit)
|
@@ -394,8 +431,9 @@ EOS
|
|
394
431
|
|
395
432
|
opts.parse!(args)
|
396
433
|
|
434
|
+
# -U3 must come before -p, otherwise you get "error: conflicting output format options."
|
397
435
|
$diff.format_flags.each { |format_flag|
|
398
|
-
|
436
|
+
prepend_flag(*format_flag)
|
399
437
|
}
|
400
438
|
|
401
439
|
if $diff.ignore_cvs_lines
|
@@ -444,11 +482,7 @@ EOS
|
|
444
482
|
end
|
445
483
|
end
|
446
484
|
|
447
|
-
def
|
448
|
-
invoke_pager! if $diff.use_pager
|
449
|
-
end
|
450
|
-
|
451
|
-
def invoke_pager!
|
485
|
+
def invoke_filter
|
452
486
|
$stdout.flush
|
453
487
|
$stderr.flush
|
454
488
|
pr, pw = IO.pipe
|
@@ -458,11 +492,7 @@ def invoke_pager!
|
|
458
492
|
pr.close
|
459
493
|
pw.close
|
460
494
|
IO.select([$stdin], nil, [$stdin])
|
461
|
-
|
462
|
-
exec(ENV['PAGER'] || 'more')
|
463
|
-
rescue
|
464
|
-
$stderr.puts "Pager failed."
|
465
|
-
end
|
495
|
+
yield
|
466
496
|
}
|
467
497
|
|
468
498
|
$stdout.reopen(pw)
|
@@ -477,6 +507,45 @@ def invoke_pager!
|
|
477
507
|
}
|
478
508
|
end
|
479
509
|
|
510
|
+
def invoke_pager
|
511
|
+
invoke_pager! if $diff.use_pager
|
512
|
+
end
|
513
|
+
|
514
|
+
def invoke_pager!
|
515
|
+
invoke_filter {
|
516
|
+
begin
|
517
|
+
exec(ENV['PAGER'] || 'more')
|
518
|
+
rescue
|
519
|
+
$stderr.puts "Pager failed."
|
520
|
+
end
|
521
|
+
}
|
522
|
+
end
|
523
|
+
|
524
|
+
def invoke_colorizer
|
525
|
+
invoke_colorizer! if $diff.colorize
|
526
|
+
end
|
527
|
+
|
528
|
+
def invoke_colorizer!
|
529
|
+
invoke_filter {
|
530
|
+
case $diff.format
|
531
|
+
when :unified
|
532
|
+
colorize_unified_diff
|
533
|
+
when :context
|
534
|
+
colorize_context_diff
|
535
|
+
end
|
536
|
+
}
|
537
|
+
end
|
538
|
+
|
539
|
+
def prepend_flag(flag, val)
|
540
|
+
case val
|
541
|
+
when true, false
|
542
|
+
$diff.flags.reject! { |f,| f == flag }
|
543
|
+
$diff.flags.unshift [flag] if val
|
544
|
+
else
|
545
|
+
$diff.flags.unshift [flag, val]
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
480
549
|
def set_flag(flag, val)
|
481
550
|
case val
|
482
551
|
when true, false
|
@@ -577,21 +646,8 @@ def diff_files(file1, file2)
|
|
577
646
|
end
|
578
647
|
|
579
648
|
def call_diff(*args)
|
580
|
-
|
581
|
-
|
582
|
-
case $diff.format
|
583
|
-
when :unified
|
584
|
-
filter = method(:colorize_unified_diff)
|
585
|
-
when :context
|
586
|
-
filter = method(:colorize_context_diff)
|
587
|
-
end
|
588
|
-
end
|
589
|
-
if filter
|
590
|
-
require 'shellwords'
|
591
|
-
filter.call(IO.popen(command_args.shelljoin, 'r'))
|
592
|
-
else
|
593
|
-
system(*command_args)
|
594
|
-
end
|
649
|
+
invoke_colorizer
|
650
|
+
xsystem *[DIFF_CMD, $diff.flags, args].flatten
|
595
651
|
status = $? >> 8
|
596
652
|
$status = status if $status < status
|
597
653
|
return status
|
@@ -701,92 +757,228 @@ def diff_exclude?(dir, basename)
|
|
701
757
|
return false
|
702
758
|
end
|
703
759
|
|
704
|
-
def colorize_unified_diff
|
760
|
+
def colorize_unified_diff
|
761
|
+
begin
|
762
|
+
require 'diff/lcs'
|
763
|
+
colorize_unified_diff_hunk = method(:colorize_hunk_in_unified_diff_inline)
|
764
|
+
rescue LoadError
|
765
|
+
colorize_unified_diff_hunk = method(:colorize_hunk_in_unified_diff_normal)
|
766
|
+
end
|
767
|
+
|
705
768
|
colors = $diff.colors
|
769
|
+
colors.to_function ||= colors.off + colors.function
|
706
770
|
|
707
771
|
state = :comment
|
708
772
|
hunk_left = nil
|
709
|
-
|
773
|
+
hunk = []
|
774
|
+
$stdin.each_line { |line|
|
775
|
+
line.chomp!
|
710
776
|
replace_invalid_bytes!(line)
|
711
777
|
case state
|
712
778
|
when :comment
|
713
779
|
case line
|
714
780
|
when /^\+{3} /
|
715
|
-
color = colors
|
781
|
+
color = colors.file1
|
716
782
|
when /^-{3} /
|
717
|
-
color = colors
|
783
|
+
color = colors.file2
|
718
784
|
when /^@@ -[0-9]+(,([0-9]+))? \+[0-9]+(,([0-9]+))?/
|
719
785
|
state = :hunk
|
720
786
|
hunk_left = ($1 ? $2.to_i : 1) + ($3 ? $4.to_i : 1)
|
721
|
-
line.sub!(/^(@@ .*? @@
|
722
|
-
$1 +
|
787
|
+
line.sub!(/^(@@ .*? @@ )/) {
|
788
|
+
$1 + colors.to_function
|
723
789
|
}
|
724
|
-
color = colors
|
790
|
+
color = colors.header
|
725
791
|
else
|
726
|
-
color = colors
|
792
|
+
color = colors.comment
|
727
793
|
end
|
728
794
|
when :hunk
|
729
|
-
|
795
|
+
hunk << line
|
730
796
|
case line
|
731
|
-
when
|
732
|
-
color = colors[:new]
|
797
|
+
when /^[-+]/
|
733
798
|
hunk_left -= 1
|
734
|
-
check = $diff.highlight_whitespace
|
735
|
-
when /^-/
|
736
|
-
color = colors[:old]
|
737
|
-
hunk_left -= 1
|
738
|
-
check = $diff.highlight_whitespace
|
739
799
|
when /^ /
|
740
|
-
color = colors[:unchanged]
|
741
800
|
hunk_left -= 2
|
742
|
-
else
|
743
|
-
# error
|
744
|
-
color = colors[:comment]
|
745
|
-
end
|
746
|
-
if check
|
747
|
-
line.sub!(/([ \t]+)$/) {
|
748
|
-
colors[:off] + colors[:whitespace] + $1
|
749
|
-
}
|
750
|
-
true while line.sub!(/^(.[ \t]*)( +)(\t)/) {
|
751
|
-
$1 + colors[:off] + colors[:whitespace] + $2 + colors[:off] + color + $3
|
752
|
-
}
|
753
801
|
end
|
754
802
|
if hunk_left <= 0
|
755
|
-
|
803
|
+
colorize_unified_diff_hunk.call(hunk)
|
756
804
|
hunk_left = nil
|
805
|
+
hunk.clear
|
806
|
+
state = :comment
|
807
|
+
end
|
808
|
+
next
|
809
|
+
end
|
810
|
+
|
811
|
+
print color, line, colors.off, "\n"
|
812
|
+
}
|
813
|
+
end
|
814
|
+
|
815
|
+
def colorize_hunk_in_unified_diff_normal(hunk)
|
816
|
+
colors = $diff.colors
|
817
|
+
|
818
|
+
hunk.each { |line|
|
819
|
+
case line
|
820
|
+
when /^\+/
|
821
|
+
color = colors.new
|
822
|
+
ws = $diff.highlight_whitespace
|
823
|
+
when /^-/
|
824
|
+
color = colors.old
|
825
|
+
ws = $diff.highlight_whitespace
|
826
|
+
when /^ /
|
827
|
+
color = colors.unchanged
|
828
|
+
ws = false
|
829
|
+
end
|
830
|
+
if ws
|
831
|
+
highlight_whitespace_in_unified_diff!(line, color)
|
832
|
+
end
|
833
|
+
print color, line, colors.off, "\n"
|
834
|
+
}
|
835
|
+
end
|
836
|
+
|
837
|
+
def colorize_hunk_in_unified_diff_inline(hunk)
|
838
|
+
colors = $diff.colors
|
839
|
+
|
840
|
+
skip_next = false
|
841
|
+
|
842
|
+
Enumerator.new { |y|
|
843
|
+
y << nil
|
844
|
+
hunk.each { |line|
|
845
|
+
y << line
|
846
|
+
}
|
847
|
+
y << nil << nil
|
848
|
+
}.each_cons(4) { |line0, line1, line2, line3|
|
849
|
+
case
|
850
|
+
when skip_next
|
851
|
+
skip_next = false
|
852
|
+
next
|
853
|
+
when line1.nil?
|
854
|
+
break
|
855
|
+
when /^[-+]/ !~ line0 && /^-/ =~ line1 && /^\+/ =~ line2 && /^[-+]/ !~ line3
|
856
|
+
colorize_inline_diff(line1, line2)
|
857
|
+
skip_next = true
|
858
|
+
next
|
859
|
+
when /^\+/ =~ line1
|
860
|
+
color = colors.new
|
861
|
+
ws = $diff.highlight_whitespace
|
862
|
+
when /^-/ =~ line1
|
863
|
+
color = colors.old
|
864
|
+
ws = $diff.highlight_whitespace
|
865
|
+
when /^ / =~ line1
|
866
|
+
color = colors.unchanged
|
867
|
+
ws = false
|
868
|
+
end
|
869
|
+
if ws
|
870
|
+
line1 = line1.dup
|
871
|
+
highlight_whitespace_in_unified_diff!(line1, color)
|
872
|
+
end
|
873
|
+
print color, line1, colors.off, "\n"
|
874
|
+
}
|
875
|
+
end
|
876
|
+
|
877
|
+
def colorize_inline_diff(line1, line2)
|
878
|
+
words1, words2 = [line1, line2].map { |line|
|
879
|
+
line[1..-1].split($diff.word_regex)
|
880
|
+
}
|
881
|
+
xwords1, xwords2 = [words1, words2].map { |words|
|
882
|
+
words.each_with_index.map { |word, i| i.even? ? nil : word }
|
883
|
+
}
|
884
|
+
swords1, swords2, signs1, signs2 = [], [], [], []
|
885
|
+
|
886
|
+
Diff::LCS.sdiff(xwords1, xwords2).each { |tuple|
|
887
|
+
sign, (pos1, word1), (pos2, word2) = *tuple
|
888
|
+
case sign
|
889
|
+
when PLUS_SIGN
|
890
|
+
if signs2.last == sign
|
891
|
+
swords2.last << word2 if word2
|
892
|
+
else
|
893
|
+
swords2 << (word2 || '')
|
894
|
+
signs2 << sign
|
895
|
+
end
|
896
|
+
when MINUS_SIGN
|
897
|
+
if signs1.last == sign
|
898
|
+
swords1.last << word1 if word1
|
899
|
+
else
|
900
|
+
swords1 << (word1 || '')
|
901
|
+
signs1 << sign
|
902
|
+
end
|
903
|
+
else
|
904
|
+
if signs1.last == sign
|
905
|
+
swords1.last << words1[pos1]
|
906
|
+
else
|
907
|
+
swords1 << words1[pos1]
|
908
|
+
signs1 << sign
|
909
|
+
end
|
910
|
+
if signs2.last == sign
|
911
|
+
swords2.last << words2[pos2]
|
912
|
+
else
|
913
|
+
swords2 << words2[pos2]
|
914
|
+
signs2 << sign
|
757
915
|
end
|
758
916
|
end
|
917
|
+
}
|
759
918
|
|
760
|
-
|
761
|
-
line.sub!(/$/, colors[:off])
|
919
|
+
colors = $diff.colors
|
762
920
|
|
763
|
-
|
921
|
+
aline1 = ''.tap { |line|
|
922
|
+
signs1.zip(swords1) { |sign, word|
|
923
|
+
case sign
|
924
|
+
when EQUAL_SIGN
|
925
|
+
line << colors.off << colors.old << word
|
926
|
+
else
|
927
|
+
line << colors.off << colors.old_word << word
|
928
|
+
end
|
929
|
+
}
|
764
930
|
}
|
931
|
+
aline2 = ''.tap { |line|
|
932
|
+
signs2.zip(swords2) { |sign, word|
|
933
|
+
case sign
|
934
|
+
when EQUAL_SIGN
|
935
|
+
line << colors.off << colors.new << word
|
936
|
+
else
|
937
|
+
line << colors.off << colors.new_word << word
|
938
|
+
end
|
939
|
+
}
|
940
|
+
}
|
941
|
+
|
942
|
+
print colors.old, '-', aline1, colors.off, "\n",
|
943
|
+
colors.new, '+', aline2, colors.off, "\n"
|
944
|
+
end
|
945
|
+
|
946
|
+
def highlight_whitespace_in_unified_diff!(line, color)
|
947
|
+
colors = $diff.colors
|
948
|
+
colors.to_whitespace ||= colors.off + colors.whitespace
|
765
949
|
|
766
|
-
|
950
|
+
line.gsub!(/([ \t]+)$|( +)(?=\t)/) {
|
951
|
+
if $1
|
952
|
+
colors.to_whitespace + $1
|
953
|
+
else
|
954
|
+
colors.to_whitespace + $2 << colors.off << color
|
955
|
+
end
|
956
|
+
}
|
767
957
|
end
|
768
958
|
|
769
|
-
def colorize_context_diff
|
959
|
+
def colorize_context_diff
|
770
960
|
colors = $diff.colors
|
961
|
+
colors.to_function ||= colors.off + colors.function
|
771
962
|
|
772
963
|
state = :comment
|
773
964
|
hunk_part = nil
|
774
|
-
|
965
|
+
$stdin.each_line { |line|
|
966
|
+
line.chomp!
|
775
967
|
replace_invalid_bytes!(line)
|
776
968
|
case state
|
777
969
|
when :comment
|
778
970
|
case line
|
779
971
|
when /^\*{3} /
|
780
|
-
color = colors
|
972
|
+
color = colors.file1
|
781
973
|
when /^-{3} /
|
782
|
-
color = colors
|
974
|
+
color = colors.file2
|
783
975
|
when /^\*{15}/
|
784
976
|
state = :hunk
|
785
977
|
hunk_part = 0
|
786
|
-
line.sub!(/^(\*{15}
|
787
|
-
$1 +
|
978
|
+
line.sub!(/^(\*{15} )/) {
|
979
|
+
$1 + colors.to_function
|
788
980
|
}
|
789
|
-
color = colors
|
981
|
+
color = colors.header
|
790
982
|
end
|
791
983
|
when :hunk
|
792
984
|
case hunk_part
|
@@ -794,10 +986,10 @@ def colorize_context_diff(io)
|
|
794
986
|
case line
|
795
987
|
when /^\*{3} /
|
796
988
|
hunk_part = 1
|
797
|
-
color = colors
|
989
|
+
color = colors.header
|
798
990
|
else
|
799
991
|
# error
|
800
|
-
color = colors
|
992
|
+
color = colors.comment
|
801
993
|
end
|
802
994
|
when 1, 2
|
803
995
|
check = false
|
@@ -805,53 +997,58 @@ def colorize_context_diff(io)
|
|
805
997
|
when /^\-{3} /
|
806
998
|
if hunk_part == 1
|
807
999
|
hunk_part = 2
|
808
|
-
color = colors
|
1000
|
+
color = colors.header
|
809
1001
|
else
|
810
1002
|
#error
|
811
|
-
color = colors
|
1003
|
+
color = colors.comment
|
812
1004
|
end
|
813
1005
|
when /^\*{3} /, /^\*{15} /
|
814
1006
|
state = :comment
|
815
1007
|
redo
|
816
1008
|
when /^\+ /
|
817
|
-
color = colors
|
1009
|
+
color = colors.new
|
818
1010
|
check = $diff.highlight_whitespace
|
819
1011
|
when /^- /
|
820
|
-
color = colors
|
1012
|
+
color = colors.old
|
821
1013
|
check = $diff.highlight_whitespace
|
822
1014
|
when /^! /
|
823
|
-
color = colors
|
1015
|
+
color = colors.changed
|
824
1016
|
check = $diff.highlight_whitespace
|
825
1017
|
when /^ /
|
826
|
-
color = colors
|
1018
|
+
color = colors.unchanged
|
827
1019
|
else
|
828
1020
|
# error
|
829
|
-
color = colors
|
1021
|
+
color = colors.comment
|
830
1022
|
end
|
831
1023
|
if check
|
832
|
-
|
833
|
-
$1 + colors[:off] + colors[:whitespace] + $2
|
834
|
-
}
|
835
|
-
true while line.sub!(/^(. [ \t]*)( +)(\t)/) {
|
836
|
-
$1 + colors[:off] + colors[:whitespace] + $2 + colors[:off] + color + $3
|
837
|
-
}
|
1024
|
+
highlight_whitespace_in_context_diff!(line, color)
|
838
1025
|
end
|
839
1026
|
end
|
840
1027
|
end
|
841
1028
|
|
842
|
-
line.
|
843
|
-
line.sub!(/$/, colors[:off])
|
844
|
-
|
845
|
-
print line
|
1029
|
+
print color, line, colors.off, "\n"
|
846
1030
|
}
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
def highlight_whitespace_in_context_diff!(line, color)
|
1034
|
+
colors = $diff.colors
|
1035
|
+
colors.to_whitespace ||= colors.off + colors.whitespace
|
847
1036
|
|
848
|
-
|
1037
|
+
line.gsub!(/^(..)|([ \t]+)$|( +)(?=\t)/) {
|
1038
|
+
if $1
|
1039
|
+
$1
|
1040
|
+
elsif $2
|
1041
|
+
colors.to_whitespace + $2
|
1042
|
+
else
|
1043
|
+
colors.to_whitespace + $3 << colors.off << color
|
1044
|
+
end
|
1045
|
+
}
|
849
1046
|
end
|
850
1047
|
|
851
1048
|
def replace_invalid_bytes!(text)
|
852
1049
|
colors = $diff.colors
|
853
1050
|
text.replace(text.replace_invalid_bytes { |byte|
|
854
|
-
'%s<%02X>%s' % [colors
|
1051
|
+
'%s<%02X>%s' % [colors.open_inv, byte, colors.close_inv]
|
855
1052
|
})
|
856
1053
|
end
|
857
1054
|
|
metadata
CHANGED
@@ -1,21 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: di
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Akinori MUSHA
|
9
|
-
autorequire:
|
8
|
+
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
|
15
|
-
|
11
|
+
date: 2021-04-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: diff-lcs
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.2.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.2.2
|
27
|
+
description: |
|
28
|
+
The di(1) command wraps around GNU diff(1) to provide reasonable
|
16
29
|
default settings and some original features.
|
17
|
-
|
18
|
-
'
|
19
30
|
email:
|
20
31
|
- knu@idaemons.org
|
21
32
|
executables:
|
@@ -25,8 +36,8 @@ extra_rdoc_files:
|
|
25
36
|
- LICENSE
|
26
37
|
- README.rdoc
|
27
38
|
files:
|
28
|
-
- .document
|
29
|
-
- .gitignore
|
39
|
+
- ".document"
|
40
|
+
- ".gitignore"
|
30
41
|
- HISTORY
|
31
42
|
- LICENSE
|
32
43
|
- README.rdoc
|
@@ -37,28 +48,27 @@ files:
|
|
37
48
|
- test/helper.rb
|
38
49
|
- test/test_di.rb
|
39
50
|
homepage: https://github.com/knu/di
|
40
|
-
licenses:
|
41
|
-
|
51
|
+
licenses:
|
52
|
+
- 2-clause BSDL
|
53
|
+
metadata: {}
|
54
|
+
post_install_message:
|
42
55
|
rdoc_options: []
|
43
56
|
require_paths:
|
44
57
|
- lib
|
45
58
|
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
-
none: false
|
47
59
|
requirements:
|
48
|
-
- -
|
60
|
+
- - ">="
|
49
61
|
- !ruby/object:Gem::Version
|
50
62
|
version: 1.8.7
|
51
63
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
-
none: false
|
53
64
|
requirements:
|
54
|
-
- -
|
65
|
+
- - ">="
|
55
66
|
- !ruby/object:Gem::Version
|
56
67
|
version: '0'
|
57
68
|
requirements: []
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
specification_version: 3
|
69
|
+
rubygems_version: 3.0.3
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
62
72
|
summary: A wrapper around GNU diff(1)
|
63
73
|
test_files:
|
64
74
|
- test/helper.rb
|