irb 1.3.0 → 1.3.5

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: 31185f1544129f656db53521cf32cd171bb8dbfb49a3826bcf9eeddf46928c64
4
- data.tar.gz: 1a48f904f93867f1242cc6e548e0acb5acf8767ec7e89eb543cd08025e7857f2
3
+ metadata.gz: d7a7034e210074f2c31db1369ffe0d5203cd7d2d35a1b9df36cbabfe6d52109e
4
+ data.tar.gz: c22c2ea2a1fb878c0b96d194c8b5af832c07d4b53173ebec07cfcadb04ac4d33
5
5
  SHA512:
6
- metadata.gz: 921e8d5c6306dbcfa7daafa8271dcadfa9f2707e315a81704e921b1d7111d6c1a1a958e8b3b615c1725c2e2a0a7dffa245a7fbd068383977cc8259f1282cf51b
7
- data.tar.gz: 8eaa9e728fd9f14a42fc08a729c9e8dc3ac8289257f26f6440fa38c29c7491caefa2611eb10d2a778a0664e8e7c29c6c8be9b3e1a91133c206e0364a61cd62ee
6
+ metadata.gz: 9017a414d09dc360a6846aa23917133f57145bdc529642931912c92c1ce675c5312705a105a5098e8cec351b6997da379a745097238d98f1e18f976ed9da4594
7
+ data.tar.gz: 67f3e78b20d4ea3881d6bea7deb8da4a2c9066029ffc19de9ed78b906cfae50f43e93da8b5ab306ac44b43f2555d0b3a65e3678ef10ba00f0e87221bb7f7a22d
data/Rakefile CHANGED
@@ -7,4 +7,11 @@ Rake::TestTask.new(:test) do |t|
7
7
  t.test_files = FileList["test/**/test_*.rb"]
8
8
  end
9
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'
15
+ end
16
+
10
17
  task :default => :test
data/irb.gemspec CHANGED
@@ -28,51 +28,8 @@ 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/completion.rb",
42
- "lib/irb/context.rb",
43
- "lib/irb/easter-egg.rb",
44
- "lib/irb/ext/change-ws.rb",
45
- "lib/irb/ext/history.rb",
46
- "lib/irb/ext/loader.rb",
47
- "lib/irb/ext/multi-irb.rb",
48
- "lib/irb/ext/save-history.rb",
49
- "lib/irb/ext/tracer.rb",
50
- "lib/irb/ext/use-loader.rb",
51
- "lib/irb/ext/workspaces.rb",
52
- "lib/irb/extend-command.rb",
53
- "lib/irb/frame.rb",
54
- "lib/irb/help.rb",
55
- "lib/irb/init.rb",
56
- "lib/irb/input-method.rb",
57
- "lib/irb/inspector.rb",
58
- "lib/irb/lc/error.rb",
59
- "lib/irb/lc/help-message",
60
- "lib/irb/lc/ja/encoding_aliases.rb",
61
- "lib/irb/lc/ja/error.rb",
62
- "lib/irb/lc/ja/help-message",
63
- "lib/irb/locale.rb",
64
- "lib/irb/magic-file.rb",
65
- "lib/irb/notifier.rb",
66
- "lib/irb/output-method.rb",
67
- "lib/irb/ruby-lex.rb",
68
- "lib/irb/ruby_logo.aa",
69
- "lib/irb/src_encoding.rb",
70
- "lib/irb/version.rb",
71
- "lib/irb/workspace.rb",
72
- "lib/irb/ws-for-case-2.rb",
73
- "lib/irb/xmp.rb",
74
31
  "man/irb.1",
75
- ]
32
+ ] + Dir.glob("lib/**/*")
76
33
  spec.bindir = "exe"
77
34
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
78
35
  spec.require_paths = ["lib"]
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
@@ -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,10 +584,35 @@ 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
 
593
+ def convert_invalid_byte_sequence(str)
594
+ str = str.force_encoding(Encoding::ASCII_8BIT)
595
+ conv = Encoding::Converter.new(Encoding::ASCII_8BIT, Encoding::UTF_8)
596
+ dst = String.new
597
+ begin
598
+ ret = conv.primitive_convert(str, dst)
599
+ case ret
600
+ when :invalid_byte_sequence
601
+ conv.insert_output(conf.primitive_errinfo[3].dump[1..-2])
602
+ redo
603
+ when :undefined_conversion
604
+ c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1])
605
+ conv.insert_output(c.dump[1..-2])
606
+ redo
607
+ when :incomplete_input
608
+ conv.insert_output(conv.primitive_errinfo[3].dump[1..-2])
609
+ when :finished
610
+ end
611
+ break
612
+ end while nil
613
+ dst
614
+ end
615
+
581
616
  def handle_exception(exc)
582
617
  if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
583
618
  !(SyntaxError === exc) && !(EncodingError === exc)
@@ -587,49 +622,44 @@ module IRB
587
622
  irb_bug = false
588
623
  end
589
624
 
590
- if STDOUT.tty?
591
- attr = ATTR_TTY
592
- print "#{attr[1]}Traceback#{attr[]} (most recent call last):\n"
593
- else
594
- attr = ATTR_PLAIN
595
- end
596
- messages = []
597
- lasts = []
598
- levels = 0
599
625
  if exc.backtrace
600
- count = 0
601
- exc.backtrace.each do |m|
602
- m = @context.workspace.filter_backtrace(m) or next unless irb_bug
603
- count += 1
604
- if attr == ATTR_TTY
605
- m = sprintf("%9d: from %s", count, m)
626
+ order = nil
627
+ if '2.5.0' == RUBY_VERSION
628
+ # Exception#full_message doesn't have keyword arguments.
629
+ message = exc.full_message # the same of (highlight: true, order: bottom)
630
+ order = :bottom
631
+ elsif '2.5.1' <= RUBY_VERSION && RUBY_VERSION < '3.0.0'
632
+ if STDOUT.tty?
633
+ message = exc.full_message(order: :bottom)
634
+ order = :bottom
606
635
  else
607
- m = "\tfrom #{m}"
608
- end
609
- if messages.size < @context.back_trace_limit
610
- messages.push(m)
611
- elsif lasts.size < @context.back_trace_limit
612
- lasts.push(m).shift
613
- levels += 1
636
+ message = exc.full_message(order: :top)
637
+ order = :top
614
638
  end
639
+ else # '3.0.0' <= RUBY_VERSION
640
+ message = exc.full_message(order: :top)
641
+ order = :top
615
642
  end
616
- end
617
- if attr == ATTR_TTY
618
- unless lasts.empty?
619
- puts lasts.reverse
620
- printf "... %d levels...\n", levels if levels > 0
621
- end
622
- puts messages.reverse
623
- end
624
- m = exc.to_s.split(/\n/)
625
- print "#{attr[1]}#{exc.class} (#{attr[4]}#{m.shift}#{attr[0, 1]})#{attr[]}\n"
626
- puts m.map {|s| "#{attr[1]}#{s}#{attr[]}\n"}
627
- if attr == ATTR_PLAIN
628
- puts messages
629
- unless lasts.empty?
630
- puts lasts
631
- printf "... %d levels...\n", levels if levels > 0
632
- end
643
+ message = convert_invalid_byte_sequence(message)
644
+ message = message.gsub(/((?:^\t.+$\n)+)/) { |m|
645
+ case order
646
+ when :top
647
+ lines = m.split("\n")
648
+ when :bottom
649
+ lines = m.split("\n").reverse
650
+ end
651
+ unless irb_bug
652
+ lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact
653
+ if lines.size > @context.back_trace_limit
654
+ omit = lines.size - @context.back_trace_limit
655
+ lines = lines[0..(@context.back_trace_limit - 1)]
656
+ lines << "\t... %d levels..." % omit
657
+ end
658
+ end
659
+ lines = lines.reverse if order == :bottom
660
+ lines.map{ |l| l + "\n" }.join
661
+ }
662
+ puts message
633
663
  end
634
664
  print "Maybe IRB bug!\n" if irb_bug
635
665
  end
@@ -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,83 @@
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
+ o.dump("#{klass}.methods", obj.singleton_methods(false))
20
+ o.dump("#{klass}#methods", klass.public_instance_methods(false))
21
+ o.dump("instance variables", obj.instance_variables)
22
+ o.dump("class variables", klass.class_variables)
23
+ o.dump("locals", locals)
24
+ end
25
+
26
+ class Output
27
+ MARGIN = " "
28
+
29
+ def initialize(grep: nil)
30
+ @grep = grep
31
+ @line_width = screen_width - MARGIN.length # right padding
32
+ end
33
+
34
+ def dump(name, strs)
35
+ strs = strs.grep(@grep) if @grep
36
+ strs = strs.sort
37
+ return if strs.empty?
38
+
39
+ # Attempt a single line
40
+ print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
41
+ if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
42
+ puts strs.join(MARGIN)
43
+ return
44
+ end
45
+ puts
46
+
47
+ # Dump with the largest # of columns that fits on a line
48
+ cols = strs.size
49
+ until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1
50
+ cols -= 1
51
+ end
52
+ widths = col_widths(strs, cols: cols)
53
+ strs.each_slice(cols) do |ss|
54
+ puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def fits_on_line?(strs, cols:, offset: 0)
61
+ width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1)
62
+ width <= @line_width - offset
63
+ end
64
+
65
+ def col_widths(strs, cols:)
66
+ cols.times.map do |col|
67
+ (col...strs.size).step(cols).map do |i|
68
+ strs[i].length
69
+ end.max
70
+ end
71
+ end
72
+
73
+ def screen_width
74
+ Reline.get_screen_size.last
75
+ rescue Errno::EINVAL # in `winsize': Invalid argument - <STDIN>
76
+ 80
77
+ end
78
+ end
79
+ private_constant :Output
80
+ end
81
+ end
82
+ end
83
+ # :startdoc:
@@ -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
- IRB.conf[:MEASURE] = true
26
- added = IRB.set_measure_callback(type, arg)
27
- puts "#{added[0]} is added." if added
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
- def self.execute(conf, *opts)
19
- command = new(conf)
20
- command.execute(*opts)
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: