irt 1.1.1
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.
- data/.gitignore +26 -0
- data/LICENSE +20 -0
- data/README.markdown +589 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/bin/irt +101 -0
- data/bin/irt_irb +4 -0
- data/bin/irt_rails2 +6 -0
- data/goodies/nano/README +6 -0
- data/goodies/nano/irt.nanorc +86 -0
- data/goodies/vi/README +5 -0
- data/irt.gemspec +29 -0
- data/irtrc +48 -0
- data/lib/irt.rb +143 -0
- data/lib/irt/commands/core.rb +52 -0
- data/lib/irt/commands/help.rb +111 -0
- data/lib/irt/commands/log.rb +52 -0
- data/lib/irt/commands/ri.rb +59 -0
- data/lib/irt/commands/system.rb +102 -0
- data/lib/irt/commands/test.rb +60 -0
- data/lib/irt/differ.rb +87 -0
- data/lib/irt/directives.rb +28 -0
- data/lib/irt/directives/test.rb +84 -0
- data/lib/irt/extensions/irb.rb +45 -0
- data/lib/irt/extensions/irb/commands.rb +42 -0
- data/lib/irt/extensions/irb/context.rb +147 -0
- data/lib/irt/extensions/kernel.rb +18 -0
- data/lib/irt/extensions/method.rb +36 -0
- data/lib/irt/extensions/object.rb +7 -0
- data/lib/irt/hunks.rb +111 -0
- data/lib/irt/init.rb +1 -0
- data/lib/irt/log.rb +94 -0
- data/lib/irt/session.rb +59 -0
- metadata +167 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
module IRT
|
2
|
+
module Commands
|
3
|
+
module Core
|
4
|
+
|
5
|
+
def irt(obj=nil)
|
6
|
+
irt_mode = context.irt_mode
|
7
|
+
to_mode = case obj
|
8
|
+
when nil
|
9
|
+
:interactive
|
10
|
+
when Binding
|
11
|
+
:binding
|
12
|
+
else
|
13
|
+
:inspect
|
14
|
+
end
|
15
|
+
raise IRT::SessionModeError, "You cannot pass binding in #{irt_mode} mode" \
|
16
|
+
if to_mode == :binding && (irt_mode == :binding || caller[0].match(/^\(/))
|
17
|
+
raise IRT::SessionModeError, "You cannot open another interactive session in #{irt_mode} mode" \
|
18
|
+
if to_mode == :interactive && irt_mode != :file
|
19
|
+
IRT::Session.enter to_mode, obj
|
20
|
+
end
|
21
|
+
alias_method :open_session, :irt # legacy method
|
22
|
+
|
23
|
+
%w[p y pp ap].each do |m|
|
24
|
+
define_method(m) do |*args|
|
25
|
+
args = [context.last_value] if args.empty?
|
26
|
+
super *args
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def vdiff(a,b)
|
31
|
+
puts IRT::Differ.new(a,b, :value, {:a_marker => 'a',
|
32
|
+
:b_marker => 'b',
|
33
|
+
:a_label => '',
|
34
|
+
:b_label => ''}).output
|
35
|
+
end
|
36
|
+
alias_method :vd, :vdiff
|
37
|
+
|
38
|
+
# rerun the same shell command
|
39
|
+
def rerun
|
40
|
+
ensure_session
|
41
|
+
IRB.irb_at_exit
|
42
|
+
str = "Rerunning: `#{ENV['IRT_COMMAND']}`"
|
43
|
+
puts
|
44
|
+
puts " #{str} ".error_color.bold.reversed.or("*** #{str} ***")
|
45
|
+
puts
|
46
|
+
exec ENV["IRT_COMMAND"]
|
47
|
+
end
|
48
|
+
alias_method :rr, :rerun
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module IRT
|
2
|
+
module Commands
|
3
|
+
module Help
|
4
|
+
|
5
|
+
def irt_help
|
6
|
+
ensure_session
|
7
|
+
puts %(
|
8
|
+
#{" NOTICE ".log_color.reversed.bold}
|
9
|
+
- The #{"Commands".interactive_color.bold} are methods generally available in any IRT session
|
10
|
+
- The #{"Directives".file_color.bold} are methods available in any file but not in IRT sessions
|
11
|
+
- The #{"Extensions".log_color.bold} are methods available anywhere
|
12
|
+
|
13
|
+
#{" Inspecting Commands ".interactive_color.reversed.bold}
|
14
|
+
irt object Opens an inspecting session into object
|
15
|
+
vdiff|vd obj_a, obj_b Prints the visual diff of the yaml dump of 2 objects
|
16
|
+
cat args Similar to system cat
|
17
|
+
ls args Similar to system ls
|
18
|
+
|
19
|
+
#{" Log Commands ".interactive_color.reversed.bold}
|
20
|
+
log|l [limit] Prints limit or 'tail_size' lines of the virtual log
|
21
|
+
full_log|ll Prints all the lines in the virtual log
|
22
|
+
print_lines|pl Prints the last lines of the current session
|
23
|
+
without numbers (for easy copying)
|
24
|
+
print_all_lines|pll Like print_line but prints all the sessions lines
|
25
|
+
|
26
|
+
#{" In Place Editing Commands ".interactive_color.reversed.bold}
|
27
|
+
(<editor> can be 'vi', 'nano|nn', 'edit|ed')
|
28
|
+
<editor> Uses <editor> to open the current evalued file at
|
29
|
+
the current evalued line for in place edit
|
30
|
+
<editor> file[, line] Uses <editor> to open file [at line] for in place
|
31
|
+
editing
|
32
|
+
<editor> hash Uses <editor> to open hash[:file] at the hash[:line]
|
33
|
+
<editor> array Uses <editor> to open array[0] at the array[1] line
|
34
|
+
<editor> traceline Uses <editor> to open the file at line in traceline
|
35
|
+
e.g.: nn "from /path/to/file.rb:34:in 'any_method'"
|
36
|
+
nn "a_gem (1.2.3) lib/file.rb:13:in 'a_meth'"
|
37
|
+
<editor> n Uses <editor> to open the backtraced file [n] at
|
38
|
+
the backtraced line
|
39
|
+
|
40
|
+
#{" Copy-Edit Commands ".interactive_color.reversed.bold + " (use copy_to_clipboard_command)".interactive_color.bold}
|
41
|
+
copy_lines|cl Copy the last session lines
|
42
|
+
copy_all_lines|cll Copy the lines of all the sessions
|
43
|
+
cnano|cnn Like nano, but copy the last session lines first
|
44
|
+
cvi Like vi, but copy the last session lines first
|
45
|
+
cedit|ced Like edit, but copy the last session lines first
|
46
|
+
|
47
|
+
#{" Test Commands ".interactive_color.reversed.bold + " (only available in interactive sessions)".interactive_color.bold}
|
48
|
+
add_desc|dd desc Adds a description for the test in the log
|
49
|
+
add_test|tt Adds a test in the log, checking the last value (_)
|
50
|
+
by automatically choosing the :_eql?, or :_yaml_eql?
|
51
|
+
method, depending on the type of the last value (_)
|
52
|
+
add_test|tt desc Like add_test but adds a 'desc' directive first'
|
53
|
+
save_as|sa path Saves the current irt file as path and runs it
|
54
|
+
|
55
|
+
#{" FileUtils Commands ".interactive_color.reversed.bold}
|
56
|
+
All the FileUtils methods are availabe as IRT Commands
|
57
|
+
(e.g. pwd, touch, mkdir, mv, cp, rm, rm_rf, compare_files, ...)
|
58
|
+
|
59
|
+
#{" Enhanced Commands ".interactive_color.reversed.bold}
|
60
|
+
p, pp, ap, y When invoked with no arguments print the last_value
|
61
|
+
(e.g. just type 'y' instead 'y _')
|
62
|
+
|
63
|
+
#{" Documentation Commands ".interactive_color.reversed.bold}
|
64
|
+
ri to_search Search the ri doc for to_search (no quotes needed)
|
65
|
+
ri obj.any_method Search the method.owner ri doc for of any_method
|
66
|
+
(no quotes needed, and completion available)
|
67
|
+
e.g.: ri "".eql? #=> ri doc for String#eql?
|
68
|
+
ri [].eql? #=> ri doc for Array#eql?
|
69
|
+
ri n Search the ri doc for the method n in a multiple
|
70
|
+
choices list
|
71
|
+
|
72
|
+
#{" Misc Commands ".interactive_color.reversed.bold}
|
73
|
+
x|q Aliases for exit (from the current session)
|
74
|
+
xx|qq Aliases for abort (abort the irt process)
|
75
|
+
status|ss Prints the session status line
|
76
|
+
rerun|rr Reruns the same file
|
77
|
+
irt_help|hh Shows this screen
|
78
|
+
|
79
|
+
#{" Session Directives ".file_color.reversed.bold}
|
80
|
+
irt Opens an interactive session which retains the
|
81
|
+
current variables and the last value (_)
|
82
|
+
irt binding Opens a binding session at the line of the call
|
83
|
+
|
84
|
+
#{" Test Directives ".file_color.reversed.bold + " (auto added by the Test Commands)".file_color.bold}
|
85
|
+
desc description Adds a description to the next test
|
86
|
+
_eql? val Runs a test checking _ == val
|
87
|
+
_yaml_eql? yaml_dump Runs a test checking y _ == yaml_dump
|
88
|
+
|
89
|
+
#{" Helper Directives ".file_color.reversed.bold}
|
90
|
+
insert_file file Evaluates file as it were inserted at that line
|
91
|
+
eval_file Alias for eval_file
|
92
|
+
irt_at_exit block Ensures execution of block at exit (useful for
|
93
|
+
cleanup of test env)
|
94
|
+
|
95
|
+
#{" Extensions ".log_color.reversed.bold}
|
96
|
+
Kernel#capture block Executes block and returns a string containing the
|
97
|
+
captured stdout
|
98
|
+
Object#own_methods Returns the methods implemented by the receiver
|
99
|
+
itself (not inherited)
|
100
|
+
Method#location When possible, it returns file and line where the
|
101
|
+
method is defined. It is uitable to be passed to the
|
102
|
+
in place editing commands.
|
103
|
+
Method#info Returns useful info about the method. It is suitable
|
104
|
+
to be passed to the in place editing commands.
|
105
|
+
)
|
106
|
+
end
|
107
|
+
alias_method :hh, :irt_help
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module IRT
|
2
|
+
module Commands
|
3
|
+
module Log
|
4
|
+
|
5
|
+
def log(limit=nil)
|
6
|
+
ensure_session
|
7
|
+
IRT.log.print limit || IRT.log.tail_size
|
8
|
+
IRT.log.print_status
|
9
|
+
end
|
10
|
+
alias_method :l, :log
|
11
|
+
|
12
|
+
def full_log
|
13
|
+
ensure_session
|
14
|
+
IRT.log.print
|
15
|
+
IRT.log.print_status
|
16
|
+
end
|
17
|
+
alias_method :ll, :full_log
|
18
|
+
|
19
|
+
def status
|
20
|
+
ensure_session
|
21
|
+
IRT.log.print_status
|
22
|
+
end
|
23
|
+
alias_method :ss, :status
|
24
|
+
|
25
|
+
def print_lines
|
26
|
+
ensure_session
|
27
|
+
lines_str = IRT.log.last.lines_str
|
28
|
+
return if lines_str.empty?
|
29
|
+
puts
|
30
|
+
puts lines_str
|
31
|
+
puts
|
32
|
+
end
|
33
|
+
alias_method :pl, :print_lines
|
34
|
+
|
35
|
+
def print_all_lines
|
36
|
+
ensure_session
|
37
|
+
lines = []
|
38
|
+
IRT.log.reject{|h| h.class == IRT::Log::FileHunk }.each do |h|
|
39
|
+
ls = h.lines_str
|
40
|
+
lines << ls unless ls.empty?
|
41
|
+
end
|
42
|
+
unless lines.empty?
|
43
|
+
puts
|
44
|
+
puts lines.join("\n\n")
|
45
|
+
puts
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias_method :pll, :print_all_lines
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module IRT
|
2
|
+
module Commands
|
3
|
+
module Ri
|
4
|
+
|
5
|
+
@@choices_map = {}
|
6
|
+
|
7
|
+
def self.reset_choices_map
|
8
|
+
@@choices_map = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def ri(arg)
|
12
|
+
ensure_session
|
13
|
+
raise IRT::NotImplementedError, "No available ri_command_format for this system." unless IRT.ri_command_format
|
14
|
+
case
|
15
|
+
when arg.nil?, arg.empty?
|
16
|
+
return puts('nil')
|
17
|
+
when arg.match(/^\d+$/)
|
18
|
+
if @@choices_map.key?(arg)
|
19
|
+
to_search = @@choices_map[arg]
|
20
|
+
else
|
21
|
+
raise IndexError, "No such method index -- [#{arg}]"
|
22
|
+
end
|
23
|
+
else
|
24
|
+
segm = arg.split('.')
|
25
|
+
to_search = segm.pop
|
26
|
+
unless segm.empty?
|
27
|
+
begin
|
28
|
+
meth = eval "#{segm.join('.')}.method(:#{to_search})", IRB.CurrentContext.workspace.binding
|
29
|
+
to_search = "#{meth.owner.name}##{meth.name}"
|
30
|
+
rescue
|
31
|
+
raise NoMethodError, %(undefined method "#{to_search}" for "#{segm.join('.')}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
process_ri to_search
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def process_ri(to_search)
|
41
|
+
ri = `#{sprintf(IRT.ri_command_format, to_search)}`
|
42
|
+
if m = ri.match(/^(-+.*Multiple choices:.*\n\n)(.+)/m)
|
43
|
+
output, methods = m.captures
|
44
|
+
IRT::Commands::Ri.reset_choices_map
|
45
|
+
fmt = "%+7s %s\n"
|
46
|
+
methods.gsub(/\s+/, '').split(',').each_with_index do |m, i|
|
47
|
+
@@choices_map[(i+1).to_s] = m
|
48
|
+
output << sprintf( fmt, "#{i+1}", m )
|
49
|
+
end
|
50
|
+
output << "\n"
|
51
|
+
else
|
52
|
+
output = ri
|
53
|
+
end
|
54
|
+
puts output
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module IRT
|
2
|
+
module Commands
|
3
|
+
module System
|
4
|
+
|
5
|
+
def cat(*args)
|
6
|
+
ensure_session
|
7
|
+
return system "cat #{context.file_line_pointers.first}" if args.empty?
|
8
|
+
system "cat #{args * ' '}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def ls(*args)
|
12
|
+
ensure_session
|
13
|
+
args = %w[.] if args.empty?
|
14
|
+
system "ls #{args * ' '}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_lines
|
18
|
+
ensure_session
|
19
|
+
copy_to_clipboard :print_lines
|
20
|
+
end
|
21
|
+
alias_method :cl, :copy_lines
|
22
|
+
|
23
|
+
def copy_all_lines
|
24
|
+
ensure_session
|
25
|
+
copy_to_clipboard :print_all_lines
|
26
|
+
end
|
27
|
+
alias_method :cll, :copy_all_lines
|
28
|
+
|
29
|
+
%w[vi nano edit].each do |n|
|
30
|
+
eval <<-EOE, binding, __FILE__, __LINE__+1
|
31
|
+
def #{n}(*args)
|
32
|
+
ensure_session
|
33
|
+
run_editor(:#{n}, *args)
|
34
|
+
end
|
35
|
+
EOE
|
36
|
+
eval <<-EOE, binding, __FILE__, __LINE__+1
|
37
|
+
def c#{n}(*args)
|
38
|
+
ensure_session
|
39
|
+
copy_lines
|
40
|
+
#{n} *args
|
41
|
+
end
|
42
|
+
EOE
|
43
|
+
end
|
44
|
+
alias_method :nn, :nano
|
45
|
+
alias_method :ed, :edit
|
46
|
+
alias_method :cnn, :cnano
|
47
|
+
alias_method :ced, :cedit
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def run_editor(cmd, *args)
|
52
|
+
cmd_format = IRT.send("#{cmd}_command_format".to_sym)
|
53
|
+
raise IRT::NotImplementedError, "#{cmd}_command_format missing" unless cmd_format
|
54
|
+
arg = args.first if args.size == 1
|
55
|
+
file, line = case
|
56
|
+
when args.empty?
|
57
|
+
context.file_line_pointers
|
58
|
+
when arg.is_a?(Integer)
|
59
|
+
if context.backtrace_map.key?(arg)
|
60
|
+
context.backtrace_map[arg]
|
61
|
+
else
|
62
|
+
raise IRT::IndexError, "No such backtrace index -- [#{arg}]"
|
63
|
+
return
|
64
|
+
end
|
65
|
+
when arg.is_a?(Array)
|
66
|
+
arg
|
67
|
+
when arg.is_a?(Hash)
|
68
|
+
[arg[:file], arg[:line]]
|
69
|
+
when arg.is_a?(String) && m = arg.match(/(?:([\w]+) \(([\w.]+)\))? ?([+\w\/\n.-]+):(\d+)/m)
|
70
|
+
gem, vers, f, l = m.captures
|
71
|
+
if gem
|
72
|
+
Gem.path.each do |p|
|
73
|
+
gp = File.join(p, 'gems', "#{gem}-#{vers}", f)
|
74
|
+
break [gp, l] if File.exist?(gp)
|
75
|
+
end
|
76
|
+
else
|
77
|
+
[f.gsub("\n", ''), l]
|
78
|
+
end
|
79
|
+
else
|
80
|
+
args
|
81
|
+
end
|
82
|
+
system sprintf(cmd_format, file, line)
|
83
|
+
end
|
84
|
+
|
85
|
+
def copy_to_clipboard(cmd)
|
86
|
+
raise IRT::NotImplementedError, "No known copy_to_clipboard_command for this system." \
|
87
|
+
unless IRT.copy_to_clipboard_command
|
88
|
+
lines_str = capture { send(cmd) }
|
89
|
+
return unless lines_str.match(/\w/m)
|
90
|
+
begin
|
91
|
+
IO.popen(IRT.copy_to_clipboard_command, 'w') do |io|
|
92
|
+
io.puts lines_str.strip
|
93
|
+
end
|
94
|
+
print lines_str
|
95
|
+
rescue Exception
|
96
|
+
raise IRT::NotImplementedError, "This system does not appear to support the \`#{IRT.copy_to_clipboard_command}\` command."
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module IRT
|
2
|
+
module Commands
|
3
|
+
module Test
|
4
|
+
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def add_desc(description)
|
8
|
+
mode = context.irt_mode
|
9
|
+
raise IRT::SessionModeError, "You cannot add a test description in #{mode} mode." unless mode == :interactive
|
10
|
+
desc_str = %(desc "#{description}")
|
11
|
+
context.current_line = desc_str
|
12
|
+
puts
|
13
|
+
puts desc_str.interactive_color
|
14
|
+
puts
|
15
|
+
end
|
16
|
+
alias_method :dd, :add_desc
|
17
|
+
|
18
|
+
def add_test(description='')
|
19
|
+
mode = context.irt_mode
|
20
|
+
raise IRT::SessionModeError, "You cannot add a test in #{mode} mode." unless mode == :interactive
|
21
|
+
last_value = context.last_value
|
22
|
+
begin
|
23
|
+
evaled = context.workspace.evaluate(self, last_value.inspect)
|
24
|
+
rescue Exception
|
25
|
+
end
|
26
|
+
# the eval of the last_value.inspect == the last_value
|
27
|
+
test_str = if evaled == last_value
|
28
|
+
# same as _? but easier to read for multiline strings
|
29
|
+
if last_value.is_a?(String) && last_value.match(/\n/)
|
30
|
+
str = last_value.split("\n").map{|l| l.inspect.sub(/^"(.*)"$/,'\1') }.join("\n")
|
31
|
+
last_value.match(/\n$/) ? "_eql? <<EOS\n#{str}\nEOS" : "_eql? %(#{str})"
|
32
|
+
else
|
33
|
+
"_eql?( #{last_value.inspect} )"
|
34
|
+
end
|
35
|
+
else # need YAML
|
36
|
+
"_yaml_eql? %(#{IRT.yaml_dump(last_value)})"
|
37
|
+
end
|
38
|
+
desc_str = description.empty? ? '' : %(desc "#{description}"\n)
|
39
|
+
str = desc_str + test_str
|
40
|
+
context.current_line = str
|
41
|
+
puts
|
42
|
+
puts str.interactive_color
|
43
|
+
puts
|
44
|
+
end
|
45
|
+
alias_method :tt, :add_test
|
46
|
+
|
47
|
+
def save_as(path)
|
48
|
+
path = File.expand_path(path)
|
49
|
+
if File.exists?(path)
|
50
|
+
return if IRT.prompter.no? %(Do you want to overwrite "#{path}"?), :hint => '[y|<enter=n]', :default => 'n'
|
51
|
+
end
|
52
|
+
cp IRT.irt_file, path
|
53
|
+
ENV['IRT_COMMAND'] = ENV['IRT_COMMAND'].sub(/#{Regexp.quote(IRT.irt_file)}/, path)
|
54
|
+
rerun
|
55
|
+
end
|
56
|
+
alias_method :sa, :save_as
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/irt/differ.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'differ'
|
2
|
+
module IRT
|
3
|
+
class Differ
|
4
|
+
|
5
|
+
def initialize(a, b, kind=:value, options={})
|
6
|
+
if kind == :value
|
7
|
+
a = IRT.yaml_dump a
|
8
|
+
b = IRT.yaml_dump b
|
9
|
+
end
|
10
|
+
@a = a
|
11
|
+
@b = b
|
12
|
+
@options = { :a_label => 'saved',
|
13
|
+
:b_label => 'actual',
|
14
|
+
:a_marker => '~',
|
15
|
+
:b_marker => '!' }.merge options
|
16
|
+
IRT::Differ::Format.options = @options
|
17
|
+
@diff = ::Differ.diff_by_line(@b, @a)
|
18
|
+
end
|
19
|
+
|
20
|
+
def output
|
21
|
+
out = "\n"
|
22
|
+
out << " = same ".reversed.bold.or('***** diff ')
|
23
|
+
out << " #{@options[:a_marker]} #{@options[:a_label]} ".diff_a_color.reversed.bold.
|
24
|
+
or(" (#{@options[:a_marker]} #{@options[:a_label]}) ")
|
25
|
+
out << " #{@options[:b_marker]} #{@options[:b_label]} ".diff_b_color.reversed.bold.
|
26
|
+
or(" (#{@options[:b_marker]} #{@options[:b_label]}) ")
|
27
|
+
out << "\n"
|
28
|
+
diff = @diff.format_as(IRT::Differ::Format)
|
29
|
+
out << diff.sub(/^\n/,'')
|
30
|
+
out << "\n"
|
31
|
+
out
|
32
|
+
end
|
33
|
+
|
34
|
+
module Format
|
35
|
+
extend self
|
36
|
+
|
37
|
+
attr_accessor :options
|
38
|
+
|
39
|
+
def format(change)
|
40
|
+
(change.is_a?(String) && as_same(change)) ||
|
41
|
+
(change.change? && as_change(change)) ||
|
42
|
+
(change.delete? && as_delete(change)) ||
|
43
|
+
(change.insert? && as_insert(change)) ||
|
44
|
+
''
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def process(string, mark='=', color=:null, bold=:null)
|
50
|
+
string.sub(/^\n/,'').split("\n").map do |s|
|
51
|
+
" #{mark} ".send(color).send(bold).reversed.or(" #{mark} ") + ' ' + s.send(color)
|
52
|
+
end.join("\n") + "\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
def as_same(string)
|
56
|
+
process string
|
57
|
+
end
|
58
|
+
|
59
|
+
def as_insert(change)
|
60
|
+
process(change.insert(), options[:b_marker], :diff_b_color, :bold)
|
61
|
+
end
|
62
|
+
|
63
|
+
def as_delete(change)
|
64
|
+
process(change.delete(), options[:a_marker], :diff_a_color, :bold)
|
65
|
+
end
|
66
|
+
|
67
|
+
def as_change(change)
|
68
|
+
as_delete(change) << as_insert(change)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module Differ
|
76
|
+
class Diff
|
77
|
+
|
78
|
+
def format_as(f)
|
79
|
+
f = Differ.format_for(f)
|
80
|
+
@raw.inject('') do |sum, part|
|
81
|
+
part = f.format(part)
|
82
|
+
sum << part
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|