irb 1.3.1 → 1.3.6

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: e147abaf69084b92f2f7accaf7d83014b6c0f7b3b6cbe0cc9b9878c52baee8af
4
- data.tar.gz: 9a770f98f44f4bf498c91a3d8546d13a1db418daa034639646c0df0c3720d23e
3
+ metadata.gz: 7071322837c419efbce74bd5aa91c9b83a9a3fd31e893e72376b763b2bbf4409
4
+ data.tar.gz: fa4e508771f91e4da313913592a7caa713cb82069f57d4dab059426baa764fc4
5
5
  SHA512:
6
- metadata.gz: f760ae68d08c7ae7f9f4ec07149935819f50df015a5f4a9453eca4a01574677ed5a29ae1c4eb8462b9cc92f5ad6b465b4e8b1c3f37748bd81ecde7159cf3a1c0
7
- data.tar.gz: 3da91491f2e3928c8b619f120b6c6adcd020ed16760a4c176aee38bec5ca3964eb7cd0acc053a6a18dacec571b9a0b1e93d2a4c94a628a642b3b39bfd98b5284
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/**/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,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.1.5"
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
- # --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,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 = str.force_encoding(Encoding::ASCII_8BIT)
583
- 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)
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
@@ -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:
@@ -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: