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 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: