irb 1.3.3 → 1.3.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd13d45b58713bde6589b963fc6d2a93c166d340aaba132c9b7981ffe88062cb
4
- data.tar.gz: 56d4e5c73fb369f36cc34bbda1462492a0db7b7393f9b3e15a4e1a54e2ad1ec7
3
+ metadata.gz: ddb63fc9d57700014a7da313e20504596ca42dfee0952547fa545d726f08d7d6
4
+ data.tar.gz: cc4ee2f880d56dc7f792ecc406f489f8555601d19499f45d8f8828cc260ed1b0
5
5
  SHA512:
6
- metadata.gz: cd6725cf6479552499418c3a93058ef9adb471f44fff49bd30d382e6c534dac1aa43086d002a93b06a856c2bffd5d5decdd2a79c1e9b3d31c344ecccf6cfc60f
7
- data.tar.gz: 064efe186e582ca440903e98f7b2b5cfab38867c7f3812ffe6f2e8bd1bc3c01b64ca4828c9d38ba26c0b9d6c7ceba76f4e1974484527a9ba6cbea249970cb067
6
+ metadata.gz: c5b128b8ce5457862489e313231af33167802619c3847da526dda30c83f7fc96d1a248d2916e17da4cbd45f8d30aee8c181237182b97b5741cf4bc4c13568bfb
7
+ data.tar.gz: 61147b2b4e76f34076043feaa84feeb2e893a140d3d7d1e5013a00f87f27f694802f8ae21788709a7ee03c5b41ee445735aec93bfedbeaa9fcf02d6bf06f705d
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/**/test_*.rb"]
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,60 +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/info.rb",
36
- "lib/irb/cmd/load.rb",
37
- "lib/irb/cmd/measure.rb",
38
- "lib/irb/cmd/nop.rb",
39
- "lib/irb/cmd/pushws.rb",
40
- "lib/irb/cmd/subirb.rb",
41
- "lib/irb/color.rb",
42
- "lib/irb/color_printer.rb",
43
- "lib/irb/completion.rb",
44
- "lib/irb/context.rb",
45
- "lib/irb/easter-egg.rb",
46
- "lib/irb/ext/change-ws.rb",
47
- "lib/irb/ext/history.rb",
48
- "lib/irb/ext/loader.rb",
49
- "lib/irb/ext/multi-irb.rb",
50
- "lib/irb/ext/save-history.rb",
51
- "lib/irb/ext/tracer.rb",
52
- "lib/irb/ext/use-loader.rb",
53
- "lib/irb/ext/workspaces.rb",
54
- "lib/irb/extend-command.rb",
55
- "lib/irb/frame.rb",
56
- "lib/irb/help.rb",
57
- "lib/irb/init.rb",
58
- "lib/irb/input-method.rb",
59
- "lib/irb/inspector.rb",
60
- "lib/irb/lc/error.rb",
61
- "lib/irb/lc/help-message",
62
- "lib/irb/lc/ja/encoding_aliases.rb",
63
- "lib/irb/lc/ja/error.rb",
64
- "lib/irb/lc/ja/help-message",
65
- "lib/irb/locale.rb",
66
- "lib/irb/magic-file.rb",
67
- "lib/irb/notifier.rb",
68
- "lib/irb/output-method.rb",
69
- "lib/irb/ruby-lex.rb",
70
- "lib/irb/ruby_logo.aa",
71
- "lib/irb/src_encoding.rb",
72
- "lib/irb/version.rb",
73
- "lib/irb/workspace.rb",
74
- "lib/irb/ws-for-case-2.rb",
75
- "lib/irb/xmp.rb",
76
31
  "man/irb.1",
77
- ]
32
+ ] + Dir.glob("lib/**/*")
78
33
  spec.bindir = "exe"
79
34
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
80
35
  spec.require_paths = ["lib"]
81
36
 
82
37
  spec.required_ruby_version = Gem::Requirement.new(">= 2.5")
83
38
 
84
- spec.add_dependency "reline", ">= 0.1.5"
85
- spec.add_development_dependency "bundler"
86
- spec.add_development_dependency "rake"
39
+ spec.add_dependency "reline", ">= 0.2.7"
87
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
- # --inspect Use `inspect' for output (default except for bc mode)
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 Simple prompt mode
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
- # -v, --version Print the version of irb
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
@@ -514,7 +524,7 @@ module IRB
514
524
  @context.io.prompt
515
525
  end
516
526
 
517
- @scanner.set_input(@context.io) do
527
+ @scanner.set_input(@context.io, context: @context) do
518
528
  signal_status(:IN_INPUT) do
519
529
  if l = @context.io.gets
520
530
  print l if @context.verbose?
@@ -580,9 +590,15 @@ module IRB
580
590
  end
581
591
  end
582
592
 
583
- def convert_invalid_byte_sequence(str)
584
- str = str.force_encoding(Encoding::ASCII_8BIT)
585
- conv = Encoding::Converter.new(Encoding::ASCII_8BIT, Encoding::UTF_8)
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)
586
602
  dst = String.new
587
603
  begin
588
604
  ret = conv.primitive_convert(str, dst)
@@ -630,7 +646,8 @@ module IRB
630
646
  message = exc.full_message(order: :top)
631
647
  order = :top
632
648
  end
633
- 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)
634
651
  message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
635
652
  case order
636
653
  when :top
data/lib/irb/cmd/info.rb CHANGED
@@ -13,6 +13,13 @@ module IRB
13
13
  str += "IRB version: #{IRB.version}\n"
14
14
  str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n"
15
15
  str += ".irbrc path: #{IRB.rc_file}\n" if File.exist?(IRB.rc_file)
16
+ str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n"
17
+ str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty?
18
+ str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty?
19
+ if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
20
+ codepage = `chcp`.sub(/.*: (\d+)\n/, '\1')
21
+ str += "Code page: #{codepage}\n"
22
+ end
16
23
  str
17
24
  end
18
25
  alias_method :to_s, :inspect
data/lib/irb/cmd/ls.rb ADDED
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "reline"
4
+ require_relative "nop"
5
+ require_relative "../color"
6
+
7
+ # :stopdoc:
8
+ module IRB
9
+ module ExtendCommand
10
+ class Ls < Nop
11
+ def execute(*arg, grep: nil)
12
+ o = Output.new(grep: grep)
13
+
14
+ obj = arg.empty? ? irb_context.workspace.main : arg.first
15
+ locals = arg.empty? ? irb_context.workspace.binding.local_variables : []
16
+ klass = (obj.class == Class || obj.class == Module ? obj : obj.class)
17
+
18
+ o.dump("constants", obj.constants) if obj.respond_to?(:constants)
19
+ dump_methods(o, klass, obj)
20
+ o.dump("instance variables", obj.instance_variables)
21
+ o.dump("class variables", klass.class_variables)
22
+ o.dump("locals", locals)
23
+ end
24
+
25
+ def dump_methods(o, klass, obj)
26
+ singleton_class = begin obj.singleton_class; rescue TypeError; nil end
27
+ maps = class_method_map((singleton_class || klass).ancestors)
28
+ maps.each do |mod, methods|
29
+ name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
30
+ o.dump(name, methods)
31
+ end
32
+ end
33
+
34
+ def class_method_map(classes)
35
+ dumped = Array.new
36
+ classes.reject { |mod| mod >= Object }.map do |mod|
37
+ methods = mod.public_instance_methods(false).select do |m|
38
+ dumped.push(m) unless dumped.include?(m)
39
+ end
40
+ [mod, methods]
41
+ end.reverse
42
+ end
43
+
44
+ class Output
45
+ MARGIN = " "
46
+
47
+ def initialize(grep: nil)
48
+ @grep = grep
49
+ @line_width = screen_width - MARGIN.length # right padding
50
+ end
51
+
52
+ def dump(name, strs)
53
+ strs = strs.grep(@grep) if @grep
54
+ strs = strs.sort
55
+ return if strs.empty?
56
+
57
+ # Attempt a single line
58
+ print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
59
+ if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
60
+ puts strs.join(MARGIN)
61
+ return
62
+ end
63
+ puts
64
+
65
+ # Dump with the largest # of columns that fits on a line
66
+ cols = strs.size
67
+ until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
68
+ cols -= 1
69
+ end
70
+ widths = col_widths(strs, cols: cols)
71
+ strs.each_slice(cols) do |ss|
72
+ puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def fits_on_line?(strs, cols:, offset: 0)
79
+ width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
80
+ width <= @line_width - offset
81
+ end
82
+
83
+ def col_widths(strs, cols:)
84
+ cols.times.map do |col|
85
+ (col...strs.size).step(cols).map do |i|
86
+ strs[i].length
87
+ end.max
88
+ end
89
+ end
90
+
91
+ def screen_width
92
+ Reline.get_screen_size.last
93
+ rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
94
+ 80
95
+ end
96
+ end
97
+ private_constant :Output
98
+ end
99
+ end
100
+ end
101
+ # :startdoc:
@@ -9,6 +9,9 @@ module IRB
9
9
  end
10
10
 
11
11
  def execute(type = nil, arg = nil, &block)
12
+ # Please check IRB.init_config in lib/irb/init.rb that sets
13
+ # IRB.conf[:MEASURE_PROC] to register default "measure" methods,
14
+ # "measure :time" (abbreviated as "measure") and "measure :stackprof".
12
15
  case type
13
16
  when :off
14
17
  IRB.conf[:MEASURE] = nil
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
- def self.execute(conf, *opts, &block)
19
- command = new(conf)
20
- command.execute(*opts, &block)
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,96 @@
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
+ lines = File.read(file).lines[(first_line - 1)..-1]
63
+ tokens = RubyLex.ripper_lex_without_warning(lines.join)
64
+
65
+ code = +""
66
+ prev_tokens = []
67
+
68
+ # chunk with line number
69
+ tokens.chunk { |tok| tok[0][0] }.each do |lnum, chunk|
70
+ code << lines[lnum]
71
+ prev_tokens.concat chunk
72
+
73
+ continue = lex.process_continue(prev_tokens)
74
+ code_block_open = lex.check_code_block(code, prev_tokens)
75
+ if !continue && !code_block_open
76
+ return first_line + lnum
77
+ end
78
+ end
79
+ first_line
80
+ end
81
+
82
+ def bold(str)
83
+ Color.colorize(str, [:BOLD])
84
+ end
85
+
86
+ Source = Struct.new(
87
+ :file, # @param [String] - file name
88
+ :first_line, # @param [String] - first line
89
+ :last_line, # @param [String] - last line
90
+ keyword_init: true,
91
+ )
92
+ private_constant :Source
93
+ end
94
+ end
95
+ end
96
+ # :startdoc:
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "nop"
4
+
5
+ # :stopdoc:
6
+ module IRB
7
+ module ExtendCommand
8
+ class Whereami < Nop
9
+ def execute(*)
10
+ code = irb_context.workspace.code_around_binding
11
+ if code
12
+ puts code
13
+ else
14
+ puts "The current context doesn't have code."
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ # :startdoc:
data/lib/irb/color.rb CHANGED
@@ -64,6 +64,7 @@ module IRB # :nodoc:
64
64
  on_alias_error: [[RED, REVERSE], ALL],
65
65
  on_class_name_error:[[RED, REVERSE], ALL],
66
66
  on_param_error: [[RED, REVERSE], ALL],
67
+ on___end__: [[GREEN], ALL],
67
68
  }
68
69
  rescue NameError
69
70
  # Give up highlighting Ripper-incompatible older Ruby
@@ -76,7 +77,7 @@ module IRB # :nodoc:
76
77
 
77
78
  class << self
78
79
  def colorable?
79
- $stdout.tty? && supported? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
80
+ $stdout.tty? && (/mswin|mingw/ =~ RUBY_PLATFORM || (ENV.key?('TERM') && ENV['TERM'] != 'dumb'))
80
81
  end
81
82
 
82
83
  def inspect_colorable?(obj, seen: {}.compare_by_identity)
@@ -100,26 +101,27 @@ module IRB # :nodoc:
100
101
  end
101
102
  end
102
103
 
103
- def clear
104
- return '' unless colorable?
104
+ def clear(colorable: colorable?)
105
+ return '' unless colorable
105
106
  "\e[#{CLEAR}m"
106
107
  end
107
108
 
108
- def colorize(text, seq)
109
- return text unless colorable?
109
+ def colorize(text, seq, colorable: colorable?)
110
+ return text unless colorable
110
111
  seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('')
111
- "#{seq}#{text}#{clear}"
112
+ "#{seq}#{text}#{clear(colorable: colorable)}"
112
113
  end
113
114
 
114
115
  # If `complete` is false (code is incomplete), this does not warn compile_error.
115
116
  # This option is needed to avoid warning a user when the compile_error is happening
116
117
  # because the input is not wrong but just incomplete.
117
- def colorize_code(code, complete: true, ignore_error: false)
118
- return code unless colorable?
118
+ def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?)
119
+ return code unless colorable
119
120
 
120
121
  symbol_state = SymbolState.new
121
122
  colored = +''
122
123
  length = 0
124
+ end_seen = false
123
125
 
124
126
  scan(code, allow_last_error: !complete) do |token, str, expr|
125
127
  # IRB::ColorPrinter skips colorizing fragments with any invalid token
@@ -132,16 +134,17 @@ module IRB # :nodoc:
132
134
  line = Reline::Unicode.escape_for_print(line)
133
135
  if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol)
134
136
  colored << seq.map { |s| "\e[#{s}m" }.join('')
135
- colored << line.sub(/\Z/, clear)
137
+ colored << line.sub(/\Z/, clear(colorable: colorable))
136
138
  else
137
139
  colored << line
138
140
  end
139
141
  end
140
142
  length += str.bytesize
143
+ end_seen = true if token == :on___end__
141
144
  end
142
145
 
143
146
  # give up colorizing incomplete Ripper tokens
144
- if length != code.bytesize
147
+ unless end_seen or length == code.bytesize
145
148
  return Reline::Unicode.escape_for_print(code)
146
149
  end
147
150
 
@@ -158,11 +161,6 @@ module IRB # :nodoc:
158
161
  seen.delete(obj)
159
162
  end
160
163
 
161
- def supported?
162
- return @supported if defined?(@supported)
163
- @supported = Ripper::Lexer::Elem.method_defined?(:state)
164
- end
165
-
166
164
  def scan(code, allow_last_error:)
167
165
  pos = [1, 0]
168
166
 
@@ -21,6 +21,15 @@ module IRB
21
21
  end
22
22
  end
23
23
 
24
+ def pp(obj)
25
+ if obj.is_a?(String)
26
+ # Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
27
+ text(obj.inspect)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
24
33
  def text(str, width = nil)
25
34
  unless str.is_a?(String)
26
35
  str = str.inspect
@@ -7,7 +7,7 @@
7
7
  # From Original Idea of shugo@ruby-lang.org
8
8
  #
9
9
 
10
- autoload :RDoc, "rdoc"
10
+ require_relative 'ruby-lex'
11
11
 
12
12
  module IRB
13
13
  module InputCompletor # :nodoc:
@@ -38,8 +38,69 @@ module IRB
38
38
 
39
39
  BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
40
40
 
41
- CompletionProc = proc { |input|
42
- retrieve_completion_data(input).compact.map{ |i| i.encode(Encoding.default_external) }
41
+ def self.retrieve_files_to_require_from_load_path
42
+ @@files_from_load_path ||= $LOAD_PATH.flat_map { |path|
43
+ begin
44
+ Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
45
+ rescue Errno::ENOENT
46
+ []
47
+ end
48
+ }.uniq.map { |path|
49
+ path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
50
+ }
51
+ end
52
+
53
+ def self.retrieve_files_to_require_relative_from_current_dir
54
+ @@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
55
+ path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
56
+ }
57
+ end
58
+
59
+ CompletionRequireProc = lambda { |target, preposing = nil, postposing = nil|
60
+ if target =~ /\A(['"])([^'"]+)\Z/
61
+ quote = $1
62
+ actual_target = $2
63
+ else
64
+ return nil # It's not String literal
65
+ end
66
+ tokens = RubyLex.ripper_lex_without_warning(preposing.gsub(/\s*\z/, ''))
67
+ tok = nil
68
+ tokens.reverse_each do |t|
69
+ unless [:on_lparen, :on_sp, :on_ignored_sp, :on_nl, :on_ignored_nl, :on_comment].include?(t.event)
70
+ tok = t
71
+ break
72
+ end
73
+ end
74
+ result = []
75
+ if tok && tok.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
76
+ case tok.tok
77
+ when 'require'
78
+ result = retrieve_files_to_require_from_load_path.select { |path|
79
+ path.start_with?(actual_target)
80
+ }.map { |path|
81
+ quote + path
82
+ }
83
+ when 'require_relative'
84
+ result = retrieve_files_to_require_relative_from_current_dir.select { |path|
85
+ path.start_with?(actual_target)
86
+ }.map { |path|
87
+ quote + path
88
+ }
89
+ end
90
+ end
91
+ result
92
+ }
93
+
94
+ CompletionProc = lambda { |target, preposing = nil, postposing = nil|
95
+ if preposing && postposing
96
+ result = CompletionRequireProc.(target, preposing, postposing)
97
+ unless result
98
+ result = retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
99
+ end
100
+ result
101
+ else
102
+ retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
103
+ end
43
104
  }
44
105
 
45
106
  def self.retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
@@ -266,13 +327,22 @@ module IRB
266
327
  end
267
328
 
268
329
  PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
330
+ begin
331
+ require 'rdoc'
332
+ rescue LoadError
333
+ return
334
+ end
335
+
269
336
  RDocRIDriver ||= RDoc::RI::Driver.new
337
+
270
338
  if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
271
339
  IRB.__send__(:easter_egg)
272
340
  return
273
341
  end
342
+
274
343
  namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
275
344
  return unless namespace
345
+
276
346
  if namespace.is_a?(Array)
277
347
  out = RDoc::Markup::Document.new
278
348
  namespace.each do |m|
@@ -38,9 +38,9 @@ module IRB # :nodoc:
38
38
  else
39
39
  separator =
40
40
  if File::ALT_SEPARATOR
41
- File::SEPARATOR
42
- else
43
41
  "[#{Regexp.quote(File::SEPARATOR + File::ALT_SEPARATOR)}]"
42
+ else
43
+ File::SEPARATOR
44
44
  end
45
45
  ABSOLUTE_PATH_PATTERN = # :nodoc:
46
46
  case Dir.pwd
@@ -81,6 +81,8 @@ module IRB
81
81
  end
82
82
  }
83
83
  end
84
+ @loaded_history_lines = history.size
85
+ @loaded_history_mtime = File.mtime(history_file)
84
86
  end
85
87
  end
86
88
 
@@ -105,12 +107,20 @@ module IRB
105
107
  raise
106
108
  end
107
109
 
108
- open(history_file, "w:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
110
+ if File.exist?(history_file) && @loaded_history_mtime &&
111
+ File.mtime(history_file) != @loaded_history_mtime
112
+ history = history[@loaded_history_lines..-1]
113
+ append_history = true
114
+ end
115
+
116
+ open(history_file, "#{append_history ? 'a' : 'w'}:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
109
117
  hist = history.map{ |l| l.split("\n").join("\\\n") }
110
- begin
111
- hist = hist.last(num) if hist.size > num and num > 0
112
- rescue RangeError # bignum too big to convert into `long'
113
- # Do nothing because the bignum should be treated as inifinity
118
+ unless append_history
119
+ begin
120
+ hist = hist.last(num) if hist.size > num and num > 0
121
+ rescue RangeError # bignum too big to convert into `long'
122
+ # Do nothing because the bignum should be treated as inifinity
123
+ end
114
124
  end
115
125
  f.puts(hist)
116
126
  end
@@ -126,7 +126,23 @@ module IRB # :nodoc:
126
126
  ],
127
127
 
128
128
  [
129
- :measure, :Measure, "irb/cmd/measure"
129
+ :irb_ls, :Ls, "irb/cmd/ls",
130
+ [:ls, NO_OVERRIDE],
131
+ ],
132
+
133
+ [
134
+ :irb_measure, :Measure, "irb/cmd/measure",
135
+ [:measure, NO_OVERRIDE],
136
+ ],
137
+
138
+ [
139
+ :irb_show_source, :ShowSource, "irb/cmd/show_source",
140
+ [:show_source, NO_OVERRIDE],
141
+ ],
142
+
143
+ [
144
+ :irb_whereami, :Whereami, "irb/cmd/whereami",
145
+ [:whereami, NO_OVERRIDE],
130
146
  ],
131
147
 
132
148
  ]
@@ -168,12 +184,13 @@ module IRB # :nodoc:
168
184
  end
169
185
 
170
186
  if load_file
187
+ kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
171
188
  line = __LINE__; eval %[
172
- def #{cmd_name}(*opts, &b)
189
+ def #{cmd_name}(*opts#{kwargs}, &b)
173
190
  require "#{load_file}"
174
191
  arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
175
192
  args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
176
- args << "*opts" if arity < 0
193
+ args << "*opts#{kwargs}" if arity < 0
177
194
  args << "&block"
178
195
  args = args.join(", ")
179
196
  line = __LINE__; eval %[
@@ -184,7 +201,7 @@ module IRB # :nodoc:
184
201
  end
185
202
  end
186
203
  ], nil, __FILE__, line
187
- __send__ :#{cmd_name}_, *opts, &b
204
+ __send__ :#{cmd_name}_, *opts#{kwargs}, &b
188
205
  end
189
206
  ], nil, __FILE__, line
190
207
  else
data/lib/irb/init.rb CHANGED
@@ -44,7 +44,7 @@ module IRB # :nodoc:
44
44
  @CONF[:IRB_RC] = nil
45
45
 
46
46
  @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
47
- @CONF[:USE_COLORIZE] = true
47
+ @CONF[:USE_COLORIZE] = !ENV['NO_COLOR']
48
48
  @CONF[:INSPECT_MODE] = true
49
49
  @CONF[:USE_TRACER] = false
50
50
  @CONF[:USE_LOADER] = false
@@ -120,7 +120,11 @@ module IRB # :nodoc:
120
120
  puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE]
121
121
  result
122
122
  }
123
+ # arg can be either a symbol for the mode (:cpu, :wall, ..) or a hash for
124
+ # a more complete configuration.
125
+ # See https://github.com/tmm1/stackprof#all-options.
123
126
  @CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, arg, &block|
127
+ return block.() unless IRB.conf[:MEASURE]
124
128
  success = false
125
129
  begin
126
130
  require 'stackprof'
@@ -130,10 +134,18 @@ module IRB # :nodoc:
130
134
  end
131
135
  if success
132
136
  result = nil
133
- stackprof_result = StackProf.run(mode: arg ? arg : :cpu) do
137
+ arg = { mode: arg || :cpu } unless arg.is_a?(Hash)
138
+ stackprof_result = StackProf.run(**arg) do
134
139
  result = block.()
135
140
  end
136
- StackProf::Report.new(stackprof_result).print_text if IRB.conf[:MEASURE]
141
+ case stackprof_result
142
+ when File
143
+ puts "StackProf report saved to #{stackprof_result.path}"
144
+ when Hash
145
+ StackProf::Report.new(stackprof_result).print_text
146
+ else
147
+ puts "Stackprof ran with #{arg.inspect}"
148
+ end
137
149
  result
138
150
  else
139
151
  block.()
@@ -301,11 +313,11 @@ module IRB # :nodoc:
301
313
  break
302
314
  end
303
315
  end
316
+
304
317
  load_path.collect! do |path|
305
318
  /\A\.\// =~ path ? path : File.expand_path(path)
306
319
  end
307
320
  $LOAD_PATH.unshift(*load_path)
308
-
309
321
  end
310
322
 
311
323
  # running config
@@ -280,6 +280,7 @@ module IRB
280
280
  Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
281
281
  end
282
282
  Reline.completion_append_character = nil
283
+ Reline.completer_quote_characters = ''
283
284
  Reline.completion_proc = IRB::InputCompletor::CompletionProc
284
285
  Reline.output_modifier_proc =
285
286
  if IRB.conf[:USE_COLORIZE]
@@ -10,7 +10,7 @@
10
10
  #
11
11
  #
12
12
  Usage: irb.rb [options] [programfile] [arguments]
13
- -f Suppress read of ~/.irbrc
13
+ -f Suppress read of ~/.irbrc
14
14
  -d Set $DEBUG to true (same as `ruby -d')
15
15
  -r load-module Same as `ruby -r'
16
16
  -I path Specify $LOAD_PATH directory
@@ -18,7 +18,7 @@ Usage: irb.rb [options] [programfile] [arguments]
18
18
  -E enc Same as `ruby -E`
19
19
  -w Same as `ruby -w`
20
20
  -W[level=2] Same as `ruby -W`
21
- --context-mode n Set n[0-3] to method to create Binding Object,
21
+ --context-mode n Set n[0-4] to method to create Binding Object,
22
22
  when new workspace was created
23
23
  --echo Show result(default)
24
24
  --noecho Don't show result
@@ -31,8 +31,8 @@ Usage: irb.rb [options] [programfile] [arguments]
31
31
  --colorize Use colorization
32
32
  --nocolorize Don't use colorization
33
33
  --prompt prompt-mode/--prompt-mode prompt-mode
34
- Switch prompt mode. Pre-defined prompt modes are
35
- `default', `simple', `xmp' and `inf-ruby'
34
+ Switch prompt mode. Pre-defined prompt modes are
35
+ `default', `simple', `xmp' and `inf-ruby'
36
36
  --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
37
37
  Suppresses --multiline and --singleline.
38
38
  --sample-book-mode/--simple-prompt
@@ -41,8 +41,8 @@ Usage: irb.rb [options] [programfile] [arguments]
41
41
  --single-irb Share self with sub-irb.
42
42
  --tracer Display trace for each execution of commands.
43
43
  --back-trace-limit n
44
- Display backtrace top n and tail n. The default
45
- value is 16.
44
+ Display backtrace top n and tail n. The default
45
+ value is 16.
46
46
  --verbose Show details
47
47
  --noverbose Don't show details
48
48
  -v, --version Print the version of irb
data/lib/irb/ruby-lex.rb CHANGED
@@ -30,29 +30,48 @@ class RubyLex
30
30
  @prompt = nil
31
31
  end
32
32
 
33
- def self.compile_with_errors_suppressed(code)
34
- line_no = 1
33
+ def self.compile_with_errors_suppressed(code, line_no: 1)
35
34
  begin
36
35
  result = yield code, line_no
37
36
  rescue ArgumentError
37
+ # Ruby can issue an error for the code if there is an
38
+ # incomplete magic comment for encoding in it. Force an
39
+ # expression with a new line before the code in this
40
+ # case to prevent magic comment handling. To make sure
41
+ # line numbers in the lexed code remain the same,
42
+ # decrease the line number by one.
38
43
  code = ";\n#{code}"
39
- line_no = 0
44
+ line_no -= 1
40
45
  result = yield code, line_no
41
46
  end
42
47
  result
43
48
  end
44
49
 
45
50
  # io functions
46
- def set_input(io, p = nil, &block)
51
+ def set_input(io, p = nil, context: nil, &block)
47
52
  @io = io
48
53
  if @io.respond_to?(:check_termination)
49
54
  @io.check_termination do |code|
50
- code.gsub!(/\s*\z/, '').concat("\n")
51
- ltype, indent, continue, code_block_open = check_state(code)
52
- if ltype or indent > 0 or continue or code_block_open
53
- false
55
+ if Reline::IOGate.in_pasting?
56
+ lex = RubyLex.new
57
+ rest = lex.check_termination_in_prev_line(code, context: context)
58
+ if rest
59
+ Reline.delete_text
60
+ rest.bytes.reverse_each do |c|
61
+ Reline.ungetc(c)
62
+ end
63
+ true
64
+ else
65
+ false
66
+ end
54
67
  else
55
- true
68
+ code.gsub!(/\s*\z/, '').concat("\n")
69
+ ltype, indent, continue, code_block_open = check_state(code, context: context)
70
+ if ltype or indent > 0 or continue or code_block_open
71
+ false
72
+ else
73
+ true
74
+ end
56
75
  end
57
76
  end
58
77
  end
@@ -60,7 +79,7 @@ class RubyLex
60
79
  @io.dynamic_prompt do |lines|
61
80
  lines << '' if lines.empty?
62
81
  result = []
63
- tokens = ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
82
+ tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, context: context)
64
83
  code = String.new
65
84
  partial_tokens = []
66
85
  unprocessed_tokens = []
@@ -72,7 +91,7 @@ class RubyLex
72
91
  t_str = t[2]
73
92
  t_str.each_line("\n") do |s|
74
93
  code << s << "\n"
75
- ltype, indent, continue, code_block_open = check_state(code, partial_tokens)
94
+ ltype, indent, continue, code_block_open = check_state(code, partial_tokens, context: context)
76
95
  result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
77
96
  line_num_offset += 1
78
97
  end
@@ -82,7 +101,7 @@ class RubyLex
82
101
  end
83
102
  end
84
103
  unless unprocessed_tokens.empty?
85
- ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens)
104
+ ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens, context: context)
86
105
  result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset)
87
106
  end
88
107
  result
@@ -115,15 +134,25 @@ class RubyLex
115
134
  :on_param_error
116
135
  ]
117
136
 
118
- def ripper_lex_without_warning(code)
137
+ def self.ripper_lex_without_warning(code, context: nil)
119
138
  verbose, $VERBOSE = $VERBOSE, nil
139
+ if context
140
+ lvars = context&.workspace&.binding&.local_variables
141
+ if lvars && !lvars.empty?
142
+ code = "#{lvars.join('=')}=nil\n#{code}"
143
+ line_no = 0
144
+ else
145
+ line_no = 1
146
+ end
147
+ end
120
148
  tokens = nil
121
- self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
149
+ compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
122
150
  lexer = Ripper::Lexer.new(inner_code, '-', line_no)
123
151
  if lexer.respond_to?(:scan) # Ruby 2.7+
124
152
  tokens = []
125
153
  pos_to_index = {}
126
154
  lexer.scan.each do |t|
155
+ next if t.pos.first == 0
127
156
  if pos_to_index.has_key?(t[0])
128
157
  index = pos_to_index[t[0]]
129
158
  found_tk = tokens[index]
@@ -168,7 +197,7 @@ class RubyLex
168
197
  if @io.respond_to?(:auto_indent) and context.auto_indent_mode
169
198
  @io.auto_indent do |lines, line_index, byte_pointer, is_newline|
170
199
  if is_newline
171
- @tokens = ripper_lex_without_warning(lines[0..line_index].join("\n"))
200
+ @tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: context)
172
201
  prev_spaces = find_prev_spaces(line_index)
173
202
  depth_difference = check_newline_depth_difference
174
203
  depth_difference = 0 if depth_difference < 0
@@ -177,7 +206,7 @@ class RubyLex
177
206
  code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
178
207
  last_line = lines[line_index]&.byteslice(0, byte_pointer)
179
208
  code += last_line if last_line
180
- @tokens = ripper_lex_without_warning(code)
209
+ @tokens = self.class.ripper_lex_without_warning(code, context: context)
181
210
  corresponding_token_depth = check_corresponding_token_depth
182
211
  if corresponding_token_depth
183
212
  corresponding_token_depth
@@ -189,8 +218,8 @@ class RubyLex
189
218
  end
190
219
  end
191
220
 
192
- def check_state(code, tokens = nil)
193
- tokens = ripper_lex_without_warning(code) unless tokens
221
+ def check_state(code, tokens = nil, context: nil)
222
+ tokens = self.class.ripper_lex_without_warning(code, context: context) unless tokens
194
223
  ltype = process_literal_type(tokens)
195
224
  indent = process_nesting_level(tokens)
196
225
  continue = process_continue(tokens)
@@ -256,7 +285,7 @@ class RubyLex
256
285
  end
257
286
  code = @line + (line.nil? ? '' : line)
258
287
  code.gsub!(/\s*\z/, '').concat("\n")
259
- @tokens = ripper_lex_without_warning(code)
288
+ @tokens = self.class.ripper_lex_without_warning(code)
260
289
  @continue = process_continue
261
290
  @code_block_open = check_code_block(code)
262
291
  @indent = process_nesting_level
@@ -277,8 +306,9 @@ class RubyLex
277
306
  return true
278
307
  elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
279
308
  return false
280
- elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
309
+ elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2][2] !~ /\A\.\.\.?\z/
281
310
  # end of literal except for regexp
311
+ # endless range at end of line is not a continue
282
312
  return true
283
313
  end
284
314
  false
@@ -324,7 +354,7 @@ class RubyLex
324
354
  # "syntax error, unexpected end-of-input, expecting keyword_end"
325
355
  #
326
356
  # example:
327
- # if ture
357
+ # if true
328
358
  # hoge
329
359
  # if false
330
360
  # fuga
@@ -685,7 +715,7 @@ class RubyLex
685
715
  start_token << t
686
716
  end_type << :on_regexp_end
687
717
  when :on_symbeg
688
- acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw}
718
+ acceptable_single_tokens = %i{on_ident on_const on_op on_cvar on_ivar on_gvar on_kw on_int}
689
719
  if (i + 1) < tokens.size and acceptable_single_tokens.all?{ |st| tokens[i + 1][1] != st }
690
720
  start_token << t
691
721
  end_type << :on_tstring_end
@@ -738,5 +768,50 @@ class RubyLex
738
768
  nil
739
769
  end
740
770
  end
771
+
772
+ def check_termination_in_prev_line(code, context: nil)
773
+ tokens = self.class.ripper_lex_without_warning(code, context: context)
774
+ past_first_newline = false
775
+ index = tokens.rindex do |t|
776
+ # traverse first token before last line
777
+ if past_first_newline
778
+ if t.tok.include?("\n")
779
+ true
780
+ end
781
+ elsif t.tok.include?("\n")
782
+ past_first_newline = true
783
+ false
784
+ else
785
+ false
786
+ end
787
+ end
788
+ if index
789
+ first_token = nil
790
+ last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
791
+ last_line_tokens.each do |t|
792
+ unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
793
+ first_token = t
794
+ break
795
+ end
796
+ end
797
+ if first_token.nil?
798
+ return false
799
+ elsif first_token && first_token.state == Ripper::EXPR_DOT
800
+ return false
801
+ else
802
+ tokens_without_last_line = tokens[0..index]
803
+ ltype = process_literal_type(tokens_without_last_line)
804
+ indent = process_nesting_level(tokens_without_last_line)
805
+ continue = process_continue(tokens_without_last_line)
806
+ code_block_open = check_code_block(tokens_without_last_line.map(&:tok).join(''), tokens_without_last_line)
807
+ if ltype or indent > 0 or continue or code_block_open
808
+ return false
809
+ else
810
+ return last_line_tokens.map(&:tok).join('')
811
+ end
812
+ end
813
+ end
814
+ false
815
+ end
741
816
  end
742
817
  # :startdoc:
data/lib/irb/version.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module IRB # :nodoc:
14
- VERSION = "1.3.3"
14
+ VERSION = "1.3.7"
15
15
  @RELEASE_VERSION = VERSION
16
- @LAST_UPDATE_DATE = "2021-02-07"
16
+ @LAST_UPDATE_DATE = "2021-08-12"
17
17
  end
data/lib/irb/workspace.rb CHANGED
@@ -175,7 +175,7 @@ EOF
175
175
  body = (start_pos..end_pos).map do |current_pos|
176
176
  sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos])
177
177
  end.join("")
178
- "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n"
178
+ "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear if use_colorize}\n"
179
179
  end
180
180
 
181
181
  def IRB.delete_caller
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.3
4
+ version: 1.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keiju ISHITSUKA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-06 00:00:00.000000000 Z
11
+ date: 2021-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: reline
@@ -16,42 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.5
19
+ version: 0.2.7
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.5
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
26
+ version: 0.2.7
55
27
  description: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).
56
28
  email:
57
29
  - keiju@ruby-lang.org
@@ -77,10 +49,13 @@ files:
77
49
  - lib/irb/cmd/help.rb
78
50
  - lib/irb/cmd/info.rb
79
51
  - lib/irb/cmd/load.rb
52
+ - lib/irb/cmd/ls.rb
80
53
  - lib/irb/cmd/measure.rb
81
54
  - lib/irb/cmd/nop.rb
82
55
  - lib/irb/cmd/pushws.rb
56
+ - lib/irb/cmd/show_source.rb
83
57
  - lib/irb/cmd/subirb.rb
58
+ - lib/irb/cmd/whereami.rb
84
59
  - lib/irb/color.rb
85
60
  - lib/irb/color_printer.rb
86
61
  - lib/irb/completion.rb
@@ -137,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
112
  - !ruby/object:Gem::Version
138
113
  version: '0'
139
114
  requirements: []
140
- rubygems_version: 3.2.3
115
+ rubygems_version: 3.2.22
141
116
  signing_key:
142
117
  specification_version: 4
143
118
  summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).