irb 1.3.4 → 1.3.5

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