irb 1.13.1 → 1.14.0

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: b57e45ef4cb7d58489abeda8131ed81a1625b05fd139e00082bf3011fc0c2fdc
4
- data.tar.gz: 411b92eee70de798e94c0c9c30801467cdf240a43eff4da9e46230374fa8504f
3
+ metadata.gz: b96add3ef12d981b483ae225bfd8bca8a1a477f0b03c8040a0dfbf047bd0d1fb
4
+ data.tar.gz: efe91e97fab6b11a239c4774da9d5ecfe39bbc364d61a6b2c7fd6ec8b9c01a72
5
5
  SHA512:
6
- metadata.gz: '0919ac233b97abb80a9d34cad9be792e85bce261cc4c29c36eac8d7ba81bd99c4592b5b8c1bdbdc7e96d778ccf20b5374987eef0224e9fb6583639633e3c2bb0'
7
- data.tar.gz: 89dad0bbdebdee60a3f08ca2cf918293bffac4db7b183a45ab93f6cc4906ca7a62437286a08291ba76fae8e2bba31f3b6a28be3cd13a141f451a5c4e1b09041d
6
+ metadata.gz: 0eaa119e765d958cdab2ba80fa12e47a9727d389a37f255e174ec260279af8e2c2edb510689364541fe40f3c202a3b3d4f2d7dc7fbe30030b04e89bc2c851a3a
7
+ data.tar.gz: 71904280b978ac48763d7bc965f053fd5580ec7876c40cba76a1a9c26ac7aec2f4ad98deb1d9c8d3635f5222a0b757d458d7fded9264411b05f19bfe77ad2526
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IRB
4
+ module Command
5
+ class CD < Base
6
+ category "Workspace"
7
+ description "Move into the given object or leave the current context."
8
+
9
+ help_message(<<~HELP)
10
+ Usage: cd ([target]|..)
11
+
12
+ IRB uses a stack of workspaces to keep track of context(s), with `pushws` and `popws` commands to manipulate the stack.
13
+ The `cd` command is an attempt to simplify the operation and will be subject to change.
14
+
15
+ When given:
16
+ - an object, cd will use that object as the new context by pushing it onto the workspace stack.
17
+ - "..", cd will leave the current context by popping the top workspace off the stack.
18
+ - no arguments, cd will move to the top workspace on the stack by popping off all workspaces.
19
+
20
+ Examples:
21
+
22
+ cd Foo
23
+ cd Foo.new
24
+ cd @ivar
25
+ cd ..
26
+ cd
27
+ HELP
28
+
29
+ def execute(arg)
30
+ case arg
31
+ when ".."
32
+ irb_context.pop_workspace
33
+ when ""
34
+ # TODO: decide what workspace commands should be kept, and underlying APIs should look like,
35
+ # and perhaps add a new API to clear the workspace stack.
36
+ prev_workspace = irb_context.pop_workspace
37
+ while prev_workspace
38
+ prev_workspace = irb_context.pop_workspace
39
+ end
40
+ else
41
+ begin
42
+ obj = eval(arg, irb_context.workspace.binding)
43
+ irb_context.push_workspace(obj)
44
+ rescue StandardError => e
45
+ warn "Error: #{e}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -33,6 +33,8 @@ module IRB
33
33
  yield
34
34
  ]
35
35
 
36
+ HELP_COMMAND_PREPOSING = /\Ahelp\s+/
37
+
36
38
  def completion_candidates(preposing, target, postposing, bind:)
37
39
  raise NotImplementedError
38
40
  end
@@ -86,8 +88,8 @@ module IRB
86
88
  )
87
89
  end
88
90
 
89
- def command_completions(preposing, target)
90
- if preposing.empty? && !target.empty?
91
+ def command_candidates(target)
92
+ if !target.empty?
91
93
  IRB::Command.command_names.select { _1.start_with?(target) }
92
94
  else
93
95
  []
@@ -111,8 +113,18 @@ module IRB
111
113
  end
112
114
 
113
115
  def completion_candidates(preposing, target, _postposing, bind:)
114
- commands = command_completions(preposing, target)
116
+ # When completing the argument of `help` command, only commands should be candidates
117
+ return command_candidates(target) if preposing.match?(HELP_COMMAND_PREPOSING)
118
+
119
+ commands = if preposing.empty?
120
+ command_candidates(target)
121
+ # It doesn't make sense to propose commands with other preposing
122
+ else
123
+ []
124
+ end
125
+
115
126
  result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path)
127
+
116
128
  return commands unless result
117
129
 
118
130
  commands | result.completion_candidates.map { target + _1 }
@@ -187,12 +199,20 @@ module IRB
187
199
  end
188
200
 
189
201
  def completion_candidates(preposing, target, postposing, bind:)
190
- if preposing && postposing
191
- result = complete_require_path(target, preposing, postposing)
192
- return result if result
202
+ if result = complete_require_path(target, preposing, postposing)
203
+ return result
193
204
  end
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) }
205
+
206
+ commands = command_candidates(target)
207
+
208
+ # When completing the argument of `help` command, only commands should be candidates
209
+ return commands if preposing.match?(HELP_COMMAND_PREPOSING)
210
+
211
+ # It doesn't make sense to propose commands with other preposing
212
+ commands = [] unless preposing.empty?
213
+
214
+ completion_data = retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) }
215
+ commands | completion_data
196
216
  end
197
217
 
198
218
  def doc_namespace(_preposing, matched, _postposing, bind:)
@@ -470,7 +490,7 @@ module IRB
470
490
  end
471
491
  end
472
492
  CompletionProc = ->(target, preposing = nil, postposing = nil) {
473
- regexp_completor.completion_candidates(preposing, target, postposing, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
493
+ regexp_completor.completion_candidates(preposing || '', target, postposing || '', bind: IRB.conf[:MAIN_CONTEXT].workspace.binding)
474
494
  }
475
495
  end
476
496
  deprecate_constant :InputCompletor
data/lib/irb/context.rb CHANGED
@@ -73,11 +73,12 @@ module IRB
73
73
 
74
74
  self.prompt_mode = IRB.conf[:PROMPT_MODE]
75
75
 
76
- if IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager)
77
- @irb_name = IRB.conf[:IRB_NAME]
78
- else
79
- @irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
76
+ @irb_name = IRB.conf[:IRB_NAME]
77
+
78
+ unless IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager)
79
+ @irb_name = @irb_name + "#" + IRB.JobManager.n_jobs.to_s
80
80
  end
81
+
81
82
  self.irb_path = "(" + @irb_name + ")"
82
83
 
83
84
  case input_method
@@ -601,7 +602,6 @@ module IRB
601
602
  set_last_value(result)
602
603
  when Statement::Command
603
604
  statement.command_class.execute(self, statement.arg)
604
- set_last_value(nil)
605
605
  end
606
606
 
607
607
  nil
@@ -2,32 +2,34 @@
2
2
 
3
3
  require_relative "command"
4
4
  require_relative "command/internal_helpers"
5
- require_relative "command/context"
6
- require_relative "command/exit"
7
- require_relative "command/force_exit"
8
- require_relative "command/chws"
9
- require_relative "command/pushws"
10
- require_relative "command/subirb"
11
- require_relative "command/load"
12
- require_relative "command/debug"
13
- require_relative "command/edit"
5
+ require_relative "command/backtrace"
14
6
  require_relative "command/break"
15
7
  require_relative "command/catch"
16
- require_relative "command/next"
17
- require_relative "command/delete"
18
- require_relative "command/step"
8
+ require_relative "command/cd"
9
+ require_relative "command/chws"
10
+ require_relative "command/context"
19
11
  require_relative "command/continue"
12
+ require_relative "command/debug"
13
+ require_relative "command/delete"
14
+ require_relative "command/disable_irb"
15
+ require_relative "command/edit"
16
+ require_relative "command/exit"
20
17
  require_relative "command/finish"
21
- require_relative "command/backtrace"
22
- require_relative "command/info"
18
+ require_relative "command/force_exit"
23
19
  require_relative "command/help"
24
- require_relative "command/show_doc"
20
+ require_relative "command/history"
21
+ require_relative "command/info"
25
22
  require_relative "command/irb_info"
23
+ require_relative "command/load"
26
24
  require_relative "command/ls"
27
25
  require_relative "command/measure"
26
+ require_relative "command/next"
27
+ require_relative "command/pushws"
28
+ require_relative "command/show_doc"
28
29
  require_relative "command/show_source"
30
+ require_relative "command/step"
31
+ require_relative "command/subirb"
29
32
  require_relative "command/whereami"
30
- require_relative "command/history"
31
33
 
32
34
  module IRB
33
35
  module Command
@@ -235,6 +237,12 @@ module IRB
235
237
  [:history, NO_OVERRIDE],
236
238
  [:hist, NO_OVERRIDE]
237
239
  )
240
+
241
+ _register_with_aliases(:irb_disable_irb, Command::DisableIrb,
242
+ [:disable_irb, NO_OVERRIDE]
243
+ )
244
+
245
+ register(:cd, Command::CD)
238
246
  end
239
247
 
240
248
  ExtendCommand = Command
data/lib/irb/init.rb CHANGED
@@ -52,6 +52,7 @@ module IRB # :nodoc:
52
52
  IRB.init_error
53
53
  IRB.parse_opts(argv: argv)
54
54
  IRB.run_config
55
+ IRB.validate_config
55
56
  IRB.load_modules
56
57
 
57
58
  unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
@@ -427,6 +428,40 @@ module IRB # :nodoc:
427
428
  @irbrc_files
428
429
  end
429
430
 
431
+ def IRB.validate_config
432
+ conf[:IRB_NAME] = conf[:IRB_NAME].to_s
433
+
434
+ irb_rc = conf[:IRB_RC]
435
+ unless irb_rc.nil? || irb_rc.respond_to?(:call)
436
+ raise_validation_error "IRB.conf[:IRB_RC] should be a callable object. Got #{irb_rc.inspect}."
437
+ end
438
+
439
+ back_trace_limit = conf[:BACK_TRACE_LIMIT]
440
+ unless back_trace_limit.is_a?(Integer)
441
+ raise_validation_error "IRB.conf[:BACK_TRACE_LIMIT] should be an integer. Got #{back_trace_limit.inspect}."
442
+ end
443
+
444
+ prompt = conf[:PROMPT]
445
+ unless prompt.is_a?(Hash)
446
+ msg = "IRB.conf[:PROMPT] should be a Hash. Got #{prompt.inspect}."
447
+
448
+ if prompt.is_a?(Symbol)
449
+ msg += " Did you mean to set `IRB.conf[:PROMPT_MODE]`?"
450
+ end
451
+
452
+ raise_validation_error msg
453
+ end
454
+
455
+ eval_history = conf[:EVAL_HISTORY]
456
+ unless eval_history.nil? || eval_history.is_a?(Integer)
457
+ raise_validation_error "IRB.conf[:EVAL_HISTORY] should be an integer. Got #{eval_history.inspect}."
458
+ end
459
+ end
460
+
461
+ def IRB.raise_validation_error(msg)
462
+ raise TypeError, msg, @irbrc_files
463
+ end
464
+
430
465
  # loading modules
431
466
  def IRB.load_modules
432
467
  for m in @CONF[:LOAD_MODULES]
@@ -328,10 +328,11 @@ module IRB
328
328
  ->() {
329
329
  dialog.trap_key = nil
330
330
  alt_d = [
331
- [Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
332
331
  [27, 100], # Normal Alt+d when convert-meta isn't used.
333
- [195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
334
- [226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
332
+ # When option/alt is not configured as a meta key in terminal emulator,
333
+ # option/alt + d will send a unicode character depend on OS keyboard setting.
334
+ [195, 164], # "ä" in somewhere (FIXME: environment information is unknown).
335
+ [226, 136, 130] # "∂" Alt+d on Mac keyboard.
335
336
  ]
336
337
 
337
338
  if just_cursor_moving and completion_journey_data.nil?
data/lib/irb/ruby-lex.rb CHANGED
@@ -219,28 +219,7 @@ module IRB
219
219
  :unrecoverable_error
220
220
  rescue SyntaxError => e
221
221
  case e.message
222
- when /unterminated (?:string|regexp) meets end of file/
223
- # "unterminated regexp meets end of file"
224
- #
225
- # example:
226
- # /
227
- #
228
- # "unterminated string meets end of file"
229
- #
230
- # example:
231
- # '
232
- return :recoverable_error
233
- when /syntax error, unexpected end-of-input/
234
- # "syntax error, unexpected end-of-input, expecting keyword_end"
235
- #
236
- # example:
237
- # if true
238
- # hoge
239
- # if false
240
- # fuga
241
- # end
242
- return :recoverable_error
243
- when /syntax error, unexpected keyword_end/
222
+ when /unexpected keyword_end/
244
223
  # "syntax error, unexpected keyword_end"
245
224
  #
246
225
  # example:
@@ -250,7 +229,7 @@ module IRB
250
229
  # example:
251
230
  # end
252
231
  return :unrecoverable_error
253
- when /syntax error, unexpected '\.'/
232
+ when /unexpected '\.'/
254
233
  # "syntax error, unexpected '.'"
255
234
  #
256
235
  # example:
@@ -262,6 +241,27 @@ module IRB
262
241
  # example:
263
242
  # method / f /
264
243
  return :unrecoverable_error
244
+ when /unterminated (?:string|regexp) meets end of file/
245
+ # "unterminated regexp meets end of file"
246
+ #
247
+ # example:
248
+ # /
249
+ #
250
+ # "unterminated string meets end of file"
251
+ #
252
+ # example:
253
+ # '
254
+ return :recoverable_error
255
+ when /unexpected end-of-input/
256
+ # "syntax error, unexpected end-of-input, expecting keyword_end"
257
+ #
258
+ # example:
259
+ # if true
260
+ # hoge
261
+ # if false
262
+ # fuga
263
+ # end
264
+ return :recoverable_error
265
265
  else
266
266
  return :other_error
267
267
  end
data/lib/irb/statement.rb CHANGED
@@ -68,7 +68,7 @@ module IRB
68
68
  end
69
69
 
70
70
  def suppresses_echo?
71
- false
71
+ true
72
72
  end
73
73
 
74
74
  def should_be_handled_by_debugger?
data/lib/irb/version.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.13.1"
8
+ VERSION = "1.14.0"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2024-05-05"
10
+ @LAST_UPDATE_DATE = "2024-07-06"
11
11
  end
data/lib/irb.rb CHANGED
@@ -1138,6 +1138,8 @@ module IRB
1138
1138
  end
1139
1139
  end
1140
1140
 
1141
+ ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
1142
+
1141
1143
  def parse_command(code)
1142
1144
  command_name, arg = code.strip.split(/\s+/, 2)
1143
1145
  return unless code.lines.size == 1 && command_name
@@ -1149,6 +1151,12 @@ module IRB
1149
1151
  return [alias_name, arg]
1150
1152
  end
1151
1153
 
1154
+ # Assignment-like expression is not a command
1155
+ return if arg.start_with?(ASSIGN_OPERATORS_REGEXP) && !arg.start_with?(/==|=~/)
1156
+
1157
+ # Local variable have precedence over command
1158
+ return if @context.local_variables.include?(command)
1159
+
1152
1160
  # Check visibility
1153
1161
  public_method = !!Kernel.instance_method(:public_method).bind_call(@context.main, command) rescue false
1154
1162
  private_method = !public_method && !!Kernel.instance_method(:method).bind_call(@context.main, command) rescue false
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.1
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - aycabta
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2024-05-05 00:00:00.000000000 Z
12
+ date: 2024-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: reline
@@ -68,6 +68,7 @@ files:
68
68
  - lib/irb/command/base.rb
69
69
  - lib/irb/command/break.rb
70
70
  - lib/irb/command/catch.rb
71
+ - lib/irb/command/cd.rb
71
72
  - lib/irb/command/chws.rb
72
73
  - lib/irb/command/context.rb
73
74
  - lib/irb/command/continue.rb
@@ -157,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
158
  - !ruby/object:Gem::Version
158
159
  version: '0'
159
160
  requirements: []
160
- rubygems_version: 3.5.7
161
+ rubygems_version: 3.5.11
161
162
  signing_key:
162
163
  specification_version: 4
163
164
  summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).