irb 1.3.4 → 1.3.5

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: e897a7306cd4fde4a54fa2cc4c8dff34ccf4ecd5e69e324d9c91901c9a683cde
4
- data.tar.gz: d424e3853889fef65b7e01df7d58e27bbd7467e081c733d7937aadde0544f4e9
3
+ metadata.gz: d7a7034e210074f2c31db1369ffe0d5203cd7d2d35a1b9df36cbabfe6d52109e
4
+ data.tar.gz: c22c2ea2a1fb878c0b96d194c8b5af832c07d4b53173ebec07cfcadb04ac4d33
5
5
  SHA512:
6
- metadata.gz: 77001229102437b40664c561a4b2ef1f5672e2e82661332be8a9f770356640a7de588b17c6d66164edbcd504158effd2b075b58172b2863b3862aa8735a1a72f
7
- data.tar.gz: f83d98526ea74c4f015c85377f3c8d569a4d2a1f507331db80c41ab2225d4512c8ad6937d9bb90f703b7c95c214cb36e2f1c1e5107bed62554ecf2ba2cc2aa91
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,53 +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/info.rb",
36
- "lib/irb/cmd/load.rb",
37
- "lib/irb/cmd/measure.rb",
38
- "lib/irb/cmd/nop.rb",
39
- "lib/irb/cmd/pushws.rb",
40
- "lib/irb/cmd/subirb.rb",
41
- "lib/irb/color.rb",
42
- "lib/irb/color_printer.rb",
43
- "lib/irb/completion.rb",
44
- "lib/irb/context.rb",
45
- "lib/irb/easter-egg.rb",
46
- "lib/irb/ext/change-ws.rb",
47
- "lib/irb/ext/history.rb",
48
- "lib/irb/ext/loader.rb",
49
- "lib/irb/ext/multi-irb.rb",
50
- "lib/irb/ext/save-history.rb",
51
- "lib/irb/ext/tracer.rb",
52
- "lib/irb/ext/use-loader.rb",
53
- "lib/irb/ext/workspaces.rb",
54
- "lib/irb/extend-command.rb",
55
- "lib/irb/frame.rb",
56
- "lib/irb/help.rb",
57
- "lib/irb/init.rb",
58
- "lib/irb/input-method.rb",
59
- "lib/irb/inspector.rb",
60
- "lib/irb/lc/error.rb",
61
- "lib/irb/lc/help-message",
62
- "lib/irb/lc/ja/encoding_aliases.rb",
63
- "lib/irb/lc/ja/error.rb",
64
- "lib/irb/lc/ja/help-message",
65
- "lib/irb/locale.rb",
66
- "lib/irb/magic-file.rb",
67
- "lib/irb/notifier.rb",
68
- "lib/irb/output-method.rb",
69
- "lib/irb/ruby-lex.rb",
70
- "lib/irb/ruby_logo.aa",
71
- "lib/irb/src_encoding.rb",
72
- "lib/irb/version.rb",
73
- "lib/irb/workspace.rb",
74
- "lib/irb/ws-for-case-2.rb",
75
- "lib/irb/xmp.rb",
76
31
  "man/irb.1",
77
- ]
32
+ ] + Dir.glob("lib/**/*")
78
33
  spec.bindir = "exe"
79
34
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
80
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
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:
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, &block)
19
- command = new(conf)
20
- command.execute(*opts, &block)
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:
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "nop"
4
+
5
+ # :stopdoc:
6
+ module IRB
7
+ module ExtendCommand
8
+ class Whereami < Nop
9
+ def execute(*)
10
+ code = irb_context.workspace.code_around_binding
11
+ if code
12
+ puts code
13
+ else
14
+ puts "The current context doesn't have code."
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ # :startdoc:
data/lib/irb/color.rb CHANGED
@@ -64,6 +64,7 @@ module IRB # :nodoc:
64
64
  on_alias_error: [[RED, REVERSE], ALL],
65
65
  on_class_name_error:[[RED, REVERSE], ALL],
66
66
  on_param_error: [[RED, REVERSE], ALL],
67
+ on___end__: [[GREEN], ALL],
67
68
  }
68
69
  rescue NameError
69
70
  # Give up highlighting Ripper-incompatible older Ruby
@@ -120,6 +121,7 @@ module IRB # :nodoc:
120
121
  symbol_state = SymbolState.new
121
122
  colored = +''
122
123
  length = 0
124
+ end_seen = false
123
125
 
124
126
  scan(code, allow_last_error: !complete) do |token, str, expr|
125
127
  # IRB::ColorPrinter skips colorizing fragments with any invalid token
@@ -138,10 +140,11 @@ module IRB # :nodoc:
138
140
  end
139
141
  end
140
142
  length += str.bytesize
143
+ end_seen = true if token == :on___end__
141
144
  end
142
145
 
143
146
  # give up colorizing incomplete Ripper tokens
144
- if length != code.bytesize
147
+ unless end_seen or length == code.bytesize
145
148
  return Reline::Unicode.escape_for_print(code)
146
149
  end
147
150
 
@@ -21,6 +21,15 @@ module IRB
21
21
  end
22
22
  end
23
23
 
24
+ def pp(obj)
25
+ if obj.is_a?(String)
26
+ # Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n"
27
+ text(obj.inspect)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
24
33
  def text(str, width = nil)
25
34
  unless str.is_a?(String)
26
35
  str = str.inspect
@@ -7,7 +7,7 @@
7
7
  # From Original Idea of shugo@ruby-lang.org
8
8
  #
9
9
 
10
- autoload :RDoc, "rdoc"
10
+ require_relative 'ruby-lex'
11
11
 
12
12
  module IRB
13
13
  module InputCompletor # :nodoc:
@@ -38,8 +38,69 @@ module IRB
38
38
 
39
39
  BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
40
40
 
41
- CompletionProc = proc { |input|
42
- retrieve_completion_data(input).compact.map{ |i| i.encode(Encoding.default_external) }
41
+ def self.retrieve_files_to_require_from_load_path
42
+ @@files_from_load_path ||= $LOAD_PATH.flat_map { |path|
43
+ begin
44
+ Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path)
45
+ rescue Errno::ENOENT
46
+ []
47
+ end
48
+ }.uniq.map { |path|
49
+ path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
50
+ }
51
+ end
52
+
53
+ def self.retrieve_files_to_require_relative_from_current_dir
54
+ @@files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path|
55
+ path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '')
56
+ }
57
+ end
58
+
59
+ CompletionRequireProc = lambda { |target, preposing = nil, postposing = nil|
60
+ if target =~ /\A(['"])([^'"]+)\Z/
61
+ quote = $1
62
+ actual_target = $2
63
+ else
64
+ return nil # It's not String literal
65
+ end
66
+ tokens = RubyLex.ripper_lex_without_warning(preposing.gsub(/\s*\z/, ''))
67
+ tok = nil
68
+ tokens.reverse_each do |t|
69
+ unless [:on_lparen, :on_sp, :on_ignored_sp, :on_nl, :on_ignored_nl, :on_comment].include?(t.event)
70
+ tok = t
71
+ break
72
+ end
73
+ end
74
+ result = []
75
+ if tok && tok.event == :on_ident && tok.state == Ripper::EXPR_CMDARG
76
+ case tok.tok
77
+ when 'require'
78
+ result = retrieve_files_to_require_from_load_path.select { |path|
79
+ path.start_with?(actual_target)
80
+ }.map { |path|
81
+ quote + path
82
+ }
83
+ when 'require_relative'
84
+ result = retrieve_files_to_require_relative_from_current_dir.select { |path|
85
+ path.start_with?(actual_target)
86
+ }.map { |path|
87
+ quote + path
88
+ }
89
+ end
90
+ end
91
+ result
92
+ }
93
+
94
+ CompletionProc = lambda { |target, preposing = nil, postposing = nil|
95
+ if preposing && postposing
96
+ result = CompletionRequireProc.(target, preposing, postposing)
97
+ unless result
98
+ result = retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
99
+ end
100
+ result
101
+ else
102
+ retrieve_completion_data(target).compact.map{ |i| i.encode(Encoding.default_external) }
103
+ end
43
104
  }
44
105
 
45
106
  def self.retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false)
@@ -266,13 +327,22 @@ module IRB
266
327
  end
267
328
 
268
329
  PerfectMatchedProc = ->(matched, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) {
330
+ begin
331
+ require 'rdoc'
332
+ rescue LoadError
333
+ return
334
+ end
335
+
269
336
  RDocRIDriver ||= RDoc::RI::Driver.new
337
+
270
338
  if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
271
339
  IRB.__send__(:easter_egg)
272
340
  return
273
341
  end
342
+
274
343
  namespace = retrieve_completion_data(matched, bind: bind, doc_namespace: true)
275
344
  return unless namespace
345
+
276
346
  if namespace.is_a?(Array)
277
347
  out = RDoc::Markup::Document.new
278
348
  namespace.each do |m|
@@ -81,6 +81,8 @@ module IRB
81
81
  end
82
82
  }
83
83
  end
84
+ @loaded_history_lines = history.size
85
+ @loaded_history_mtime = File.mtime(history_file)
84
86
  end
85
87
  end
86
88
 
@@ -105,12 +107,20 @@ module IRB
105
107
  raise
106
108
  end
107
109
 
108
- open(history_file, "w:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
110
+ if File.exist?(history_file) && @loaded_history_mtime &&
111
+ File.mtime(history_file) != @loaded_history_mtime
112
+ history = history[@loaded_history_lines..-1]
113
+ append_history = true
114
+ end
115
+
116
+ open(history_file, "#{append_history ? 'a' : 'w'}:#{IRB.conf[:LC_MESSAGES].encoding}", 0600) do |f|
109
117
  hist = history.map{ |l| l.split("\n").join("\\\n") }
110
- begin
111
- hist = hist.last(num) if hist.size > num and num > 0
112
- rescue RangeError # bignum too big to convert into `long'
113
- # Do nothing because the bignum should be treated as inifinity
118
+ unless append_history
119
+ begin
120
+ hist = hist.last(num) if hist.size > num and num > 0
121
+ rescue RangeError # bignum too big to convert into `long'
122
+ # Do nothing because the bignum should be treated as inifinity
123
+ end
114
124
  end
115
125
  f.puts(hist)
116
126
  end
@@ -126,7 +126,23 @@ module IRB # :nodoc:
126
126
  ],
127
127
 
128
128
  [
129
- :measure, :Measure, "irb/cmd/measure"
129
+ :irb_ls, :Ls, "irb/cmd/ls",
130
+ [:ls, NO_OVERRIDE],
131
+ ],
132
+
133
+ [
134
+ :irb_measure, :Measure, "irb/cmd/measure",
135
+ [:measure, NO_OVERRIDE],
136
+ ],
137
+
138
+ [
139
+ :irb_show_source, :ShowSource, "irb/cmd/show_source",
140
+ [:show_source, NO_OVERRIDE],
141
+ ],
142
+
143
+ [
144
+ :irb_whereami, :Whereami, "irb/cmd/whereami",
145
+ [:whereami, NO_OVERRIDE],
130
146
  ],
131
147
 
132
148
  ]
@@ -168,12 +184,13 @@ module IRB # :nodoc:
168
184
  end
169
185
 
170
186
  if load_file
187
+ kwargs = ", **kwargs" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.7.0"
171
188
  line = __LINE__; eval %[
172
- def #{cmd_name}(*opts, &b)
189
+ def #{cmd_name}(*opts#{kwargs}, &b)
173
190
  require "#{load_file}"
174
191
  arity = ExtendCommand::#{cmd_class}.instance_method(:execute).arity
175
192
  args = (1..(arity < 0 ? ~arity : arity)).map {|i| "arg" + i.to_s }
176
- args << "*opts" if arity < 0
193
+ args << "*opts#{kwargs}" if arity < 0
177
194
  args << "&block"
178
195
  args = args.join(", ")
179
196
  line = __LINE__; eval %[
@@ -184,7 +201,7 @@ module IRB # :nodoc:
184
201
  end
185
202
  end
186
203
  ], nil, __FILE__, line
187
- __send__ :#{cmd_name}_, *opts, &b
204
+ __send__ :#{cmd_name}_, *opts#{kwargs}, &b
188
205
  end
189
206
  ], nil, __FILE__, line
190
207
  else
@@ -280,6 +280,7 @@ module IRB
280
280
  Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
281
281
  end
282
282
  Reline.completion_append_character = nil
283
+ Reline.completer_quote_characters = ''
283
284
  Reline.completion_proc = IRB::InputCompletor::CompletionProc
284
285
  Reline.output_modifier_proc =
285
286
  if IRB.conf[:USE_COLORIZE]
@@ -10,7 +10,7 @@
10
10
  #
11
11
  #
12
12
  Usage: irb.rb [options] [programfile] [arguments]
13
- -f Suppress read of ~/.irbrc
13
+ -f Suppress read of ~/.irbrc
14
14
  -d Set $DEBUG to true (same as `ruby -d')
15
15
  -r load-module Same as `ruby -r'
16
16
  -I path Specify $LOAD_PATH directory
@@ -18,7 +18,7 @@ Usage: irb.rb [options] [programfile] [arguments]
18
18
  -E enc Same as `ruby -E`
19
19
  -w Same as `ruby -w`
20
20
  -W[level=2] Same as `ruby -W`
21
- --context-mode n Set n[0-3] to method to create Binding Object,
21
+ --context-mode n Set n[0-4] to method to create Binding Object,
22
22
  when new workspace was created
23
23
  --echo Show result(default)
24
24
  --noecho Don't show result
@@ -31,8 +31,8 @@ Usage: irb.rb [options] [programfile] [arguments]
31
31
  --colorize Use colorization
32
32
  --nocolorize Don't use colorization
33
33
  --prompt prompt-mode/--prompt-mode prompt-mode
34
- Switch prompt mode. Pre-defined prompt modes are
35
- `default', `simple', `xmp' and `inf-ruby'
34
+ Switch prompt mode. Pre-defined prompt modes are
35
+ `default', `simple', `xmp' and `inf-ruby'
36
36
  --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs.
37
37
  Suppresses --multiline and --singleline.
38
38
  --sample-book-mode/--simple-prompt
@@ -41,8 +41,8 @@ Usage: irb.rb [options] [programfile] [arguments]
41
41
  --single-irb Share self with sub-irb.
42
42
  --tracer Display trace for each execution of commands.
43
43
  --back-trace-limit n
44
- Display backtrace top n and tail n. The default
45
- value is 16.
44
+ Display backtrace top n and tail n. The default
45
+ value is 16.
46
46
  --verbose Show details
47
47
  --noverbose Don't show details
48
48
  -v, --version Print the version of irb
data/lib/irb/ruby-lex.rb CHANGED
@@ -47,12 +47,26 @@ class RubyLex
47
47
  @io = io
48
48
  if @io.respond_to?(:check_termination)
49
49
  @io.check_termination do |code|
50
- code.gsub!(/\s*\z/, '').concat("\n")
51
- ltype, indent, continue, code_block_open = check_state(code)
52
- if ltype or indent > 0 or continue or code_block_open
53
- false
50
+ if Reline::IOGate.in_pasting?
51
+ lex = RubyLex.new
52
+ rest = lex.check_termination_in_prev_line(code)
53
+ if rest
54
+ Reline.delete_text
55
+ rest.bytes.reverse_each do |c|
56
+ Reline.ungetc(c)
57
+ end
58
+ true
59
+ else
60
+ false
61
+ end
54
62
  else
55
- true
63
+ code.gsub!(/\s*\z/, '').concat("\n")
64
+ ltype, indent, continue, code_block_open = check_state(code)
65
+ if ltype or indent > 0 or continue or code_block_open
66
+ false
67
+ else
68
+ true
69
+ end
56
70
  end
57
71
  end
58
72
  end
@@ -60,7 +74,7 @@ class RubyLex
60
74
  @io.dynamic_prompt do |lines|
61
75
  lines << '' if lines.empty?
62
76
  result = []
63
- tokens = ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
77
+ tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join)
64
78
  code = String.new
65
79
  partial_tokens = []
66
80
  unprocessed_tokens = []
@@ -115,10 +129,10 @@ class RubyLex
115
129
  :on_param_error
116
130
  ]
117
131
 
118
- def ripper_lex_without_warning(code)
132
+ def self.ripper_lex_without_warning(code)
119
133
  verbose, $VERBOSE = $VERBOSE, nil
120
134
  tokens = nil
121
- self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
135
+ compile_with_errors_suppressed(code) do |inner_code, line_no|
122
136
  lexer = Ripper::Lexer.new(inner_code, '-', line_no)
123
137
  if lexer.respond_to?(:scan) # Ruby 2.7+
124
138
  tokens = []
@@ -168,7 +182,7 @@ class RubyLex
168
182
  if @io.respond_to?(:auto_indent) and context.auto_indent_mode
169
183
  @io.auto_indent do |lines, line_index, byte_pointer, is_newline|
170
184
  if is_newline
171
- @tokens = ripper_lex_without_warning(lines[0..line_index].join("\n"))
185
+ @tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"))
172
186
  prev_spaces = find_prev_spaces(line_index)
173
187
  depth_difference = check_newline_depth_difference
174
188
  depth_difference = 0 if depth_difference < 0
@@ -177,7 +191,7 @@ class RubyLex
177
191
  code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
178
192
  last_line = lines[line_index]&.byteslice(0, byte_pointer)
179
193
  code += last_line if last_line
180
- @tokens = ripper_lex_without_warning(code)
194
+ @tokens = self.class.ripper_lex_without_warning(code)
181
195
  corresponding_token_depth = check_corresponding_token_depth
182
196
  if corresponding_token_depth
183
197
  corresponding_token_depth
@@ -190,7 +204,7 @@ class RubyLex
190
204
  end
191
205
 
192
206
  def check_state(code, tokens = nil)
193
- tokens = ripper_lex_without_warning(code) unless tokens
207
+ tokens = self.class.ripper_lex_without_warning(code) unless tokens
194
208
  ltype = process_literal_type(tokens)
195
209
  indent = process_nesting_level(tokens)
196
210
  continue = process_continue(tokens)
@@ -256,7 +270,7 @@ class RubyLex
256
270
  end
257
271
  code = @line + (line.nil? ? '' : line)
258
272
  code.gsub!(/\s*\z/, '').concat("\n")
259
- @tokens = ripper_lex_without_warning(code)
273
+ @tokens = self.class.ripper_lex_without_warning(code)
260
274
  @continue = process_continue
261
275
  @code_block_open = check_code_block(code)
262
276
  @indent = process_nesting_level
@@ -277,8 +291,9 @@ class RubyLex
277
291
  return true
278
292
  elsif tokens.size >= 1 and tokens[-1][1] == :on_heredoc_end # "EOH\n"
279
293
  return false
280
- elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME)
294
+ elsif tokens.size >= 2 and defined?(Ripper::EXPR_BEG) and tokens[-2][3].anybits?(Ripper::EXPR_BEG | Ripper::EXPR_FNAME) and tokens[-2][2] !~ /\A\.\.\.?\z/
281
295
  # end of literal except for regexp
296
+ # endless range at end of line is not a continue
282
297
  return true
283
298
  end
284
299
  false
@@ -738,5 +753,50 @@ class RubyLex
738
753
  nil
739
754
  end
740
755
  end
756
+
757
+ def check_termination_in_prev_line(code)
758
+ tokens = self.class.ripper_lex_without_warning(code)
759
+ past_first_newline = false
760
+ index = tokens.rindex do |t|
761
+ # traverse first token before last line
762
+ if past_first_newline
763
+ if t.tok.include?("\n")
764
+ true
765
+ end
766
+ elsif t.tok.include?("\n")
767
+ past_first_newline = true
768
+ false
769
+ else
770
+ false
771
+ end
772
+ end
773
+ if index
774
+ first_token = nil
775
+ last_line_tokens = tokens[(index + 1)..(tokens.size - 1)]
776
+ last_line_tokens.each do |t|
777
+ unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event)
778
+ first_token = t
779
+ break
780
+ end
781
+ end
782
+ if first_token.nil?
783
+ return false
784
+ elsif first_token && first_token.state == Ripper::EXPR_DOT
785
+ return false
786
+ else
787
+ tokens_without_last_line = tokens[0..index]
788
+ ltype = process_literal_type(tokens_without_last_line)
789
+ indent = process_nesting_level(tokens_without_last_line)
790
+ continue = process_continue(tokens_without_last_line)
791
+ code_block_open = check_code_block(tokens_without_last_line.map(&:tok).join(''), tokens_without_last_line)
792
+ if ltype or indent > 0 or continue or code_block_open
793
+ return false
794
+ else
795
+ return last_line_tokens.map(&:tok).join('')
796
+ end
797
+ end
798
+ end
799
+ false
800
+ end
741
801
  end
742
802
  # :startdoc:
data/lib/irb/version.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  #
12
12
 
13
13
  module IRB # :nodoc:
14
- VERSION = "1.3.4"
14
+ VERSION = "1.3.5"
15
15
  @RELEASE_VERSION = VERSION
16
- @LAST_UPDATE_DATE = "2021-02-25"
16
+ @LAST_UPDATE_DATE = "2021-04-03"
17
17
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keiju ISHITSUKA
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-25 00:00:00.000000000 Z
11
+ date: 2021-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: reline
@@ -77,10 +77,13 @@ files:
77
77
  - lib/irb/cmd/help.rb
78
78
  - lib/irb/cmd/info.rb
79
79
  - lib/irb/cmd/load.rb
80
+ - lib/irb/cmd/ls.rb
80
81
  - lib/irb/cmd/measure.rb
81
82
  - lib/irb/cmd/nop.rb
82
83
  - lib/irb/cmd/pushws.rb
84
+ - lib/irb/cmd/show_source.rb
83
85
  - lib/irb/cmd/subirb.rb
86
+ - lib/irb/cmd/whereami.rb
84
87
  - lib/irb/color.rb
85
88
  - lib/irb/color_printer.rb
86
89
  - lib/irb/completion.rb
@@ -137,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
140
  - !ruby/object:Gem::Version
138
141
  version: '0'
139
142
  requirements: []
140
- rubygems_version: 3.0.6
143
+ rubygems_version: 3.1.4
141
144
  signing_key:
142
145
  specification_version: 4
143
146
  summary: Interactive Ruby command-line tool for REPL (Read Eval Print Loop).