irb 1.1.0.pre.3
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 +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/exe/irb +11 -0
- data/irb.gemspec +29 -0
- data/lib/irb.rb +855 -0
- data/lib/irb/cmd/chws.rb +34 -0
- data/lib/irb/cmd/fork.rb +39 -0
- data/lib/irb/cmd/help.rb +46 -0
- data/lib/irb/cmd/load.rb +67 -0
- data/lib/irb/cmd/nop.rb +39 -0
- data/lib/irb/cmd/pushws.rb +41 -0
- data/lib/irb/cmd/subirb.rb +43 -0
- data/lib/irb/color.rb +218 -0
- data/lib/irb/completion.rb +339 -0
- data/lib/irb/context.rb +459 -0
- data/lib/irb/ext/change-ws.rb +46 -0
- data/lib/irb/ext/history.rb +120 -0
- data/lib/irb/ext/loader.rb +129 -0
- data/lib/irb/ext/multi-irb.rb +265 -0
- data/lib/irb/ext/save-history.rb +117 -0
- data/lib/irb/ext/tracer.rb +72 -0
- data/lib/irb/ext/use-loader.rb +77 -0
- data/lib/irb/ext/workspaces.rb +67 -0
- data/lib/irb/extend-command.rb +328 -0
- data/lib/irb/frame.rb +81 -0
- data/lib/irb/help.rb +37 -0
- data/lib/irb/init.rb +312 -0
- data/lib/irb/input-method.rb +298 -0
- data/lib/irb/inspector.rb +142 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +32 -0
- data/lib/irb/lc/help-message +50 -0
- data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
- data/lib/irb/lc/ja/error.rb +31 -0
- data/lib/irb/lc/ja/help-message +52 -0
- data/lib/irb/locale.rb +182 -0
- data/lib/irb/magic-file.rb +38 -0
- data/lib/irb/notifier.rb +232 -0
- data/lib/irb/output-method.rb +92 -0
- data/lib/irb/ruby-lex.rb +492 -0
- data/lib/irb/ruby-token.rb +267 -0
- data/lib/irb/slex.rb +282 -0
- data/lib/irb/src_encoding.rb +7 -0
- data/lib/irb/version.rb +17 -0
- data/lib/irb/workspace.rb +190 -0
- data/lib/irb/ws-for-case-2.rb +15 -0
- data/lib/irb/xmp.rb +170 -0
- metadata +133 -0
@@ -0,0 +1,339 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/completion.rb -
|
4
|
+
# $Release Version: 0.9$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
7
|
+
# From Original Idea of shugo@ruby-lang.org
|
8
|
+
#
|
9
|
+
|
10
|
+
require "readline"
|
11
|
+
autoload :RDoc, "rdoc"
|
12
|
+
|
13
|
+
module IRB
|
14
|
+
module InputCompletor # :nodoc:
|
15
|
+
|
16
|
+
|
17
|
+
# Set of reserved words used by Ruby, you should not use these for
|
18
|
+
# constants or variables
|
19
|
+
ReservedWords = %w[
|
20
|
+
BEGIN END
|
21
|
+
alias and
|
22
|
+
begin break
|
23
|
+
case class
|
24
|
+
def defined do
|
25
|
+
else elsif end ensure
|
26
|
+
false for
|
27
|
+
if in
|
28
|
+
module
|
29
|
+
next nil not
|
30
|
+
or
|
31
|
+
redo rescue retry return
|
32
|
+
self super
|
33
|
+
then true
|
34
|
+
undef unless until
|
35
|
+
when while
|
36
|
+
yield
|
37
|
+
]
|
38
|
+
|
39
|
+
BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{("
|
40
|
+
|
41
|
+
CompletionProc = proc { |input|
|
42
|
+
retrieve_completion_data(input).compact.map{ |i| i.encode(Encoding.default_external) }
|
43
|
+
}
|
44
|
+
|
45
|
+
def self.retrieve_completion_data(input, doc_namespace = false)
|
46
|
+
bind = IRB.conf[:MAIN_CONTEXT].workspace.binding
|
47
|
+
|
48
|
+
case input
|
49
|
+
when /^((["'`]).*\2)\.([^.]*)$/
|
50
|
+
# String
|
51
|
+
receiver = $1
|
52
|
+
message = Regexp.quote($3)
|
53
|
+
|
54
|
+
candidates = String.instance_methods.collect{|m| m.to_s}
|
55
|
+
if doc_namespace
|
56
|
+
"String.#{message}"
|
57
|
+
else
|
58
|
+
select_message(receiver, message, candidates)
|
59
|
+
end
|
60
|
+
|
61
|
+
when /^(\/[^\/]*\/)\.([^.]*)$/
|
62
|
+
# Regexp
|
63
|
+
receiver = $1
|
64
|
+
message = Regexp.quote($2)
|
65
|
+
|
66
|
+
candidates = Regexp.instance_methods.collect{|m| m.to_s}
|
67
|
+
if doc_namespace
|
68
|
+
"Regexp.#{message}"
|
69
|
+
else
|
70
|
+
select_message(receiver, message, candidates)
|
71
|
+
end
|
72
|
+
|
73
|
+
when /^([^\]]*\])\.([^.]*)$/
|
74
|
+
# Array
|
75
|
+
receiver = $1
|
76
|
+
message = Regexp.quote($2)
|
77
|
+
|
78
|
+
candidates = Array.instance_methods.collect{|m| m.to_s}
|
79
|
+
if doc_namespace
|
80
|
+
"Array.#{message}"
|
81
|
+
else
|
82
|
+
select_message(receiver, message, candidates)
|
83
|
+
end
|
84
|
+
|
85
|
+
when /^([^\}]*\})\.([^.]*)$/
|
86
|
+
# Proc or Hash
|
87
|
+
receiver = $1
|
88
|
+
message = Regexp.quote($2)
|
89
|
+
|
90
|
+
proc_candidates = Proc.instance_methods.collect{|m| m.to_s}
|
91
|
+
hash_candidates = Hash.instance_methods.collect{|m| m.to_s}
|
92
|
+
if doc_namespace
|
93
|
+
["Proc.#{message}", "Hash.#{message}"]
|
94
|
+
else
|
95
|
+
select_message(receiver, message, proc_candidates | hash_candidates)
|
96
|
+
end
|
97
|
+
|
98
|
+
when /^(:[^:.]*)$/
|
99
|
+
# Symbol
|
100
|
+
return nil if doc_namespace
|
101
|
+
if Symbol.respond_to?(:all_symbols)
|
102
|
+
sym = $1
|
103
|
+
candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
|
104
|
+
candidates.grep(/^#{Regexp.quote(sym)}/)
|
105
|
+
else
|
106
|
+
[]
|
107
|
+
end
|
108
|
+
|
109
|
+
when /^::([A-Z][^:\.\(]*)$/
|
110
|
+
# Absolute Constant or class methods
|
111
|
+
receiver = $1
|
112
|
+
candidates = Object.constants.collect{|m| m.to_s}
|
113
|
+
if doc_namespace
|
114
|
+
candidates.find { |i| i == receiver }
|
115
|
+
else
|
116
|
+
candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
|
117
|
+
end
|
118
|
+
|
119
|
+
when /^([A-Z].*)::([^:.]*)$/
|
120
|
+
# Constant or class methods
|
121
|
+
receiver = $1
|
122
|
+
message = Regexp.quote($2)
|
123
|
+
begin
|
124
|
+
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
|
125
|
+
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
|
126
|
+
rescue Exception
|
127
|
+
candidates = []
|
128
|
+
end
|
129
|
+
if doc_namespace
|
130
|
+
"#{receiver}::#{message}"
|
131
|
+
else
|
132
|
+
select_message(receiver, message, candidates, "::")
|
133
|
+
end
|
134
|
+
|
135
|
+
when /^(:[^:.]+)(\.|::)([^.]*)$/
|
136
|
+
# Symbol
|
137
|
+
receiver = $1
|
138
|
+
sep = $2
|
139
|
+
message = Regexp.quote($3)
|
140
|
+
|
141
|
+
candidates = Symbol.instance_methods.collect{|m| m.to_s}
|
142
|
+
if doc_namespace
|
143
|
+
"Symbol.#{message}"
|
144
|
+
else
|
145
|
+
select_message(receiver, message, candidates, sep)
|
146
|
+
end
|
147
|
+
|
148
|
+
when /^(?<num>-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE][+-]?[0-9]+i?|r)?)(?<sep>\.|::)(?<mes>[^.]*)$/
|
149
|
+
# Numeric
|
150
|
+
receiver = $~[:num]
|
151
|
+
sep = $~[:sep]
|
152
|
+
message = Regexp.quote($~[:mes])
|
153
|
+
|
154
|
+
begin
|
155
|
+
instance = eval(receiver, bind)
|
156
|
+
if doc_namespace
|
157
|
+
"#{instance.class.name}.#{message}"
|
158
|
+
else
|
159
|
+
candidates = instance.methods.collect{|m| m.to_s}
|
160
|
+
select_message(receiver, message, candidates, sep)
|
161
|
+
end
|
162
|
+
rescue Exception
|
163
|
+
if doc_namespace
|
164
|
+
nil
|
165
|
+
else
|
166
|
+
candidates = []
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/
|
171
|
+
# Numeric(0xFFFF)
|
172
|
+
receiver = $1
|
173
|
+
sep = $2
|
174
|
+
message = Regexp.quote($3)
|
175
|
+
|
176
|
+
begin
|
177
|
+
instance = eval(receiver, bind)
|
178
|
+
if doc_namespace
|
179
|
+
"#{instance.class.name}.#{message}"
|
180
|
+
else
|
181
|
+
candidates = instance.methods.collect{|m| m.to_s}
|
182
|
+
select_message(receiver, message, candidates, sep)
|
183
|
+
end
|
184
|
+
rescue Exception
|
185
|
+
if doc_namespace
|
186
|
+
nil
|
187
|
+
else
|
188
|
+
candidates = []
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
when /^(\$[^.]*)$/
|
193
|
+
# global var
|
194
|
+
gvar = $1
|
195
|
+
all_gvars = global_variables.collect{|m| m.to_s}
|
196
|
+
if doc_namespace
|
197
|
+
all_gvars.find{ |i| i == gvar }
|
198
|
+
else
|
199
|
+
all_gvars.grep(Regexp.new(Regexp.quote(gvar)))
|
200
|
+
end
|
201
|
+
|
202
|
+
when /^([^."].*)(\.|::)([^.]*)$/
|
203
|
+
# variable.func or func.func
|
204
|
+
receiver = $1
|
205
|
+
sep = $2
|
206
|
+
message = Regexp.quote($3)
|
207
|
+
|
208
|
+
gv = eval("global_variables", bind).collect{|m| m.to_s}.append("true", "false", "nil")
|
209
|
+
lv = eval("local_variables", bind).collect{|m| m.to_s}
|
210
|
+
iv = eval("instance_variables", bind).collect{|m| m.to_s}
|
211
|
+
cv = eval("self.class.constants", bind).collect{|m| m.to_s}
|
212
|
+
|
213
|
+
if (gv | lv | iv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
|
214
|
+
# foo.func and foo is var. OR
|
215
|
+
# foo::func and foo is var. OR
|
216
|
+
# foo::Const and foo is var. OR
|
217
|
+
# Foo::Bar.func
|
218
|
+
begin
|
219
|
+
candidates = []
|
220
|
+
rec = eval(receiver, bind)
|
221
|
+
if sep == "::" and rec.kind_of?(Module)
|
222
|
+
candidates = rec.constants.collect{|m| m.to_s}
|
223
|
+
end
|
224
|
+
candidates |= rec.methods.collect{|m| m.to_s}
|
225
|
+
rescue Exception
|
226
|
+
candidates = []
|
227
|
+
end
|
228
|
+
else
|
229
|
+
# func1.func2
|
230
|
+
candidates = []
|
231
|
+
to_ignore = ignored_modules
|
232
|
+
ObjectSpace.each_object(Module){|m|
|
233
|
+
next if (to_ignore.include?(m) rescue true)
|
234
|
+
candidates.concat m.instance_methods(false).collect{|x| x.to_s}
|
235
|
+
}
|
236
|
+
candidates.sort!
|
237
|
+
candidates.uniq!
|
238
|
+
end
|
239
|
+
if doc_namespace
|
240
|
+
"#{rec.class.name}#{sep}#{candidates.find{ |i| i == message }}"
|
241
|
+
else
|
242
|
+
select_message(receiver, message, candidates, sep)
|
243
|
+
end
|
244
|
+
|
245
|
+
when /^\.([^.]*)$/
|
246
|
+
# unknown(maybe String)
|
247
|
+
|
248
|
+
receiver = ""
|
249
|
+
message = Regexp.quote($1)
|
250
|
+
|
251
|
+
candidates = String.instance_methods(true).collect{|m| m.to_s}
|
252
|
+
if doc_namespace
|
253
|
+
"String.#{candidates.find{ |i| i == message }}"
|
254
|
+
else
|
255
|
+
select_message(receiver, message, candidates)
|
256
|
+
end
|
257
|
+
|
258
|
+
else
|
259
|
+
candidates = eval("methods | private_methods | local_variables | instance_variables | self.class.constants", bind).collect{|m| m.to_s}
|
260
|
+
conditions |= ReservedWords
|
261
|
+
|
262
|
+
if doc_namespace
|
263
|
+
candidates.find{ |i| i == input }
|
264
|
+
else
|
265
|
+
candidates.grep(/^#{Regexp.quote(input)}/)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
PerfectMatchedProc = ->(matched) {
|
271
|
+
RDocRIDriver ||= RDoc::RI::Driver.new
|
272
|
+
if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER']
|
273
|
+
File.open(File.join(__dir__, 'ruby_logo.aa')) do |f|
|
274
|
+
RDocRIDriver.page do |io|
|
275
|
+
IO.copy_stream(f, io)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
return
|
279
|
+
end
|
280
|
+
namespace = retrieve_completion_data(matched, true)
|
281
|
+
return unless matched
|
282
|
+
if namespace.is_a?(Array)
|
283
|
+
out = RDoc::Markup::Document.new
|
284
|
+
namespace.each do |m|
|
285
|
+
begin
|
286
|
+
RDocRIDriver.add_method(out, m)
|
287
|
+
rescue RDoc::RI::Driver::NotFoundError
|
288
|
+
end
|
289
|
+
end
|
290
|
+
RDocRIDriver.display(out)
|
291
|
+
else
|
292
|
+
begin
|
293
|
+
RDocRIDriver.display_names([namespace])
|
294
|
+
rescue RDoc::RI::Driver::NotFoundError
|
295
|
+
end
|
296
|
+
end
|
297
|
+
}
|
298
|
+
|
299
|
+
# Set of available operators in Ruby
|
300
|
+
Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~]
|
301
|
+
|
302
|
+
def self.select_message(receiver, message, candidates, sep = ".")
|
303
|
+
candidates.grep(/^#{message}/).collect do |e|
|
304
|
+
case e
|
305
|
+
when /^[a-zA-Z_]/
|
306
|
+
receiver + sep + e
|
307
|
+
when /^[0-9]/
|
308
|
+
when *Operators
|
309
|
+
#receiver + " " + e
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def self.ignored_modules
|
315
|
+
# We could cache the result, but this is very fast already.
|
316
|
+
# By using this approach, we avoid Module#name calls, which are
|
317
|
+
# relatively slow when there are a lot of anonymous modules defined.
|
318
|
+
s = {}
|
319
|
+
|
320
|
+
scanner = lambda do |m|
|
321
|
+
next if s.include?(m) # IRB::ExtendCommandBundle::EXCB recurses.
|
322
|
+
s[m] = true
|
323
|
+
m.constants(false).each do |c|
|
324
|
+
value = m.const_get(c)
|
325
|
+
scanner.call(value) if value.is_a?(Module)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
%i(IRB SLex RubyLex RubyToken).each do |sym|
|
330
|
+
next unless Object.const_defined?(sym)
|
331
|
+
scanner.call(Object.const_get(sym))
|
332
|
+
end
|
333
|
+
|
334
|
+
s.delete(IRB::Context) if defined?(IRB::Context)
|
335
|
+
|
336
|
+
s
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
data/lib/irb/context.rb
ADDED
@@ -0,0 +1,459 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/context.rb - irb context
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
require_relative "workspace"
|
13
|
+
require_relative "inspector"
|
14
|
+
require_relative "input-method"
|
15
|
+
require_relative "output-method"
|
16
|
+
|
17
|
+
module IRB
|
18
|
+
# A class that wraps the current state of the irb session, including the
|
19
|
+
# configuration of IRB.conf.
|
20
|
+
class Context
|
21
|
+
# Creates a new IRB context.
|
22
|
+
#
|
23
|
+
# The optional +input_method+ argument:
|
24
|
+
#
|
25
|
+
# +nil+:: uses stdin or Reidline or Readline
|
26
|
+
# +String+:: uses a File
|
27
|
+
# +other+:: uses this as InputMethod
|
28
|
+
def initialize(irb, workspace = nil, input_method = nil, output_method = nil)
|
29
|
+
@irb = irb
|
30
|
+
if workspace
|
31
|
+
@workspace = workspace
|
32
|
+
else
|
33
|
+
@workspace = WorkSpace.new
|
34
|
+
end
|
35
|
+
@thread = Thread.current if defined? Thread
|
36
|
+
|
37
|
+
# copy of default configuration
|
38
|
+
@ap_name = IRB.conf[:AP_NAME]
|
39
|
+
@rc = IRB.conf[:RC]
|
40
|
+
@load_modules = IRB.conf[:LOAD_MODULES]
|
41
|
+
|
42
|
+
@use_readline = IRB.conf[:USE_READLINE]
|
43
|
+
@use_reidline = IRB.conf[:USE_REIDLINE]
|
44
|
+
@use_colorize = IRB.conf[:USE_COLORIZE]
|
45
|
+
@verbose = IRB.conf[:VERBOSE]
|
46
|
+
@io = nil
|
47
|
+
|
48
|
+
self.inspect_mode = IRB.conf[:INSPECT_MODE]
|
49
|
+
self.use_tracer = IRB.conf[:USE_TRACER] if IRB.conf[:USE_TRACER]
|
50
|
+
self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER]
|
51
|
+
self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY]
|
52
|
+
|
53
|
+
@ignore_sigint = IRB.conf[:IGNORE_SIGINT]
|
54
|
+
@ignore_eof = IRB.conf[:IGNORE_EOF]
|
55
|
+
|
56
|
+
@back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT]
|
57
|
+
|
58
|
+
self.prompt_mode = IRB.conf[:PROMPT_MODE]
|
59
|
+
|
60
|
+
if IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager)
|
61
|
+
@irb_name = IRB.conf[:IRB_NAME]
|
62
|
+
else
|
63
|
+
@irb_name = IRB.conf[:IRB_NAME]+"#"+IRB.JobManager.n_jobs.to_s
|
64
|
+
end
|
65
|
+
@irb_path = "(" + @irb_name + ")"
|
66
|
+
|
67
|
+
case input_method
|
68
|
+
when nil
|
69
|
+
@io = nil
|
70
|
+
case use_reidline?
|
71
|
+
when nil
|
72
|
+
if STDIN.tty? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_readline?
|
73
|
+
@io = ReidlineInputMethod.new
|
74
|
+
else
|
75
|
+
@io = nil
|
76
|
+
end
|
77
|
+
when false
|
78
|
+
@io = nil
|
79
|
+
when true
|
80
|
+
@io = ReidlineInputMethod.new
|
81
|
+
end
|
82
|
+
unless @io
|
83
|
+
case use_readline?
|
84
|
+
when nil
|
85
|
+
if (defined?(ReadlineInputMethod) && STDIN.tty? &&
|
86
|
+
IRB.conf[:PROMPT_MODE] != :INF_RUBY)
|
87
|
+
@io = ReadlineInputMethod.new
|
88
|
+
else
|
89
|
+
@io = nil
|
90
|
+
end
|
91
|
+
when false
|
92
|
+
@io = nil
|
93
|
+
when true
|
94
|
+
if defined?(ReadlineInputMethod)
|
95
|
+
@io = ReadlineInputMethod.new
|
96
|
+
else
|
97
|
+
@io = nil
|
98
|
+
end
|
99
|
+
else
|
100
|
+
@io = nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
@io = StdioInputMethod.new unless @io
|
104
|
+
|
105
|
+
when String
|
106
|
+
@io = FileInputMethod.new(input_method)
|
107
|
+
@irb_name = File.basename(input_method)
|
108
|
+
@irb_path = input_method
|
109
|
+
else
|
110
|
+
@io = input_method
|
111
|
+
end
|
112
|
+
self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
|
113
|
+
|
114
|
+
if output_method
|
115
|
+
@output_method = output_method
|
116
|
+
else
|
117
|
+
@output_method = StdioOutputMethod.new
|
118
|
+
end
|
119
|
+
|
120
|
+
@echo = IRB.conf[:ECHO]
|
121
|
+
if @echo.nil?
|
122
|
+
@echo = true
|
123
|
+
end
|
124
|
+
|
125
|
+
@echo_on_assignment = IRB.conf[:ECHO_ON_ASSIGNMENT]
|
126
|
+
if @echo_on_assignment.nil?
|
127
|
+
@echo_on_assignment = false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# The top-level workspace, see WorkSpace#main
|
132
|
+
def main
|
133
|
+
@workspace.main
|
134
|
+
end
|
135
|
+
|
136
|
+
# The toplevel workspace, see #home_workspace
|
137
|
+
attr_reader :workspace_home
|
138
|
+
# WorkSpace in the current context
|
139
|
+
attr_accessor :workspace
|
140
|
+
# The current thread in this context
|
141
|
+
attr_reader :thread
|
142
|
+
# The current input method
|
143
|
+
#
|
144
|
+
# Can be either StdioInputMethod, ReadlineInputMethod,
|
145
|
+
# ReidlineInputMethod, FileInputMethod or other specified when the
|
146
|
+
# context is created. See ::new for more # information on +input_method+.
|
147
|
+
attr_accessor :io
|
148
|
+
|
149
|
+
# Current irb session
|
150
|
+
attr_accessor :irb
|
151
|
+
# A copy of the default <code>IRB.conf[:AP_NAME]</code>
|
152
|
+
attr_accessor :ap_name
|
153
|
+
# A copy of the default <code>IRB.conf[:RC]</code>
|
154
|
+
attr_accessor :rc
|
155
|
+
# A copy of the default <code>IRB.conf[:LOAD_MODULES]</code>
|
156
|
+
attr_accessor :load_modules
|
157
|
+
# Can be either name from <code>IRB.conf[:IRB_NAME]</code>, or the number of
|
158
|
+
# the current job set by JobManager, such as <code>irb#2</code>
|
159
|
+
attr_accessor :irb_name
|
160
|
+
# Can be either the #irb_name surrounded by parenthesis, or the
|
161
|
+
# +input_method+ passed to Context.new
|
162
|
+
attr_accessor :irb_path
|
163
|
+
|
164
|
+
# Whether +Reidline+ is enabled or not.
|
165
|
+
#
|
166
|
+
# A copy of the default <code>IRB.conf[:USE_REIDLINE]</code>
|
167
|
+
#
|
168
|
+
# See #use_reidline= for more information.
|
169
|
+
attr_reader :use_reidline
|
170
|
+
# Whether +Readline+ is enabled or not.
|
171
|
+
#
|
172
|
+
# A copy of the default <code>IRB.conf[:USE_READLINE]</code>
|
173
|
+
#
|
174
|
+
# See #use_readline= for more information.
|
175
|
+
attr_reader :use_readline
|
176
|
+
# Whether colorization is enabled or not.
|
177
|
+
#
|
178
|
+
# A copy of the default <code>IRB.conf[:USE_COLORIZE]</code>
|
179
|
+
attr_reader :use_colorize
|
180
|
+
# A copy of the default <code>IRB.conf[:INSPECT_MODE]</code>
|
181
|
+
attr_reader :inspect_mode
|
182
|
+
|
183
|
+
# A copy of the default <code>IRB.conf[:PROMPT_MODE]</code>
|
184
|
+
attr_reader :prompt_mode
|
185
|
+
# Standard IRB prompt
|
186
|
+
#
|
187
|
+
# See IRB@Customizing+the+IRB+Prompt for more information.
|
188
|
+
attr_accessor :prompt_i
|
189
|
+
# IRB prompt for continuated strings
|
190
|
+
#
|
191
|
+
# See IRB@Customizing+the+IRB+Prompt for more information.
|
192
|
+
attr_accessor :prompt_s
|
193
|
+
# IRB prompt for continuated statement (e.g. immediately after an +if+)
|
194
|
+
#
|
195
|
+
# See IRB@Customizing+the+IRB+Prompt for more information.
|
196
|
+
attr_accessor :prompt_c
|
197
|
+
# See IRB@Customizing+the+IRB+Prompt for more information.
|
198
|
+
attr_accessor :prompt_n
|
199
|
+
# Can be either the default <code>IRB.conf[:AUTO_INDENT]</code>, or the
|
200
|
+
# mode set by #prompt_mode=
|
201
|
+
#
|
202
|
+
# To disable auto-indentation in irb:
|
203
|
+
#
|
204
|
+
# IRB.conf[:AUTO_INDENT] = false
|
205
|
+
#
|
206
|
+
# or
|
207
|
+
#
|
208
|
+
# irb_context.auto_indent_mode = false
|
209
|
+
#
|
210
|
+
# or
|
211
|
+
#
|
212
|
+
# IRB.CurrentContext.auto_indent_mode = false
|
213
|
+
#
|
214
|
+
# See IRB@Configuration for more information.
|
215
|
+
attr_accessor :auto_indent_mode
|
216
|
+
# The format of the return statement, set by #prompt_mode= using the
|
217
|
+
# +:RETURN+ of the +mode+ passed to set the current #prompt_mode.
|
218
|
+
attr_accessor :return_format
|
219
|
+
|
220
|
+
# Whether <code>^C</code> (+control-c+) will be ignored or not.
|
221
|
+
#
|
222
|
+
# If set to +false+, <code>^C</code> will quit irb.
|
223
|
+
#
|
224
|
+
# If set to +true+,
|
225
|
+
#
|
226
|
+
# * during input: cancel input then return to top level.
|
227
|
+
# * during execute: abandon current execution.
|
228
|
+
attr_accessor :ignore_sigint
|
229
|
+
# Whether <code>^D</code> (+control-d+) will be ignored or not.
|
230
|
+
#
|
231
|
+
# If set to +false+, <code>^D</code> will quit irb.
|
232
|
+
attr_accessor :ignore_eof
|
233
|
+
# Whether to echo the return value to output or not.
|
234
|
+
#
|
235
|
+
# Uses IRB.conf[:ECHO] if available, or defaults to +true+.
|
236
|
+
#
|
237
|
+
# puts "hello"
|
238
|
+
# # hello
|
239
|
+
# #=> nil
|
240
|
+
# IRB.CurrentContext.echo = false
|
241
|
+
# puts "omg"
|
242
|
+
# # omg
|
243
|
+
attr_accessor :echo
|
244
|
+
# Whether to echo for assignment expressions
|
245
|
+
#
|
246
|
+
# Uses IRB.conf[:ECHO_ON_ASSIGNMENT] if available, or defaults to +false+.
|
247
|
+
#
|
248
|
+
# a = "omg"
|
249
|
+
# IRB.CurrentContext.echo_on_assignment = true
|
250
|
+
# a = "omg"
|
251
|
+
# #=> omg
|
252
|
+
attr_accessor :echo_on_assignment
|
253
|
+
# Whether verbose messages are displayed or not.
|
254
|
+
#
|
255
|
+
# A copy of the default <code>IRB.conf[:VERBOSE]</code>
|
256
|
+
attr_accessor :verbose
|
257
|
+
|
258
|
+
# The limit of backtrace lines displayed as top +n+ and tail +n+.
|
259
|
+
#
|
260
|
+
# The default value is 16.
|
261
|
+
#
|
262
|
+
# Can also be set using the +--back-trace-limit+ command line option.
|
263
|
+
#
|
264
|
+
# See IRB@Command+line+options for more command line options.
|
265
|
+
attr_accessor :back_trace_limit
|
266
|
+
|
267
|
+
# Alias for #use_reidline
|
268
|
+
alias use_reidline? use_reidline
|
269
|
+
# Alias for #use_readline
|
270
|
+
alias use_readline? use_readline
|
271
|
+
# Alias for #use_colorize
|
272
|
+
alias use_colorize? use_colorize
|
273
|
+
# Alias for #rc
|
274
|
+
alias rc? rc
|
275
|
+
alias ignore_sigint? ignore_sigint
|
276
|
+
alias ignore_eof? ignore_eof
|
277
|
+
alias echo? echo
|
278
|
+
alias echo_on_assignment? echo_on_assignment
|
279
|
+
|
280
|
+
# Returns whether messages are displayed or not.
|
281
|
+
def verbose?
|
282
|
+
if @verbose.nil?
|
283
|
+
if @io.kind_of?(ReidlineInputMethod)
|
284
|
+
false
|
285
|
+
elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)
|
286
|
+
false
|
287
|
+
elsif !STDIN.tty? or @io.kind_of?(FileInputMethod)
|
288
|
+
true
|
289
|
+
else
|
290
|
+
false
|
291
|
+
end
|
292
|
+
else
|
293
|
+
@verbose
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Whether #verbose? is +true+, and +input_method+ is either
|
298
|
+
# StdioInputMethod or ReidlineInputMethod or ReadlineInputMethod, see #io
|
299
|
+
# for more information.
|
300
|
+
def prompting?
|
301
|
+
verbose? || (STDIN.tty? && @io.kind_of?(StdioInputMethod) ||
|
302
|
+
@io.kind_of?(ReidlineInputMethod) ||
|
303
|
+
(defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod)))
|
304
|
+
end
|
305
|
+
|
306
|
+
# The return value of the last statement evaluated.
|
307
|
+
attr_reader :last_value
|
308
|
+
|
309
|
+
# Sets the return value from the last statement evaluated in this context
|
310
|
+
# to #last_value.
|
311
|
+
def set_last_value(value)
|
312
|
+
@last_value = value
|
313
|
+
@workspace.local_variable_set :_, value
|
314
|
+
end
|
315
|
+
|
316
|
+
# Sets the +mode+ of the prompt in this context.
|
317
|
+
#
|
318
|
+
# See IRB@Customizing+the+IRB+Prompt for more information.
|
319
|
+
def prompt_mode=(mode)
|
320
|
+
@prompt_mode = mode
|
321
|
+
pconf = IRB.conf[:PROMPT][mode]
|
322
|
+
@prompt_i = pconf[:PROMPT_I]
|
323
|
+
@prompt_s = pconf[:PROMPT_S]
|
324
|
+
@prompt_c = pconf[:PROMPT_C]
|
325
|
+
@prompt_n = pconf[:PROMPT_N]
|
326
|
+
@return_format = pconf[:RETURN]
|
327
|
+
if ai = pconf.include?(:AUTO_INDENT)
|
328
|
+
@auto_indent_mode = ai
|
329
|
+
else
|
330
|
+
@auto_indent_mode = IRB.conf[:AUTO_INDENT]
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# Whether #inspect_mode is set or not, see #inspect_mode= for more detail.
|
335
|
+
def inspect?
|
336
|
+
@inspect_mode.nil? or @inspect_mode
|
337
|
+
end
|
338
|
+
|
339
|
+
# Whether #io uses a File for the +input_method+ passed when creating the
|
340
|
+
# current context, see ::new
|
341
|
+
def file_input?
|
342
|
+
@io.class == FileInputMethod
|
343
|
+
end
|
344
|
+
|
345
|
+
# Specifies the inspect mode with +opt+:
|
346
|
+
#
|
347
|
+
# +true+:: display +inspect+
|
348
|
+
# +false+:: display +to_s+
|
349
|
+
# +nil+:: inspect mode in non-math mode,
|
350
|
+
# non-inspect mode in math mode
|
351
|
+
#
|
352
|
+
# See IRB::Inspector for more information.
|
353
|
+
#
|
354
|
+
# Can also be set using the +--inspect+ and +--noinspect+ command line
|
355
|
+
# options.
|
356
|
+
#
|
357
|
+
# See IRB@Command+line+options for more command line options.
|
358
|
+
def inspect_mode=(opt)
|
359
|
+
|
360
|
+
if i = Inspector::INSPECTORS[opt]
|
361
|
+
@inspect_mode = opt
|
362
|
+
@inspect_method = i
|
363
|
+
i.init
|
364
|
+
else
|
365
|
+
case opt
|
366
|
+
when nil
|
367
|
+
if Inspector.keys_with_inspector(Inspector::INSPECTORS[true]).include?(@inspect_mode)
|
368
|
+
self.inspect_mode = false
|
369
|
+
elsif Inspector.keys_with_inspector(Inspector::INSPECTORS[false]).include?(@inspect_mode)
|
370
|
+
self.inspect_mode = true
|
371
|
+
else
|
372
|
+
puts "Can't switch inspect mode."
|
373
|
+
return
|
374
|
+
end
|
375
|
+
when /^\s*\{.*\}\s*$/
|
376
|
+
begin
|
377
|
+
inspector = eval "proc#{opt}"
|
378
|
+
rescue Exception
|
379
|
+
puts "Can't switch inspect mode(#{opt})."
|
380
|
+
return
|
381
|
+
end
|
382
|
+
self.inspect_mode = inspector
|
383
|
+
when Proc
|
384
|
+
self.inspect_mode = IRB::Inspector(opt)
|
385
|
+
when Inspector
|
386
|
+
prefix = "usr%d"
|
387
|
+
i = 1
|
388
|
+
while Inspector::INSPECTORS[format(prefix, i)]; i += 1; end
|
389
|
+
@inspect_mode = format(prefix, i)
|
390
|
+
@inspect_method = opt
|
391
|
+
Inspector.def_inspector(format(prefix, i), @inspect_method)
|
392
|
+
else
|
393
|
+
puts "Can't switch inspect mode(#{opt})."
|
394
|
+
return
|
395
|
+
end
|
396
|
+
end
|
397
|
+
print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose?
|
398
|
+
@inspect_mode
|
399
|
+
end
|
400
|
+
|
401
|
+
# Obsolete method.
|
402
|
+
#
|
403
|
+
# Can be set using the +--noreadline+ and +--readline+ command line
|
404
|
+
# options.
|
405
|
+
#
|
406
|
+
# See IRB@Command+line+options for more command line options.
|
407
|
+
def use_readline=(opt)
|
408
|
+
print "This method is obsolete."
|
409
|
+
print "Do nothing."
|
410
|
+
end
|
411
|
+
|
412
|
+
def evaluate(line, line_no, exception: nil) # :nodoc:
|
413
|
+
@line_no = line_no
|
414
|
+
if exception
|
415
|
+
line_no -= 1
|
416
|
+
line = "begin ::Kernel.raise _; rescue _.class\n#{line}\n""end"
|
417
|
+
@workspace.local_variable_set(:_, exception)
|
418
|
+
end
|
419
|
+
set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
|
420
|
+
end
|
421
|
+
|
422
|
+
def inspect_last_value # :nodoc:
|
423
|
+
@inspect_method.inspect_value(@last_value)
|
424
|
+
end
|
425
|
+
|
426
|
+
alias __exit__ exit
|
427
|
+
# Exits the current session, see IRB.irb_exit
|
428
|
+
def exit(ret = 0)
|
429
|
+
IRB.irb_exit(@irb, ret)
|
430
|
+
end
|
431
|
+
|
432
|
+
NOPRINTING_IVARS = ["@last_value"] # :nodoc:
|
433
|
+
NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc:
|
434
|
+
IDNAME_IVARS = ["@prompt_mode"] # :nodoc:
|
435
|
+
|
436
|
+
alias __inspect__ inspect
|
437
|
+
def inspect # :nodoc:
|
438
|
+
array = []
|
439
|
+
for ivar in instance_variables.sort{|e1, e2| e1 <=> e2}
|
440
|
+
ivar = ivar.to_s
|
441
|
+
name = ivar.sub(/^@(.*)$/, '\1')
|
442
|
+
val = instance_eval(ivar)
|
443
|
+
case ivar
|
444
|
+
when *NOPRINTING_IVARS
|
445
|
+
array.push format("conf.%s=%s", name, "...")
|
446
|
+
when *NO_INSPECTING_IVARS
|
447
|
+
array.push format("conf.%s=%s", name, val.to_s)
|
448
|
+
when *IDNAME_IVARS
|
449
|
+
array.push format("conf.%s=:%s", name, val.id2name)
|
450
|
+
else
|
451
|
+
array.push format("conf.%s=%s", name, val.inspect)
|
452
|
+
end
|
453
|
+
end
|
454
|
+
array.join("\n")
|
455
|
+
end
|
456
|
+
alias __to_s__ to_s
|
457
|
+
alias to_s inspect
|
458
|
+
end
|
459
|
+
end
|