irb 1.3.1 → 1.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +10 -0
- data/Rakefile +8 -1
- data/irb.gemspec +2 -48
- data/lib/irb.rb +30 -11
- data/lib/irb/cmd/info.rb +25 -0
- data/lib/irb/cmd/ls.rb +107 -0
- data/lib/irb/cmd/measure.rb +10 -4
- data/lib/irb/cmd/nop.rb +10 -4
- data/lib/irb/cmd/show_source.rb +86 -0
- data/lib/irb/cmd/whereami.rb +20 -0
- data/lib/irb/color.rb +14 -16
- data/lib/irb/color_printer.rb +24 -5
- data/lib/irb/completion.rb +73 -3
- data/lib/irb/ext/loader.rb +46 -19
- data/lib/irb/ext/save-history.rb +15 -5
- data/lib/irb/extend-command.rb +21 -4
- data/lib/irb/init.rb +27 -5
- data/lib/irb/input-method.rb +19 -2
- data/lib/irb/lc/help-message +6 -6
- data/lib/irb/ruby-lex.rb +131 -21
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +2 -1
- metadata +13 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7071322837c419efbce74bd5aa91c9b83a9a3fd31e893e72376b763b2bbf4409
|
4
|
+
data.tar.gz: fa4e508771f91e4da313913592a7caa713cb82069f57d4dab059426baa764fc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b040a17c30df8f8512c176acfb1884237c050d5e4dab769f08aa75a00da23dcba1be9fab15d37671e4617abee3f6279363fed80c0980687cdcbed417bf5e3f4
|
7
|
+
data.tar.gz: 0a021169f28c114aeac7b7375eda932cdd4b357056b092a8499a61da6d4d1b01d019591e94eaaf134392a8b5c92cd632d0dfc7bf4b243831df93cc0514cd2eb1
|
data/Gemfile
CHANGED
@@ -3,3 +3,13 @@ source "https://rubygems.org"
|
|
3
3
|
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
4
4
|
|
5
5
|
gemspec
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "bundler"
|
9
|
+
is_unix = RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
|
10
|
+
is_truffleruby = RUBY_DESCRIPTION =~ /truffleruby/
|
11
|
+
gem 'vterm', '>= 0.0.5' if is_unix && ENV['WITH_VTERM']
|
12
|
+
gem 'yamatanooroti', '>= 0.0.6'
|
13
|
+
gem "rake"
|
14
|
+
gem "stackprof" if is_unix && !is_truffleruby
|
15
|
+
end
|
data/Rakefile
CHANGED
@@ -4,7 +4,14 @@ require "rake/testtask"
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
5
5
|
t.libs << "test" << "test/lib"
|
6
6
|
t.libs << "lib"
|
7
|
-
t.test_files = FileList["test
|
7
|
+
t.test_files = FileList["test/irb/test_*.rb"]
|
8
|
+
end
|
9
|
+
|
10
|
+
Rake::TestTask.new(:test_yamatanooroti) do |t|
|
11
|
+
t.libs << 'test'
|
12
|
+
t.libs << 'lib'
|
13
|
+
#t.loader = :direct
|
14
|
+
t.pattern = 'test/irb/yamatanooroti/test_*.rb'
|
8
15
|
end
|
9
16
|
|
10
17
|
task :default => :test
|
data/irb.gemspec
CHANGED
@@ -28,59 +28,13 @@ Gem::Specification.new do |spec|
|
|
28
28
|
"doc/irb/irb.rd.ja",
|
29
29
|
"exe/irb",
|
30
30
|
"irb.gemspec",
|
31
|
-
"lib/irb.rb",
|
32
|
-
"lib/irb/cmd/chws.rb",
|
33
|
-
"lib/irb/cmd/fork.rb",
|
34
|
-
"lib/irb/cmd/help.rb",
|
35
|
-
"lib/irb/cmd/load.rb",
|
36
|
-
"lib/irb/cmd/measure.rb",
|
37
|
-
"lib/irb/cmd/nop.rb",
|
38
|
-
"lib/irb/cmd/pushws.rb",
|
39
|
-
"lib/irb/cmd/subirb.rb",
|
40
|
-
"lib/irb/color.rb",
|
41
|
-
"lib/irb/color_printer.rb",
|
42
|
-
"lib/irb/completion.rb",
|
43
|
-
"lib/irb/context.rb",
|
44
|
-
"lib/irb/easter-egg.rb",
|
45
|
-
"lib/irb/ext/change-ws.rb",
|
46
|
-
"lib/irb/ext/history.rb",
|
47
|
-
"lib/irb/ext/loader.rb",
|
48
|
-
"lib/irb/ext/multi-irb.rb",
|
49
|
-
"lib/irb/ext/save-history.rb",
|
50
|
-
"lib/irb/ext/tracer.rb",
|
51
|
-
"lib/irb/ext/use-loader.rb",
|
52
|
-
"lib/irb/ext/workspaces.rb",
|
53
|
-
"lib/irb/extend-command.rb",
|
54
|
-
"lib/irb/frame.rb",
|
55
|
-
"lib/irb/help.rb",
|
56
|
-
"lib/irb/init.rb",
|
57
|
-
"lib/irb/input-method.rb",
|
58
|
-
"lib/irb/inspector.rb",
|
59
|
-
"lib/irb/lc/error.rb",
|
60
|
-
"lib/irb/lc/help-message",
|
61
|
-
"lib/irb/lc/ja/encoding_aliases.rb",
|
62
|
-
"lib/irb/lc/ja/error.rb",
|
63
|
-
"lib/irb/lc/ja/help-message",
|
64
|
-
"lib/irb/locale.rb",
|
65
|
-
"lib/irb/magic-file.rb",
|
66
|
-
"lib/irb/notifier.rb",
|
67
|
-
"lib/irb/output-method.rb",
|
68
|
-
"lib/irb/ruby-lex.rb",
|
69
|
-
"lib/irb/ruby_logo.aa",
|
70
|
-
"lib/irb/src_encoding.rb",
|
71
|
-
"lib/irb/version.rb",
|
72
|
-
"lib/irb/workspace.rb",
|
73
|
-
"lib/irb/ws-for-case-2.rb",
|
74
|
-
"lib/irb/xmp.rb",
|
75
31
|
"man/irb.1",
|
76
|
-
]
|
32
|
+
] + Dir.glob("lib/**/*")
|
77
33
|
spec.bindir = "exe"
|
78
34
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
79
35
|
spec.require_paths = ["lib"]
|
80
36
|
|
81
37
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
|
82
38
|
|
83
|
-
spec.add_dependency "reline", ">= 0.
|
84
|
-
spec.add_development_dependency "bundler"
|
85
|
-
spec.add_development_dependency "rake"
|
39
|
+
spec.add_dependency "reline", ">= 0.2.5"
|
86
40
|
end
|
data/lib/irb.rb
CHANGED
@@ -60,7 +60,11 @@ require_relative "irb/easter-egg"
|
|
60
60
|
# -E enc Same as `ruby -E`
|
61
61
|
# -w Same as `ruby -w`
|
62
62
|
# -W[level=2] Same as `ruby -W`
|
63
|
-
# --
|
63
|
+
# --context-mode n Set n[0-4] to method to create Binding Object,
|
64
|
+
# when new workspace was created
|
65
|
+
# --echo Show result(default)
|
66
|
+
# --noecho Don't show result
|
67
|
+
# --inspect Use `inspect' for output
|
64
68
|
# --noinspect Don't use inspect for output
|
65
69
|
# --multiline Use multiline editor module
|
66
70
|
# --nomultiline Don't use multiline editor module
|
@@ -68,19 +72,24 @@ require_relative "irb/easter-egg"
|
|
68
72
|
# --nosingleline Don't use singleline editor module
|
69
73
|
# --colorize Use colorization
|
70
74
|
# --nocolorize Don't use colorization
|
71
|
-
# --prompt prompt-mode
|
72
|
-
# --prompt-mode prompt-mode
|
75
|
+
# --prompt prompt-mode/--prompt-mode prompt-mode
|
73
76
|
# Switch prompt mode. Pre-defined prompt modes are
|
74
77
|
# `default', `simple', `xmp' and `inf-ruby'
|
75
78
|
# --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
|
76
79
|
# Suppresses --multiline and --singleline.
|
77
|
-
# --simple-prompt
|
80
|
+
# --sample-book-mode/--simple-prompt
|
81
|
+
# Simple prompt mode
|
78
82
|
# --noprompt No prompt mode
|
83
|
+
# --single-irb Share self with sub-irb.
|
79
84
|
# --tracer Display trace for each execution of commands.
|
80
85
|
# --back-trace-limit n
|
81
86
|
# Display backtrace top n and tail n. The default
|
82
87
|
# value is 16.
|
83
|
-
#
|
88
|
+
# --verbose Show details
|
89
|
+
# --noverbose Don't show details
|
90
|
+
# -v, --version Print the version of irb
|
91
|
+
# -h, --help Print help
|
92
|
+
# -- Separate options of irb from the list of command-line args
|
84
93
|
#
|
85
94
|
# == Configuration
|
86
95
|
#
|
@@ -463,7 +472,7 @@ module IRB
|
|
463
472
|
conf[:IRB_RC].call(context) if conf[:IRB_RC]
|
464
473
|
conf[:MAIN_CONTEXT] = context
|
465
474
|
|
466
|
-
trap("SIGINT") do
|
475
|
+
prev_trap = trap("SIGINT") do
|
467
476
|
signal_handle
|
468
477
|
end
|
469
478
|
|
@@ -472,6 +481,7 @@ module IRB
|
|
472
481
|
eval_input
|
473
482
|
end
|
474
483
|
ensure
|
484
|
+
trap("SIGINT", prev_trap)
|
475
485
|
conf[:AT_EXIT].each{|hook| hook.call}
|
476
486
|
end
|
477
487
|
end
|
@@ -525,7 +535,7 @@ module IRB
|
|
525
535
|
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
526
536
|
end
|
527
537
|
else
|
528
|
-
print "\n"
|
538
|
+
print "\n" if @context.prompting?
|
529
539
|
end
|
530
540
|
end
|
531
541
|
l
|
@@ -574,13 +584,21 @@ module IRB
|
|
574
584
|
next
|
575
585
|
end
|
576
586
|
handle_exception(exc)
|
587
|
+
@context.workspace.local_variable_set(:_, exc)
|
588
|
+
exc = nil
|
577
589
|
end
|
578
590
|
end
|
579
591
|
end
|
580
592
|
|
581
|
-
def convert_invalid_byte_sequence(str)
|
582
|
-
str
|
583
|
-
|
593
|
+
def convert_invalid_byte_sequence(str, enc)
|
594
|
+
str.force_encoding(enc)
|
595
|
+
str.scrub { |c|
|
596
|
+
c.bytes.map{ |b| "\\x#{b.to_s(16).upcase}" }.join
|
597
|
+
}
|
598
|
+
end
|
599
|
+
|
600
|
+
def encode_with_invalid_byte_sequence(str, enc)
|
601
|
+
conv = Encoding::Converter.new(str.encoding, enc)
|
584
602
|
dst = String.new
|
585
603
|
begin
|
586
604
|
ret = conv.primitive_convert(str, dst)
|
@@ -628,7 +646,8 @@ module IRB
|
|
628
646
|
message = exc.full_message(order: :top)
|
629
647
|
order = :top
|
630
648
|
end
|
631
|
-
message = convert_invalid_byte_sequence(message)
|
649
|
+
message = convert_invalid_byte_sequence(message, exc.message.encoding)
|
650
|
+
message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s)
|
632
651
|
message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
|
633
652
|
case order
|
634
653
|
when :top
|
data/lib/irb/cmd/info.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require_relative "nop"
|
4
|
+
|
5
|
+
# :stopdoc:
|
6
|
+
module IRB
|
7
|
+
module ExtendCommand
|
8
|
+
class Info < Nop
|
9
|
+
def execute
|
10
|
+
Class.new {
|
11
|
+
def inspect
|
12
|
+
str = "Ruby version: #{RUBY_VERSION}\n"
|
13
|
+
str += "IRB version: #{IRB.version}\n"
|
14
|
+
str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
|
15
|
+
str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
|
16
|
+
str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
|
17
|
+
str
|
18
|
+
end
|
19
|
+
alias_method :to_s, :inspect
|
20
|
+
}.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# :startdoc:
|
data/lib/irb/cmd/ls.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "reline"
|
4
|
+
require 'set'
|
5
|
+
require_relative "nop"
|
6
|
+
require_relative "../color"
|
7
|
+
|
8
|
+
# :stopdoc:
|
9
|
+
module IRB
|
10
|
+
module ExtendCommand
|
11
|
+
class Ls < Nop
|
12
|
+
def execute(*arg, grep: nil)
|
13
|
+
o = Output.new(grep: grep)
|
14
|
+
|
15
|
+
obj = arg.empty? ? irb_context.workspace.main : arg.first
|
16
|
+
locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
|
17
|
+
klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
|
18
|
+
|
19
|
+
o.dump("constants", obj.constants) if obj.respond_to?(:constants)
|
20
|
+
dump_singleton_methods(o, klass, obj)
|
21
|
+
dump_instance_methods(o, klass)
|
22
|
+
o.dump("instance variables", obj.instance_variables)
|
23
|
+
o.dump("class variables", klass.class_variables)
|
24
|
+
o.dump("locals", locals)
|
25
|
+
end
|
26
|
+
|
27
|
+
def dump_singleton_methods(o, klass, obj)
|
28
|
+
maps = class_method_map(obj.singleton_class.ancestors.take_while { |c| c != klass })
|
29
|
+
maps.each do |mod, methods|
|
30
|
+
name = mod == obj.singleton_class ? "#{klass}.methods" : "#{mod}#methods"
|
31
|
+
o.dump(name, methods)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def dump_instance_methods(o, klass)
|
36
|
+
maps = class_method_map(klass.ancestors)
|
37
|
+
maps.each do |mod, methods|
|
38
|
+
o.dump("#{mod}#methods", methods)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def class_method_map(classes)
|
43
|
+
dumped = Set.new
|
44
|
+
classes.reject { |mod| mod >= Object }.map do |mod|
|
45
|
+
methods = mod.public_instance_methods(false).select { |m| dumped.add?(m) }
|
46
|
+
[mod, methods]
|
47
|
+
end.reverse
|
48
|
+
end
|
49
|
+
|
50
|
+
class Output
|
51
|
+
MARGIN = " "
|
52
|
+
|
53
|
+
def initialize(grep: nil)
|
54
|
+
@grep = grep
|
55
|
+
@line_width = screen_width - MARGIN.length # right padding
|
56
|
+
end
|
57
|
+
|
58
|
+
def dump(name, strs)
|
59
|
+
strs = strs.grep(@grep) if @grep
|
60
|
+
strs = strs.sort
|
61
|
+
return if strs.empty?
|
62
|
+
|
63
|
+
# Attempt a single line
|
64
|
+
print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
|
65
|
+
if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
|
66
|
+
puts strs.join(MARGIN)
|
67
|
+
return
|
68
|
+
end
|
69
|
+
puts
|
70
|
+
|
71
|
+
# Dump with the largest # of columns that fits on a line
|
72
|
+
cols = strs.size
|
73
|
+
until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
|
74
|
+
cols -= 1
|
75
|
+
end
|
76
|
+
widths = col_widths(strs, cols: cols)
|
77
|
+
strs.each_slice(cols) do |ss|
|
78
|
+
puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def fits_on_line?(strs, cols:, offset: 0)
|
85
|
+
width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
|
86
|
+
width <= @line_width - offset
|
87
|
+
end
|
88
|
+
|
89
|
+
def col_widths(strs, cols:)
|
90
|
+
cols.times.map do |col|
|
91
|
+
(col...strs.size).step(cols).map do |i|
|
92
|
+
strs[i].length
|
93
|
+
end.max
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def screen_width
|
98
|
+
Reline.get_screen_size.last
|
99
|
+
rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
|
100
|
+
80
|
101
|
+
end
|
102
|
+
end
|
103
|
+
private_constant :Output
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
# :startdoc:
|
data/lib/irb/cmd/measure.rb
CHANGED
@@ -8,7 +8,7 @@ module IRB
|
|
8
8
|
super(*args)
|
9
9
|
end
|
10
10
|
|
11
|
-
def execute(type = nil, arg = nil)
|
11
|
+
def execute(type = nil, arg = nil, &block)
|
12
12
|
case type
|
13
13
|
when :off
|
14
14
|
IRB.conf[:MEASURE] = nil
|
@@ -22,9 +22,15 @@ module IRB
|
|
22
22
|
added = IRB.set_measure_callback(type, arg)
|
23
23
|
puts "#{added[0]} is added." if added
|
24
24
|
else
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
if block_given?
|
26
|
+
IRB.conf[:MEASURE] = true
|
27
|
+
added = IRB.set_measure_callback(&block)
|
28
|
+
puts "#{added[0]} is added." if added
|
29
|
+
else
|
30
|
+
IRB.conf[:MEASURE] = true
|
31
|
+
added = IRB.set_measure_callback(type, arg)
|
32
|
+
puts "#{added[0]} is added." if added
|
33
|
+
end
|
28
34
|
end
|
29
35
|
nil
|
30
36
|
end
|
data/lib/irb/cmd/nop.rb
CHANGED
@@ -14,10 +14,16 @@ module IRB
|
|
14
14
|
module ExtendCommand
|
15
15
|
class Nop
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
|
18
|
+
def self.execute(conf, *opts, **kwargs, &block)
|
19
|
+
command = new(conf)
|
20
|
+
command.execute(*opts, **kwargs, &block)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
def self.execute(conf, *opts, &block)
|
24
|
+
command = new(conf)
|
25
|
+
command.execute(*opts, &block)
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
def initialize(conf)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "nop"
|
4
|
+
require_relative "../color"
|
5
|
+
require_relative "../ruby-lex"
|
6
|
+
|
7
|
+
# :stopdoc:
|
8
|
+
module IRB
|
9
|
+
module ExtendCommand
|
10
|
+
class ShowSource < Nop
|
11
|
+
def execute(str = nil)
|
12
|
+
unless str.is_a?(String)
|
13
|
+
puts "Error: Expected a string but got #{str.inspect}"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
source = find_source(str)
|
17
|
+
if source && File.exist?(source.file)
|
18
|
+
show_source(source)
|
19
|
+
else
|
20
|
+
puts "Error: Couldn't locate a definition for #{str}"
|
21
|
+
end
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# @param [IRB::ExtendCommand::ShowSource::Source] source
|
28
|
+
def show_source(source)
|
29
|
+
puts
|
30
|
+
puts "#{bold("From")}: #{source.file}:#{source.first_line}"
|
31
|
+
puts
|
32
|
+
code = IRB::Color.colorize_code(File.read(source.file))
|
33
|
+
puts code.lines[(source.first_line - 1)...source.last_line].join
|
34
|
+
puts
|
35
|
+
end
|
36
|
+
|
37
|
+
def find_source(str)
|
38
|
+
case str
|
39
|
+
when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
|
40
|
+
eval(str, irb_context.workspace.binding) # trigger autoload
|
41
|
+
base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
|
42
|
+
file, line = base.const_source_location(str) if base.respond_to?(:const_source_location) # Ruby 2.7+
|
43
|
+
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
|
44
|
+
owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
|
45
|
+
method = Regexp.last_match[:method]
|
46
|
+
if owner.respond_to?(:instance_method) && owner.instance_methods.include?(method.to_sym)
|
47
|
+
file, line = owner.instance_method(method).source_location
|
48
|
+
end
|
49
|
+
when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
|
50
|
+
receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
|
51
|
+
method = Regexp.last_match[:method]
|
52
|
+
file, line = receiver.method(method).source_location if receiver.respond_to?(method)
|
53
|
+
end
|
54
|
+
if file && line
|
55
|
+
Source.new(file: file, first_line: line, last_line: find_end(file, line))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_end(file, first_line)
|
60
|
+
return first_line unless File.exist?(file)
|
61
|
+
lex = RubyLex.new
|
62
|
+
code = +""
|
63
|
+
File.read(file).lines[(first_line - 1)..-1].each_with_index do |line, i|
|
64
|
+
_ltype, _indent, continue, code_block_open = lex.check_state(code << line)
|
65
|
+
if !continue && !code_block_open
|
66
|
+
return first_line + i
|
67
|
+
end
|
68
|
+
end
|
69
|
+
first_line
|
70
|
+
end
|
71
|
+
|
72
|
+
def bold(str)
|
73
|
+
Color.colorize(str, [:BOLD])
|
74
|
+
end
|
75
|
+
|
76
|
+
Source = Struct.new(
|
77
|
+
:file, # @param [String] - file name
|
78
|
+
:first_line, # @param [String] - first line
|
79
|
+
:last_line, # @param [String] - last line
|
80
|
+
keyword_init: true,
|
81
|
+
)
|
82
|
+
private_constant :Source
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
# :startdoc:
|