irb 1.0.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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +10 -0
- data/bin/console +6 -0
- data/bin/setup +6 -0
- data/exe/irb +11 -0
- data/irb.gemspec +26 -0
- data/lib/irb.rb +798 -0
- data/lib/irb/cmd/chws.rb +34 -0
- data/lib/irb/cmd/fork.rb +39 -0
- data/lib/irb/cmd/help.rb +42 -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/completion.rb +244 -0
- data/lib/irb/context.rb +425 -0
- data/lib/irb/ext/change-ws.rb +46 -0
- data/lib/irb/ext/history.rb +119 -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 +105 -0
- data/lib/irb/ext/tracer.rb +72 -0
- data/lib/irb/ext/use-loader.rb +74 -0
- data/lib/irb/ext/workspaces.rb +67 -0
- data/lib/irb/extend-command.rb +306 -0
- data/lib/irb/frame.rb +81 -0
- data/lib/irb/help.rb +37 -0
- data/lib/irb/init.rb +302 -0
- data/lib/irb/input-method.rb +192 -0
- data/lib/irb/inspector.rb +132 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +32 -0
- data/lib/irb/lc/help-message +49 -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 +1180 -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 +143 -0
- data/lib/irb/ws-for-case-2.rb +15 -0
- data/lib/irb/xmp.rb +170 -0
- metadata +125 -0
data/lib/irb/frame.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# frame.rb -
|
4
|
+
# $Release Version: 0.9$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require "e2mmap"
|
14
|
+
|
15
|
+
module IRB
|
16
|
+
class Frame
|
17
|
+
extend Exception2MessageMapper
|
18
|
+
def_exception :FrameOverflow, "frame overflow"
|
19
|
+
def_exception :FrameUnderflow, "frame underflow"
|
20
|
+
|
21
|
+
# Default number of stack frames
|
22
|
+
INIT_STACK_TIMES = 3
|
23
|
+
# Default number of frames offset
|
24
|
+
CALL_STACK_OFFSET = 3
|
25
|
+
|
26
|
+
# Creates a new stack frame
|
27
|
+
def initialize
|
28
|
+
@frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES
|
29
|
+
end
|
30
|
+
|
31
|
+
# Used by Kernel#set_trace_func to register each event in the call stack
|
32
|
+
def trace_func(event, file, line, id, binding)
|
33
|
+
case event
|
34
|
+
when 'call', 'class'
|
35
|
+
@frames.push binding
|
36
|
+
when 'return', 'end'
|
37
|
+
@frames.pop
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the +n+ number of frames on the call stack from the last frame
|
42
|
+
# initialized.
|
43
|
+
#
|
44
|
+
# Raises FrameUnderflow if there are no frames in the given stack range.
|
45
|
+
def top(n = 0)
|
46
|
+
bind = @frames[-(n + CALL_STACK_OFFSET)]
|
47
|
+
Fail FrameUnderflow unless bind
|
48
|
+
bind
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the +n+ number of frames on the call stack from the first frame
|
52
|
+
# initialized.
|
53
|
+
#
|
54
|
+
# Raises FrameOverflow if there are no frames in the given stack range.
|
55
|
+
def bottom(n = 0)
|
56
|
+
bind = @frames[n]
|
57
|
+
Fail FrameOverflow unless bind
|
58
|
+
bind
|
59
|
+
end
|
60
|
+
|
61
|
+
# Convenience method for Frame#bottom
|
62
|
+
def Frame.bottom(n = 0)
|
63
|
+
@backtrace.bottom(n)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Convenience method for Frame#top
|
67
|
+
def Frame.top(n = 0)
|
68
|
+
@backtrace.top(n)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the binding context of the caller from the last frame initialized
|
72
|
+
def Frame.sender
|
73
|
+
eval "self", @backtrace.top
|
74
|
+
end
|
75
|
+
|
76
|
+
@backtrace = Frame.new
|
77
|
+
set_trace_func proc{|event, file, line, id, binding, klass|
|
78
|
+
@backtrace.trace_func(event, file, line, id, binding)
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end
|
data/lib/irb/help.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/help.rb - print usage module
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
require_relative 'magic-file'
|
14
|
+
|
15
|
+
module IRB
|
16
|
+
# Outputs the irb help message, see IRB@Command+line+options.
|
17
|
+
def IRB.print_usage
|
18
|
+
lc = IRB.conf[:LC_MESSAGES]
|
19
|
+
path = lc.find("irb/help-message")
|
20
|
+
space_line = false
|
21
|
+
IRB::MagicFile.open(path){|f|
|
22
|
+
f.each_line do |l|
|
23
|
+
if /^\s*$/ =~ l
|
24
|
+
lc.puts l unless space_line
|
25
|
+
space_line = true
|
26
|
+
next
|
27
|
+
end
|
28
|
+
space_line = false
|
29
|
+
|
30
|
+
l.sub!(/#.*$/, "")
|
31
|
+
next if /^\s*$/ =~ l
|
32
|
+
lc.puts l
|
33
|
+
end
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/lib/irb/init.rb
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/init.rb - irb initialize module
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
module IRB # :nodoc:
|
14
|
+
|
15
|
+
# initialize config
|
16
|
+
def IRB.setup(ap_path, argv: ::ARGV)
|
17
|
+
IRB.init_config(ap_path)
|
18
|
+
IRB.init_error
|
19
|
+
IRB.parse_opts(argv: argv)
|
20
|
+
IRB.run_config
|
21
|
+
IRB.load_modules
|
22
|
+
|
23
|
+
unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
|
24
|
+
IRB.fail(UndefinedPromptMode, @CONF[:PROMPT_MODE])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @CONF default setting
|
29
|
+
def IRB.init_config(ap_path)
|
30
|
+
# class instance variables
|
31
|
+
@TRACER_INITIALIZED = false
|
32
|
+
|
33
|
+
# default configurations
|
34
|
+
unless ap_path and @CONF[:AP_NAME]
|
35
|
+
ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
|
36
|
+
end
|
37
|
+
@CONF[:AP_NAME] = File::basename(ap_path, ".rb")
|
38
|
+
|
39
|
+
@CONF[:IRB_NAME] = "irb"
|
40
|
+
@CONF[:IRB_LIB_PATH] = File.dirname(__FILE__)
|
41
|
+
|
42
|
+
@CONF[:RC] = true
|
43
|
+
@CONF[:LOAD_MODULES] = []
|
44
|
+
@CONF[:IRB_RC] = nil
|
45
|
+
|
46
|
+
@CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)
|
47
|
+
@CONF[:INSPECT_MODE] = true
|
48
|
+
@CONF[:USE_TRACER] = false
|
49
|
+
@CONF[:USE_LOADER] = false
|
50
|
+
@CONF[:IGNORE_SIGINT] = true
|
51
|
+
@CONF[:IGNORE_EOF] = false
|
52
|
+
@CONF[:ECHO] = nil
|
53
|
+
@CONF[:VERBOSE] = nil
|
54
|
+
|
55
|
+
@CONF[:EVAL_HISTORY] = nil
|
56
|
+
@CONF[:SAVE_HISTORY] = nil
|
57
|
+
|
58
|
+
@CONF[:BACK_TRACE_LIMIT] = 16
|
59
|
+
|
60
|
+
@CONF[:PROMPT] = {
|
61
|
+
:NULL => {
|
62
|
+
:PROMPT_I => nil,
|
63
|
+
:PROMPT_N => nil,
|
64
|
+
:PROMPT_S => nil,
|
65
|
+
:PROMPT_C => nil,
|
66
|
+
:RETURN => "%s\n"
|
67
|
+
},
|
68
|
+
:DEFAULT => {
|
69
|
+
:PROMPT_I => "%N(%m):%03n:%i> ",
|
70
|
+
:PROMPT_N => "%N(%m):%03n:%i> ",
|
71
|
+
:PROMPT_S => "%N(%m):%03n:%i%l ",
|
72
|
+
:PROMPT_C => "%N(%m):%03n:%i* ",
|
73
|
+
:RETURN => "=> %s\n"
|
74
|
+
},
|
75
|
+
:CLASSIC => {
|
76
|
+
:PROMPT_I => "%N(%m):%03n:%i> ",
|
77
|
+
:PROMPT_N => "%N(%m):%03n:%i> ",
|
78
|
+
:PROMPT_S => "%N(%m):%03n:%i%l ",
|
79
|
+
:PROMPT_C => "%N(%m):%03n:%i* ",
|
80
|
+
:RETURN => "%s\n"
|
81
|
+
},
|
82
|
+
:SIMPLE => {
|
83
|
+
:PROMPT_I => ">> ",
|
84
|
+
:PROMPT_N => ">> ",
|
85
|
+
:PROMPT_S => nil,
|
86
|
+
:PROMPT_C => "?> ",
|
87
|
+
:RETURN => "=> %s\n"
|
88
|
+
},
|
89
|
+
:INF_RUBY => {
|
90
|
+
:PROMPT_I => "%N(%m):%03n:%i> ",
|
91
|
+
:PROMPT_N => nil,
|
92
|
+
:PROMPT_S => nil,
|
93
|
+
:PROMPT_C => nil,
|
94
|
+
:RETURN => "%s\n",
|
95
|
+
:AUTO_INDENT => true
|
96
|
+
},
|
97
|
+
:XMP => {
|
98
|
+
:PROMPT_I => nil,
|
99
|
+
:PROMPT_N => nil,
|
100
|
+
:PROMPT_S => nil,
|
101
|
+
:PROMPT_C => nil,
|
102
|
+
:RETURN => " ==>%s\n"
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
@CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
|
107
|
+
@CONF[:AUTO_INDENT] = false
|
108
|
+
|
109
|
+
@CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
|
110
|
+
@CONF[:SINGLE_IRB] = false
|
111
|
+
|
112
|
+
@CONF[:LC_MESSAGES] = Locale.new
|
113
|
+
|
114
|
+
@CONF[:AT_EXIT] = []
|
115
|
+
|
116
|
+
@CONF[:DEBUG_LEVEL] = 0
|
117
|
+
end
|
118
|
+
|
119
|
+
def IRB.init_error
|
120
|
+
@CONF[:LC_MESSAGES].load("irb/error.rb")
|
121
|
+
end
|
122
|
+
|
123
|
+
# option analyzing
|
124
|
+
def IRB.parse_opts(argv: ::ARGV)
|
125
|
+
load_path = []
|
126
|
+
while opt = argv.shift
|
127
|
+
case opt
|
128
|
+
when "-f"
|
129
|
+
@CONF[:RC] = false
|
130
|
+
when "-d"
|
131
|
+
$DEBUG = true
|
132
|
+
$VERBOSE = true
|
133
|
+
when "-w"
|
134
|
+
$VERBOSE = true
|
135
|
+
when /^-W(.+)?/
|
136
|
+
opt = $1 || argv.shift
|
137
|
+
case opt
|
138
|
+
when "0"
|
139
|
+
$VERBOSE = nil
|
140
|
+
when "1"
|
141
|
+
$VERBOSE = false
|
142
|
+
else
|
143
|
+
$VERBOSE = true
|
144
|
+
end
|
145
|
+
when /^-r(.+)?/
|
146
|
+
opt = $1 || argv.shift
|
147
|
+
@CONF[:LOAD_MODULES].push opt if opt
|
148
|
+
when /^-I(.+)?/
|
149
|
+
opt = $1 || argv.shift
|
150
|
+
load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt
|
151
|
+
when '-U'
|
152
|
+
set_encoding("UTF-8", "UTF-8")
|
153
|
+
when /^-E(.+)?/, /^--encoding(?:=(.+))?/
|
154
|
+
opt = $1 || argv.shift
|
155
|
+
set_encoding(*opt.split(':', 2))
|
156
|
+
when "--inspect"
|
157
|
+
if /^-/ !~ argv.first
|
158
|
+
@CONF[:INSPECT_MODE] = argv.shift
|
159
|
+
else
|
160
|
+
@CONF[:INSPECT_MODE] = true
|
161
|
+
end
|
162
|
+
when "--noinspect"
|
163
|
+
@CONF[:INSPECT_MODE] = false
|
164
|
+
when "--readline"
|
165
|
+
@CONF[:USE_READLINE] = true
|
166
|
+
when "--noreadline"
|
167
|
+
@CONF[:USE_READLINE] = false
|
168
|
+
when "--echo"
|
169
|
+
@CONF[:ECHO] = true
|
170
|
+
when "--noecho"
|
171
|
+
@CONF[:ECHO] = false
|
172
|
+
when "--verbose"
|
173
|
+
@CONF[:VERBOSE] = true
|
174
|
+
when "--noverbose"
|
175
|
+
@CONF[:VERBOSE] = false
|
176
|
+
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
|
177
|
+
opt = $1 || argv.shift
|
178
|
+
prompt_mode = opt.upcase.tr("-", "_").intern
|
179
|
+
@CONF[:PROMPT_MODE] = prompt_mode
|
180
|
+
when "--noprompt"
|
181
|
+
@CONF[:PROMPT_MODE] = :NULL
|
182
|
+
when "--inf-ruby-mode"
|
183
|
+
@CONF[:PROMPT_MODE] = :INF_RUBY
|
184
|
+
when "--sample-book-mode", "--simple-prompt"
|
185
|
+
@CONF[:PROMPT_MODE] = :SIMPLE
|
186
|
+
when "--tracer"
|
187
|
+
@CONF[:USE_TRACER] = true
|
188
|
+
when /^--back-trace-limit(?:=(.+))?/
|
189
|
+
@CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i
|
190
|
+
when /^--context-mode(?:=(.+))?/
|
191
|
+
@CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
|
192
|
+
when "--single-irb"
|
193
|
+
@CONF[:SINGLE_IRB] = true
|
194
|
+
when /^--irb_debug(?:=(.+))?/
|
195
|
+
@CONF[:DEBUG_LEVEL] = ($1 || argv.shift).to_i
|
196
|
+
when "-v", "--version"
|
197
|
+
print IRB.version, "\n"
|
198
|
+
exit 0
|
199
|
+
when "-h", "--help"
|
200
|
+
require_relative "help"
|
201
|
+
IRB.print_usage
|
202
|
+
exit 0
|
203
|
+
when "--"
|
204
|
+
if opt = argv.shift
|
205
|
+
@CONF[:SCRIPT] = opt
|
206
|
+
$0 = opt
|
207
|
+
end
|
208
|
+
break
|
209
|
+
when /^-/
|
210
|
+
IRB.fail UnrecognizedSwitch, opt
|
211
|
+
else
|
212
|
+
@CONF[:SCRIPT] = opt
|
213
|
+
$0 = opt
|
214
|
+
break
|
215
|
+
end
|
216
|
+
end
|
217
|
+
load_path.collect! do |path|
|
218
|
+
/\A\.\// =~ path ? path : File.expand_path(path)
|
219
|
+
end
|
220
|
+
$LOAD_PATH.unshift(*load_path)
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
# running config
|
225
|
+
def IRB.run_config
|
226
|
+
if @CONF[:RC]
|
227
|
+
begin
|
228
|
+
load rc_file
|
229
|
+
rescue LoadError, Errno::ENOENT
|
230
|
+
rescue # StandardError, ScriptError
|
231
|
+
print "load error: #{rc_file}\n"
|
232
|
+
print $!.class, ": ", $!, "\n"
|
233
|
+
for err in $@[0, $@.size - 2]
|
234
|
+
print "\t", err, "\n"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
IRBRC_EXT = "rc"
|
241
|
+
def IRB.rc_file(ext = IRBRC_EXT)
|
242
|
+
if !@CONF[:RC_NAME_GENERATOR]
|
243
|
+
rc_file_generators do |rcgen|
|
244
|
+
@CONF[:RC_NAME_GENERATOR] ||= rcgen
|
245
|
+
if File.exist?(rcgen.call(IRBRC_EXT))
|
246
|
+
@CONF[:RC_NAME_GENERATOR] = rcgen
|
247
|
+
break
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
|
252
|
+
when String
|
253
|
+
return rc_file
|
254
|
+
else
|
255
|
+
IRB.fail IllegalRCNameGenerator
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# enumerate possible rc-file base name generators
|
260
|
+
def IRB.rc_file_generators
|
261
|
+
if irbrc = ENV["IRBRC"]
|
262
|
+
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
|
263
|
+
end
|
264
|
+
if home = ENV["HOME"]
|
265
|
+
yield proc{|rc| home+"/.irb#{rc}"}
|
266
|
+
end
|
267
|
+
home = Dir.pwd
|
268
|
+
yield proc{|rc| home+"/.irb#{rc}"}
|
269
|
+
yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
|
270
|
+
yield proc{|rc| home+"/_irb#{rc}"}
|
271
|
+
yield proc{|rc| home+"/$irb#{rc}"}
|
272
|
+
end
|
273
|
+
|
274
|
+
# loading modules
|
275
|
+
def IRB.load_modules
|
276
|
+
for m in @CONF[:LOAD_MODULES]
|
277
|
+
begin
|
278
|
+
require m
|
279
|
+
rescue LoadError => err
|
280
|
+
warn "#{err.class}: #{err}", uplevel: 0
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
DefaultEncodings = Struct.new(:external, :internal)
|
287
|
+
class << IRB
|
288
|
+
private
|
289
|
+
def set_encoding(extern, intern = nil)
|
290
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
291
|
+
Encoding.default_external = extern unless extern.nil? || extern.empty?
|
292
|
+
Encoding.default_internal = intern unless intern.nil? || intern.empty?
|
293
|
+
@CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
|
294
|
+
[$stdin, $stdout, $stderr].each do |io|
|
295
|
+
io.set_encoding(extern, intern)
|
296
|
+
end
|
297
|
+
@CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
|
298
|
+
ensure
|
299
|
+
$VERBOSE = verbose
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/input-method.rb - input methods used irb
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
require_relative 'src_encoding'
|
13
|
+
require_relative 'magic-file'
|
14
|
+
|
15
|
+
module IRB
|
16
|
+
STDIN_FILE_NAME = "(line)" # :nodoc:
|
17
|
+
class InputMethod
|
18
|
+
|
19
|
+
# Creates a new input method object
|
20
|
+
def initialize(file = STDIN_FILE_NAME)
|
21
|
+
@file_name = file
|
22
|
+
end
|
23
|
+
# The file name of this input method, usually given during initialization.
|
24
|
+
attr_reader :file_name
|
25
|
+
|
26
|
+
# The irb prompt associated with this input method
|
27
|
+
attr_accessor :prompt
|
28
|
+
|
29
|
+
# Reads the next line from this input method.
|
30
|
+
#
|
31
|
+
# See IO#gets for more information.
|
32
|
+
def gets
|
33
|
+
IRB.fail NotImplementedError, "gets"
|
34
|
+
end
|
35
|
+
public :gets
|
36
|
+
|
37
|
+
# Whether this input method is still readable when there is no more data to
|
38
|
+
# read.
|
39
|
+
#
|
40
|
+
# See IO#eof for more information.
|
41
|
+
def readable_after_eof?
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class StdioInputMethod < InputMethod
|
47
|
+
# Creates a new input method object
|
48
|
+
def initialize
|
49
|
+
super
|
50
|
+
@line_no = 0
|
51
|
+
@line = []
|
52
|
+
@stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
53
|
+
@stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Reads the next line from this input method.
|
57
|
+
#
|
58
|
+
# See IO#gets for more information.
|
59
|
+
def gets
|
60
|
+
print @prompt
|
61
|
+
line = @stdin.gets
|
62
|
+
@line[@line_no += 1] = line
|
63
|
+
end
|
64
|
+
|
65
|
+
# Whether the end of this input method has been reached, returns +true+ if
|
66
|
+
# there is no more data to read.
|
67
|
+
#
|
68
|
+
# See IO#eof? for more information.
|
69
|
+
def eof?
|
70
|
+
@stdin.eof?
|
71
|
+
end
|
72
|
+
|
73
|
+
# Whether this input method is still readable when there is no more data to
|
74
|
+
# read.
|
75
|
+
#
|
76
|
+
# See IO#eof for more information.
|
77
|
+
def readable_after_eof?
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the current line number for #io.
|
82
|
+
#
|
83
|
+
# #line counts the number of times #gets is called.
|
84
|
+
#
|
85
|
+
# See IO#lineno for more information.
|
86
|
+
def line(line_no)
|
87
|
+
@line[line_no]
|
88
|
+
end
|
89
|
+
|
90
|
+
# The external encoding for standard input.
|
91
|
+
def encoding
|
92
|
+
@stdin.external_encoding
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Use a File for IO with irb, see InputMethod
|
97
|
+
class FileInputMethod < InputMethod
|
98
|
+
# Creates a new input method object
|
99
|
+
def initialize(file)
|
100
|
+
super
|
101
|
+
@io = IRB::MagicFile.open(file)
|
102
|
+
end
|
103
|
+
# The file name of this input method, usually given during initialization.
|
104
|
+
attr_reader :file_name
|
105
|
+
|
106
|
+
# Whether the end of this input method has been reached, returns +true+ if
|
107
|
+
# there is no more data to read.
|
108
|
+
#
|
109
|
+
# See IO#eof? for more information.
|
110
|
+
def eof?
|
111
|
+
@io.eof?
|
112
|
+
end
|
113
|
+
|
114
|
+
# Reads the next line from this input method.
|
115
|
+
#
|
116
|
+
# See IO#gets for more information.
|
117
|
+
def gets
|
118
|
+
print @prompt
|
119
|
+
l = @io.gets
|
120
|
+
l
|
121
|
+
end
|
122
|
+
|
123
|
+
# The external encoding for standard input.
|
124
|
+
def encoding
|
125
|
+
@io.external_encoding
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
begin
|
130
|
+
require "readline"
|
131
|
+
class ReadlineInputMethod < InputMethod
|
132
|
+
include Readline
|
133
|
+
# Creates a new input method object using Readline
|
134
|
+
def initialize
|
135
|
+
super
|
136
|
+
|
137
|
+
@line_no = 0
|
138
|
+
@line = []
|
139
|
+
@eof = false
|
140
|
+
|
141
|
+
@stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
142
|
+
@stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
143
|
+
end
|
144
|
+
|
145
|
+
# Reads the next line from this input method.
|
146
|
+
#
|
147
|
+
# See IO#gets for more information.
|
148
|
+
def gets
|
149
|
+
Readline.input = @stdin
|
150
|
+
Readline.output = @stdout
|
151
|
+
if l = readline(@prompt, false)
|
152
|
+
HISTORY.push(l) if !l.empty?
|
153
|
+
@line[@line_no += 1] = l + "\n"
|
154
|
+
else
|
155
|
+
@eof = true
|
156
|
+
l
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Whether the end of this input method has been reached, returns +true+
|
161
|
+
# if there is no more data to read.
|
162
|
+
#
|
163
|
+
# See IO#eof? for more information.
|
164
|
+
def eof?
|
165
|
+
@eof
|
166
|
+
end
|
167
|
+
|
168
|
+
# Whether this input method is still readable when there is no more data to
|
169
|
+
# read.
|
170
|
+
#
|
171
|
+
# See IO#eof for more information.
|
172
|
+
def readable_after_eof?
|
173
|
+
true
|
174
|
+
end
|
175
|
+
|
176
|
+
# Returns the current line number for #io.
|
177
|
+
#
|
178
|
+
# #line counts the number of times #gets is called.
|
179
|
+
#
|
180
|
+
# See IO#lineno for more information.
|
181
|
+
def line(line_no)
|
182
|
+
@line[line_no]
|
183
|
+
end
|
184
|
+
|
185
|
+
# The external encoding for standard input.
|
186
|
+
def encoding
|
187
|
+
@stdin.external_encoding
|
188
|
+
end
|
189
|
+
end
|
190
|
+
rescue LoadError
|
191
|
+
end
|
192
|
+
end
|