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
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# history.rb -
|
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
|
+
class Context
|
16
|
+
|
17
|
+
NOPRINTING_IVARS.push "@eval_history_values"
|
18
|
+
|
19
|
+
# See #set_last_value
|
20
|
+
alias _set_last_value set_last_value
|
21
|
+
|
22
|
+
def set_last_value(value)
|
23
|
+
_set_last_value(value)
|
24
|
+
|
25
|
+
if @eval_history
|
26
|
+
@eval_history_values.push @line_no, @last_value
|
27
|
+
@workspace.evaluate self, "__ = IRB.CurrentContext.instance_eval{@eval_history_values}"
|
28
|
+
end
|
29
|
+
|
30
|
+
@last_value
|
31
|
+
end
|
32
|
+
|
33
|
+
# The command result history limit.
|
34
|
+
attr_reader :eval_history
|
35
|
+
# Sets command result history limit.
|
36
|
+
#
|
37
|
+
# +no+ is an Integer or +nil+.
|
38
|
+
#
|
39
|
+
# Returns +no+ of history items if greater than 0.
|
40
|
+
#
|
41
|
+
# If +no+ is 0, the number of history items is unlimited.
|
42
|
+
#
|
43
|
+
# If +no+ is +nil+, execution result history isn't used (default).
|
44
|
+
def eval_history=(no)
|
45
|
+
if no
|
46
|
+
if defined?(@eval_history) && @eval_history
|
47
|
+
@eval_history_values.size(no)
|
48
|
+
else
|
49
|
+
@eval_history_values = History.new(no)
|
50
|
+
IRB.conf[:__TMP__EHV__] = @eval_history_values
|
51
|
+
@workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
|
52
|
+
IRB.conf.delete(:__TMP_EHV__)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
@eval_history_values = nil
|
56
|
+
end
|
57
|
+
@eval_history = no
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class History # :nodoc:
|
62
|
+
|
63
|
+
def initialize(size = 16)
|
64
|
+
@size = size
|
65
|
+
@contents = []
|
66
|
+
end
|
67
|
+
|
68
|
+
def size(size)
|
69
|
+
if size != 0 && size < @size
|
70
|
+
@contents = @contents[@size - size .. @size]
|
71
|
+
end
|
72
|
+
@size = size
|
73
|
+
end
|
74
|
+
|
75
|
+
def [](idx)
|
76
|
+
begin
|
77
|
+
if idx >= 0
|
78
|
+
@contents.find{|no, val| no == idx}[1]
|
79
|
+
else
|
80
|
+
@contents[idx][1]
|
81
|
+
end
|
82
|
+
rescue NameError
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def push(no, val)
|
88
|
+
@contents.push [no, val]
|
89
|
+
@contents.shift if @size != 0 && @contents.size > @size
|
90
|
+
end
|
91
|
+
|
92
|
+
alias real_inspect inspect
|
93
|
+
|
94
|
+
def inspect
|
95
|
+
if @contents.empty?
|
96
|
+
return real_inspect
|
97
|
+
end
|
98
|
+
|
99
|
+
unless (last = @contents.pop)[1].equal?(self)
|
100
|
+
@contents.push last
|
101
|
+
last = nil
|
102
|
+
end
|
103
|
+
str = @contents.collect{|no, val|
|
104
|
+
if val.equal?(self)
|
105
|
+
"#{no} ...self-history..."
|
106
|
+
else
|
107
|
+
"#{no} #{val.inspect}"
|
108
|
+
end
|
109
|
+
}.join("\n")
|
110
|
+
if str == ""
|
111
|
+
str = "Empty."
|
112
|
+
end
|
113
|
+
@contents.push last if last
|
114
|
+
str
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# loader.rb -
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
|
13
|
+
|
14
|
+
module IRB # :nodoc:
|
15
|
+
# Raised in the event of an exception in a file loaded from an Irb session
|
16
|
+
class LoadAbort < Exception;end
|
17
|
+
|
18
|
+
# Provides a few commands for loading files within an irb session.
|
19
|
+
#
|
20
|
+
# See ExtendCommandBundle for more information.
|
21
|
+
module IrbLoader
|
22
|
+
|
23
|
+
alias ruby_load load
|
24
|
+
alias ruby_require require
|
25
|
+
|
26
|
+
# Loads the given file similarly to Kernel#load
|
27
|
+
def irb_load(fn, priv = nil)
|
28
|
+
path = search_file_from_ruby_path(fn)
|
29
|
+
raise LoadError, "No such file to load -- #{fn}" unless path
|
30
|
+
|
31
|
+
load_file(path, priv)
|
32
|
+
end
|
33
|
+
|
34
|
+
def search_file_from_ruby_path(fn) # :nodoc:
|
35
|
+
if /^#{Regexp.quote(File::Separator)}/ =~ fn
|
36
|
+
return fn if File.exist?(fn)
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
|
40
|
+
for path in $:
|
41
|
+
if File.exist?(f = File.join(path, fn))
|
42
|
+
return f
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Loads a given file in the current session and displays the source lines
|
49
|
+
#
|
50
|
+
# See Irb#suspend_input_method for more information.
|
51
|
+
def source_file(path)
|
52
|
+
irb.suspend_name(path, File.basename(path)) do
|
53
|
+
irb.suspend_input_method(FileInputMethod.new(path)) do
|
54
|
+
|back_io|
|
55
|
+
irb.signal_status(:IN_LOAD) do
|
56
|
+
if back_io.kind_of?(FileInputMethod)
|
57
|
+
irb.eval_input
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
irb.eval_input
|
61
|
+
rescue LoadAbort
|
62
|
+
print "load abort!!\n"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Loads the given file in the current session's context and evaluates it.
|
71
|
+
#
|
72
|
+
# See Irb#suspend_input_method for more information.
|
73
|
+
def load_file(path, priv = nil)
|
74
|
+
irb.suspend_name(path, File.basename(path)) do
|
75
|
+
|
76
|
+
if priv
|
77
|
+
ws = WorkSpace.new(Module.new)
|
78
|
+
else
|
79
|
+
ws = WorkSpace.new
|
80
|
+
end
|
81
|
+
irb.suspend_workspace(ws) do
|
82
|
+
irb.suspend_input_method(FileInputMethod.new(path)) do
|
83
|
+
|back_io|
|
84
|
+
irb.signal_status(:IN_LOAD) do
|
85
|
+
if back_io.kind_of?(FileInputMethod)
|
86
|
+
irb.eval_input
|
87
|
+
else
|
88
|
+
begin
|
89
|
+
irb.eval_input
|
90
|
+
rescue LoadAbort
|
91
|
+
print "load abort!!\n"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def old # :nodoc:
|
101
|
+
back_io = @io
|
102
|
+
back_path = @irb_path
|
103
|
+
back_name = @irb_name
|
104
|
+
back_scanner = @irb.scanner
|
105
|
+
begin
|
106
|
+
@io = FileInputMethod.new(path)
|
107
|
+
@irb_name = File.basename(path)
|
108
|
+
@irb_path = path
|
109
|
+
@irb.signal_status(:IN_LOAD) do
|
110
|
+
if back_io.kind_of?(FileInputMethod)
|
111
|
+
@irb.eval_input
|
112
|
+
else
|
113
|
+
begin
|
114
|
+
@irb.eval_input
|
115
|
+
rescue LoadAbort
|
116
|
+
print "load abort!!\n"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
ensure
|
121
|
+
@io = back_io
|
122
|
+
@irb_name = back_name
|
123
|
+
@irb_path = back_path
|
124
|
+
@irb.scanner = back_scanner
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
@@ -0,0 +1,265 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
#
|
3
|
+
# irb/multi-irb.rb - multiple irb module
|
4
|
+
# $Release Version: 0.9.6$
|
5
|
+
# $Revision$
|
6
|
+
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
|
+
#
|
8
|
+
# --
|
9
|
+
#
|
10
|
+
#
|
11
|
+
#
|
12
|
+
IRB.fail CantShiftToMultiIrbMode unless defined?(Thread)
|
13
|
+
|
14
|
+
module IRB
|
15
|
+
class JobManager
|
16
|
+
|
17
|
+
# Creates a new JobManager object
|
18
|
+
def initialize
|
19
|
+
@jobs = []
|
20
|
+
@current_job = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# The active irb session
|
24
|
+
attr_accessor :current_job
|
25
|
+
|
26
|
+
# The total number of irb sessions, used to set +irb_name+ of the current
|
27
|
+
# Context.
|
28
|
+
def n_jobs
|
29
|
+
@jobs.size
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the thread for the given +key+ object, see #search for more
|
33
|
+
# information.
|
34
|
+
def thread(key)
|
35
|
+
th, = search(key)
|
36
|
+
th
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the irb session for the given +key+ object, see #search for more
|
40
|
+
# information.
|
41
|
+
def irb(key)
|
42
|
+
_, irb = search(key)
|
43
|
+
irb
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the top level thread.
|
47
|
+
def main_thread
|
48
|
+
@jobs[0][0]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the top level irb session.
|
52
|
+
def main_irb
|
53
|
+
@jobs[0][1]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add the given +irb+ session to the jobs Array.
|
57
|
+
def insert(irb)
|
58
|
+
@jobs.push [Thread.current, irb]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Changes the current active irb session to the given +key+ in the jobs
|
62
|
+
# Array.
|
63
|
+
#
|
64
|
+
# Raises an IrbAlreadyDead exception if the given +key+ is no longer alive.
|
65
|
+
#
|
66
|
+
# If the given irb session is already active, an IrbSwitchedToCurrentThread
|
67
|
+
# exception is raised.
|
68
|
+
def switch(key)
|
69
|
+
th, irb = search(key)
|
70
|
+
IRB.fail IrbAlreadyDead unless th.alive?
|
71
|
+
IRB.fail IrbSwitchedToCurrentThread if th == Thread.current
|
72
|
+
@current_job = irb
|
73
|
+
th.run
|
74
|
+
Thread.stop
|
75
|
+
@current_job = irb(Thread.current)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Terminates the irb sessions specified by the given +keys+.
|
79
|
+
#
|
80
|
+
# Raises an IrbAlreadyDead exception if one of the given +keys+ is already
|
81
|
+
# terminated.
|
82
|
+
#
|
83
|
+
# See Thread#exit for more information.
|
84
|
+
def kill(*keys)
|
85
|
+
for key in keys
|
86
|
+
th, _ = search(key)
|
87
|
+
IRB.fail IrbAlreadyDead unless th.alive?
|
88
|
+
th.exit
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the associated job for the given +key+.
|
93
|
+
#
|
94
|
+
# If given an Integer, it will return the +key+ index for the jobs Array.
|
95
|
+
#
|
96
|
+
# When an instance of Irb is given, it will return the irb session
|
97
|
+
# associated with +key+.
|
98
|
+
#
|
99
|
+
# If given an instance of Thread, it will return the associated thread
|
100
|
+
# +key+ using Object#=== on the jobs Array.
|
101
|
+
#
|
102
|
+
# Otherwise returns the irb session with the same top-level binding as the
|
103
|
+
# given +key+.
|
104
|
+
#
|
105
|
+
# Raises a NoSuchJob exception if no job can be found with the given +key+.
|
106
|
+
def search(key)
|
107
|
+
job = case key
|
108
|
+
when Integer
|
109
|
+
@jobs[key]
|
110
|
+
when Irb
|
111
|
+
@jobs.find{|k, v| v.equal?(key)}
|
112
|
+
when Thread
|
113
|
+
@jobs.assoc(key)
|
114
|
+
else
|
115
|
+
@jobs.find{|k, v| v.context.main.equal?(key)}
|
116
|
+
end
|
117
|
+
IRB.fail NoSuchJob, key if job.nil?
|
118
|
+
job
|
119
|
+
end
|
120
|
+
|
121
|
+
# Deletes the job at the given +key+.
|
122
|
+
def delete(key)
|
123
|
+
case key
|
124
|
+
when Integer
|
125
|
+
IRB.fail NoSuchJob, key unless @jobs[key]
|
126
|
+
@jobs[key] = nil
|
127
|
+
else
|
128
|
+
catch(:EXISTS) do
|
129
|
+
@jobs.each_index do
|
130
|
+
|i|
|
131
|
+
if @jobs[i] and (@jobs[i][0] == key ||
|
132
|
+
@jobs[i][1] == key ||
|
133
|
+
@jobs[i][1].context.main.equal?(key))
|
134
|
+
@jobs[i] = nil
|
135
|
+
throw :EXISTS
|
136
|
+
end
|
137
|
+
end
|
138
|
+
IRB.fail NoSuchJob, key
|
139
|
+
end
|
140
|
+
end
|
141
|
+
until assoc = @jobs.pop; end unless @jobs.empty?
|
142
|
+
@jobs.push assoc
|
143
|
+
end
|
144
|
+
|
145
|
+
# Outputs a list of jobs, see the irb command +irb_jobs+, or +jobs+.
|
146
|
+
def inspect
|
147
|
+
ary = []
|
148
|
+
@jobs.each_index do
|
149
|
+
|i|
|
150
|
+
th, irb = @jobs[i]
|
151
|
+
next if th.nil?
|
152
|
+
|
153
|
+
if th.alive?
|
154
|
+
if th.stop?
|
155
|
+
t_status = "stop"
|
156
|
+
else
|
157
|
+
t_status = "running"
|
158
|
+
end
|
159
|
+
else
|
160
|
+
t_status = "exited"
|
161
|
+
end
|
162
|
+
ary.push format("#%d->%s on %s (%s: %s)",
|
163
|
+
i,
|
164
|
+
irb.context.irb_name,
|
165
|
+
irb.context.main,
|
166
|
+
th,
|
167
|
+
t_status)
|
168
|
+
end
|
169
|
+
ary.join("\n")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
@JobManager = JobManager.new
|
174
|
+
|
175
|
+
# The current JobManager in the session
|
176
|
+
def IRB.JobManager
|
177
|
+
@JobManager
|
178
|
+
end
|
179
|
+
|
180
|
+
# The current Context in this session
|
181
|
+
def IRB.CurrentContext
|
182
|
+
IRB.JobManager.irb(Thread.current).context
|
183
|
+
end
|
184
|
+
|
185
|
+
# Creates a new IRB session, see Irb.new.
|
186
|
+
#
|
187
|
+
# The optional +file+ argument is given to Context.new, along with the
|
188
|
+
# workspace created with the remaining arguments, see WorkSpace.new
|
189
|
+
def IRB.irb(file = nil, *main)
|
190
|
+
workspace = WorkSpace.new(*main)
|
191
|
+
parent_thread = Thread.current
|
192
|
+
Thread.start do
|
193
|
+
begin
|
194
|
+
irb = Irb.new(workspace, file)
|
195
|
+
rescue
|
196
|
+
print "Subirb can't start with context(self): ", workspace.main.inspect, "\n"
|
197
|
+
print "return to main irb\n"
|
198
|
+
Thread.pass
|
199
|
+
Thread.main.wakeup
|
200
|
+
Thread.exit
|
201
|
+
end
|
202
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
203
|
+
@JobManager.insert(irb)
|
204
|
+
@JobManager.current_job = irb
|
205
|
+
begin
|
206
|
+
system_exit = false
|
207
|
+
catch(:IRB_EXIT) do
|
208
|
+
irb.eval_input
|
209
|
+
end
|
210
|
+
rescue SystemExit
|
211
|
+
system_exit = true
|
212
|
+
raise
|
213
|
+
#fail
|
214
|
+
ensure
|
215
|
+
unless system_exit
|
216
|
+
@JobManager.delete(irb)
|
217
|
+
if @JobManager.current_job == irb
|
218
|
+
if parent_thread.alive?
|
219
|
+
@JobManager.current_job = @JobManager.irb(parent_thread)
|
220
|
+
parent_thread.run
|
221
|
+
else
|
222
|
+
@JobManager.current_job = @JobManager.main_irb
|
223
|
+
@JobManager.main_thread.run
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
Thread.stop
|
230
|
+
@JobManager.current_job = @JobManager.irb(Thread.current)
|
231
|
+
end
|
232
|
+
|
233
|
+
@CONF[:SINGLE_IRB_MODE] = false
|
234
|
+
@JobManager.insert(@CONF[:MAIN_CONTEXT].irb)
|
235
|
+
@JobManager.current_job = @CONF[:MAIN_CONTEXT].irb
|
236
|
+
|
237
|
+
class Irb
|
238
|
+
def signal_handle
|
239
|
+
unless @context.ignore_sigint?
|
240
|
+
print "\nabort!!\n" if @context.verbose?
|
241
|
+
exit
|
242
|
+
end
|
243
|
+
|
244
|
+
case @signal_status
|
245
|
+
when :IN_INPUT
|
246
|
+
print "^C\n"
|
247
|
+
IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput
|
248
|
+
when :IN_EVAL
|
249
|
+
IRB.irb_abort(self)
|
250
|
+
when :IN_LOAD
|
251
|
+
IRB.irb_abort(self, LoadAbort)
|
252
|
+
when :IN_IRB
|
253
|
+
# ignore
|
254
|
+
else
|
255
|
+
# ignore other cases as well
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
trap("SIGINT") do
|
261
|
+
@JobManager.current_job.signal_handle
|
262
|
+
Thread.stop
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|