irb 1.8.3 → 1.13.1

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -1
  3. data/Gemfile +9 -1
  4. data/README.md +149 -25
  5. data/Rakefile +13 -3
  6. data/irb.gemspec +2 -2
  7. data/lib/irb/cmd/nop.rb +3 -52
  8. data/lib/irb/color.rb +2 -2
  9. data/lib/irb/command/backtrace.rb +17 -0
  10. data/lib/irb/command/base.rb +62 -0
  11. data/lib/irb/command/break.rb +17 -0
  12. data/lib/irb/command/catch.rb +17 -0
  13. data/lib/irb/command/chws.rb +40 -0
  14. data/lib/irb/command/context.rb +16 -0
  15. data/lib/irb/{cmd → command}/continue.rb +3 -3
  16. data/lib/irb/{cmd → command}/debug.rb +11 -20
  17. data/lib/irb/{cmd → command}/delete.rb +3 -3
  18. data/lib/irb/command/disable_irb.rb +19 -0
  19. data/lib/irb/command/edit.rb +63 -0
  20. data/lib/irb/command/exit.rb +18 -0
  21. data/lib/irb/{cmd → command}/finish.rb +3 -3
  22. data/lib/irb/command/force_exit.rb +18 -0
  23. data/lib/irb/command/help.rb +83 -0
  24. data/lib/irb/command/history.rb +45 -0
  25. data/lib/irb/command/info.rb +17 -0
  26. data/lib/irb/command/internal_helpers.rb +27 -0
  27. data/lib/irb/{cmd → command}/irb_info.rb +7 -7
  28. data/lib/irb/{cmd → command}/load.rb +23 -8
  29. data/lib/irb/{cmd → command}/ls.rb +30 -14
  30. data/lib/irb/{cmd → command}/measure.rb +18 -17
  31. data/lib/irb/{cmd → command}/next.rb +3 -3
  32. data/lib/irb/command/pushws.rb +65 -0
  33. data/lib/irb/command/show_doc.rb +51 -0
  34. data/lib/irb/command/show_source.rb +74 -0
  35. data/lib/irb/{cmd → command}/step.rb +3 -3
  36. data/lib/irb/{cmd → command}/subirb.rb +31 -17
  37. data/lib/irb/{cmd → command}/whereami.rb +3 -5
  38. data/lib/irb/command.rb +23 -0
  39. data/lib/irb/completion.rb +74 -31
  40. data/lib/irb/context.rb +144 -57
  41. data/lib/irb/debug.rb +18 -0
  42. data/lib/irb/default_commands.rb +260 -0
  43. data/lib/irb/easter-egg.rb +16 -6
  44. data/lib/irb/ext/change-ws.rb +6 -8
  45. data/lib/irb/ext/eval_history.rb +3 -3
  46. data/lib/irb/ext/loader.rb +4 -4
  47. data/lib/irb/ext/multi-irb.rb +5 -5
  48. data/lib/irb/ext/tracer.rb +12 -51
  49. data/lib/irb/ext/use-loader.rb +6 -8
  50. data/lib/irb/ext/workspaces.rb +10 -34
  51. data/lib/irb/frame.rb +1 -1
  52. data/lib/irb/help.rb +3 -3
  53. data/lib/irb/helper_method/base.rb +16 -0
  54. data/lib/irb/helper_method/conf.rb +11 -0
  55. data/lib/irb/helper_method.rb +29 -0
  56. data/lib/irb/history.rb +15 -4
  57. data/lib/irb/init.rb +119 -52
  58. data/lib/irb/input-method.rb +77 -27
  59. data/lib/irb/inspector.rb +3 -3
  60. data/lib/irb/lc/error.rb +1 -11
  61. data/lib/irb/lc/help-message +4 -0
  62. data/lib/irb/lc/ja/error.rb +1 -11
  63. data/lib/irb/lc/ja/help-message +13 -0
  64. data/lib/irb/locale.rb +2 -2
  65. data/lib/irb/nesting_parser.rb +13 -3
  66. data/lib/irb/notifier.rb +1 -1
  67. data/lib/irb/output-method.rb +2 -8
  68. data/lib/irb/pager.rb +16 -11
  69. data/lib/irb/ruby-lex.rb +2 -2
  70. data/lib/irb/ruby_logo.aa +43 -0
  71. data/lib/irb/source_finder.rb +112 -37
  72. data/lib/irb/statement.rb +24 -24
  73. data/lib/irb/version.rb +3 -3
  74. data/lib/irb/workspace.rb +22 -6
  75. data/lib/irb/ws-for-case-2.rb +1 -1
  76. data/lib/irb/xmp.rb +3 -3
  77. data/lib/irb.rb +1071 -556
  78. data/man/irb.1 +7 -0
  79. metadata +41 -31
  80. data/lib/irb/cmd/backtrace.rb +0 -21
  81. data/lib/irb/cmd/break.rb +0 -21
  82. data/lib/irb/cmd/catch.rb +0 -21
  83. data/lib/irb/cmd/chws.rb +0 -36
  84. data/lib/irb/cmd/edit.rb +0 -60
  85. data/lib/irb/cmd/help.rb +0 -23
  86. data/lib/irb/cmd/info.rb +0 -21
  87. data/lib/irb/cmd/pushws.rb +0 -45
  88. data/lib/irb/cmd/show_cmds.rb +0 -53
  89. data/lib/irb/cmd/show_doc.rb +0 -48
  90. data/lib/irb/cmd/show_source.rb +0 -61
  91. data/lib/irb/extend-command.rb +0 -354
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../source_finder"
4
+ require_relative "../pager"
5
+ require_relative "../color"
6
+
7
+ module IRB
8
+ module Command
9
+ class ShowSource < Base
10
+ include RubyArgsExtractor
11
+
12
+ category "Context"
13
+ description "Show the source code of a given method, class/module, or constant."
14
+
15
+ help_message <<~HELP_MESSAGE
16
+ Usage: show_source [target] [-s]
17
+
18
+ -s Show the super method. You can stack it like `-ss` to show the super of the super, etc.
19
+
20
+ Examples:
21
+
22
+ show_source Foo
23
+ show_source Foo#bar
24
+ show_source Foo#bar -s
25
+ show_source Foo.baz
26
+ show_source Foo::BAR
27
+ HELP_MESSAGE
28
+
29
+ def execute(arg)
30
+ # Accept string literal for backward compatibility
31
+ str = unwrap_string_literal(arg)
32
+ unless str.is_a?(String)
33
+ puts "Error: Expected a string but got #{str.inspect}"
34
+ return
35
+ end
36
+
37
+ str, esses = str.split(" -")
38
+ super_level = esses ? esses.count("s") : 0
39
+ source = SourceFinder.new(@irb_context).find_source(str, super_level)
40
+
41
+ if source
42
+ show_source(source)
43
+ elsif super_level > 0
44
+ puts "Error: Couldn't locate a super definition for #{str}"
45
+ else
46
+ puts "Error: Couldn't locate a definition for #{str}"
47
+ end
48
+ nil
49
+ end
50
+
51
+ private
52
+
53
+ def show_source(source)
54
+ if source.binary_file?
55
+ content = "\n#{bold('Defined in binary file')}: #{source.file}\n\n"
56
+ else
57
+ code = source.colorized_content || 'Source not available'
58
+ content = <<~CONTENT
59
+
60
+ #{bold("From")}: #{source.file}:#{source.line}
61
+
62
+ #{code.chomp}
63
+
64
+ CONTENT
65
+ end
66
+ Pager.page_content(content)
67
+ end
68
+
69
+ def bold(str)
70
+ Color.colorize(str, [:BOLD])
71
+ end
72
+ end
73
+ end
74
+ end
@@ -5,10 +5,10 @@ require_relative "debug"
5
5
  module IRB
6
6
  # :stopdoc:
7
7
 
8
- module ExtendCommand
8
+ module Command
9
9
  class Step < DebugCommand
10
- def execute(*args)
11
- super(do_cmds: ["step", *args].join(" "))
10
+ def execute(arg)
11
+ execute_debug_command(do_cmds: "step #{arg}")
12
12
  end
13
13
  end
14
14
  end
@@ -1,19 +1,15 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # multi.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
- require_relative "nop"
8
-
9
7
  module IRB
10
8
  # :stopdoc:
11
9
 
12
- module ExtendCommand
13
- class MultiIRBCommand < Nop
14
- def execute(*args)
15
- extend_irb_context
16
- end
10
+ module Command
11
+ class MultiIRBCommand < Base
12
+ include RubyArgsExtractor
17
13
 
18
14
  private
19
15
 
@@ -38,7 +34,12 @@ module IRB
38
34
  category "Multi-irb (DEPRECATED)"
39
35
  description "Start a child IRB."
40
36
 
41
- def execute(*obj)
37
+ def execute(arg)
38
+ args, kwargs = ruby_args(arg)
39
+ execute_internal(*args, **kwargs)
40
+ end
41
+
42
+ def execute_internal(*obj)
42
43
  print_deprecated_warning
43
44
 
44
45
  if irb_context.with_debugger
@@ -46,8 +47,9 @@ module IRB
46
47
  return
47
48
  end
48
49
 
49
- super
50
+ extend_irb_context
50
51
  IRB.irb(nil, *obj)
52
+ puts IRB.JobManager.inspect
51
53
  end
52
54
  end
53
55
 
@@ -55,7 +57,7 @@ module IRB
55
57
  category "Multi-irb (DEPRECATED)"
56
58
  description "List of current sessions."
57
59
 
58
- def execute
60
+ def execute(_arg)
59
61
  print_deprecated_warning
60
62
 
61
63
  if irb_context.with_debugger
@@ -63,8 +65,8 @@ module IRB
63
65
  return
64
66
  end
65
67
 
66
- super
67
- IRB.JobManager
68
+ extend_irb_context
69
+ puts IRB.JobManager.inspect
68
70
  end
69
71
  end
70
72
 
@@ -72,7 +74,12 @@ module IRB
72
74
  category "Multi-irb (DEPRECATED)"
73
75
  description "Switches to the session of the given number."
74
76
 
75
- def execute(key = nil)
77
+ def execute(arg)
78
+ args, kwargs = ruby_args(arg)
79
+ execute_internal(*args, **kwargs)
80
+ end
81
+
82
+ def execute_internal(key = nil)
76
83
  print_deprecated_warning
77
84
 
78
85
  if irb_context.with_debugger
@@ -80,10 +87,11 @@ module IRB
80
87
  return
81
88
  end
82
89
 
83
- super
90
+ extend_irb_context
84
91
 
85
92
  raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key
86
93
  IRB.JobManager.switch(key)
94
+ puts IRB.JobManager.inspect
87
95
  end
88
96
  end
89
97
 
@@ -91,7 +99,12 @@ module IRB
91
99
  category "Multi-irb (DEPRECATED)"
92
100
  description "Kills the session with the given number."
93
101
 
94
- def execute(*keys)
102
+ def execute(arg)
103
+ args, kwargs = ruby_args(arg)
104
+ execute_internal(*args, **kwargs)
105
+ end
106
+
107
+ def execute_internal(*keys)
95
108
  print_deprecated_warning
96
109
 
97
110
  if irb_context.with_debugger
@@ -99,8 +112,9 @@ module IRB
99
112
  return
100
113
  end
101
114
 
102
- super
115
+ extend_irb_context
103
116
  IRB.JobManager.kill(*keys)
117
+ puts IRB.JobManager.inspect
104
118
  end
105
119
  end
106
120
  end
@@ -1,16 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "nop"
4
-
5
3
  module IRB
6
4
  # :stopdoc:
7
5
 
8
- module ExtendCommand
9
- class Whereami < Nop
6
+ module Command
7
+ class Whereami < Base
10
8
  category "Context"
11
9
  description "Show the source code around binding.irb again."
12
10
 
13
- def execute(*)
11
+ def execute(_arg)
14
12
  code = irb_context.workspace.code_around_binding
15
13
  if code
16
14
  puts code
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # irb/command.rb - irb command
4
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
+ #
6
+
7
+ require_relative "command/base"
8
+
9
+ module IRB # :nodoc:
10
+ module Command
11
+ @commands = {}
12
+
13
+ class << self
14
+ attr_reader :commands
15
+
16
+ # Registers a command with the given name.
17
+ # Aliasing is intentionally not supported at the moment.
18
+ def register(name, command_class)
19
+ @commands[name.to_sym] = [command_class, []]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/completion.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
@@ -9,6 +9,30 @@ require_relative 'ruby-lex'
9
9
 
10
10
  module IRB
11
11
  class BaseCompletor # :nodoc:
12
+
13
+ # Set of reserved words used by Ruby, you should not use these for
14
+ # constants or variables
15
+ ReservedWords = %w[
16
+ __ENCODING__ __LINE__ __FILE__
17
+ BEGIN END
18
+ alias and
19
+ begin break
20
+ case class
21
+ def defined? do
22
+ else elsif end ensure
23
+ false for
24
+ if in
25
+ module
26
+ next nil not
27
+ or
28
+ redo rescue retry return
29
+ self super
30
+ then true
31
+ undef unless until
32
+ when while
33
+ yield
34
+ ]
35
+
12
36
  def completion_candidates(preposing, target, postposing, bind:)
13
37
  raise NotImplementedError
14
38
  end
@@ -62,6 +86,14 @@ module IRB
62
86
  )
63
87
  end
64
88
 
89
+ def command_completions(preposing, target)
90
+ if preposing.empty? && !target.empty?
91
+ IRB::Command.command_names.select { _1.start_with?(target) }
92
+ else
93
+ []
94
+ end
95
+ end
96
+
65
97
  def retrieve_files_to_require_relative_from_current_dir
66
98
  @files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
67
99
  path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
@@ -69,6 +101,29 @@ module IRB
69
101
  end
70
102
  end
71
103
 
104
+ class TypeCompletor < BaseCompletor # :nodoc:
105
+ def initialize(context)
106
+ @context = context
107
+ end
108
+
109
+ def inspect
110
+ ReplTypeCompletor.info
111
+ end
112
+
113
+ def completion_candidates(preposing, target, _postposing, bind:)
114
+ commands = command_completions(preposing, target)
115
+ result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
116
+ return commands unless result
117
+
118
+ commands | result.completion_candidates.map { target + _1 }
119
+ end
120
+
121
+ def doc_namespace(preposing, matched, _postposing, bind:)
122
+ result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path)
123
+ result&.doc_namespace('')
124
+ end
125
+ end
126
+
72
127
  class RegexpCompletor < BaseCompletor # :nodoc:
73
128
  using Module.new {
74
129
  refine ::Binding do
@@ -94,28 +149,9 @@ module IRB
94
149
  end
95
150
  }
96
151
 
97
- # Set of reserved words used by Ruby, you should not use these for
98
- # constants or variables
99
- ReservedWords = %w[
100
- __ENCODING__ __LINE__ __FILE__
101
- BEGIN END
102
- alias and
103
- begin break
104
- case class
105
- def defined? do
106
- else elsif end ensure
107
- false for
108
- if in
109
- module
110
- next nil not
111
- or
112
- redo rescue retry return
113
- self super
114
- then true
115
- undef unless until
116
- when while
117
- yield
118
- ]
152
+ def inspect
153
+ 'RegexpCompletor'
154
+ end
119
155
 
120
156
  def complete_require_path(target, preposing, postposing)
121
157
  if target =~ /\A(['"])([^'"]+)\Z/
@@ -155,7 +191,8 @@ module IRB
155
191
  result = complete_require_path(target, preposing, postposing)
156
192
  return result if result
157
193
  end
158
- retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
194
+ commands = command_completions(preposing || '', target)
195
+ commands | retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
159
196
  end
160
197
 
161
198
  def doc_namespace(_preposing, matched, _postposing, bind:)
@@ -205,16 +242,16 @@ module IRB
205
242
  end
206
243
 
207
244
  when /^([^\}]*\})\.([^.]*)$/
208
- # Proc or Hash
245
+ # Hash or Proc
209
246
  receiver = $1
210
247
  message = $2
211
248
 
212
249
  if doc_namespace
213
- ["Proc.#{message}", "Hash.#{message}"]
250
+ ["Hash.#{message}", "Proc.#{message}"]
214
251
  else
215
- proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
216
252
  hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
217
- select_message(receiver, message, proc_candidates | hash_candidates)
253
+ proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
254
+ select_message(receiver, message, hash_candidates | proc_candidates)
218
255
  end
219
256
 
220
257
  when /^(:[^:.]+)$/
@@ -362,7 +399,7 @@ module IRB
362
399
 
363
400
  if doc_namespace
364
401
  rec_class = rec.is_a?(Module) ? rec : rec.class
365
- "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}"
402
+ "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}" rescue nil
366
403
  else
367
404
  select_message(receiver, message, candidates, sep)
368
405
  end
@@ -380,13 +417,19 @@ module IRB
380
417
  else
381
418
  select_message(receiver, message, candidates.sort)
382
419
  end
383
-
420
+ when /^\s*$/
421
+ # empty input
422
+ if doc_namespace
423
+ nil
424
+ else
425
+ []
426
+ end
384
427
  else
385
428
  if doc_namespace
386
429
  vars = (bind.local_variables | bind.eval_instance_variables).collect{|m| m.to_s}
387
430
  perfect_match_var = vars.find{|m| m.to_s == input}
388
431
  if perfect_match_var
389
- eval("#{perfect_match_var}.class.name", bind)
432
+ eval("#{perfect_match_var}.class.name", bind) rescue nil
390
433
  else
391
434
  candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s}
392
435
  candidates |= ReservedWords