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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +55 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +6 -0
  9. data/bin/setup +6 -0
  10. data/exe/irb +11 -0
  11. data/irb.gemspec +26 -0
  12. data/lib/irb.rb +798 -0
  13. data/lib/irb/cmd/chws.rb +34 -0
  14. data/lib/irb/cmd/fork.rb +39 -0
  15. data/lib/irb/cmd/help.rb +42 -0
  16. data/lib/irb/cmd/load.rb +67 -0
  17. data/lib/irb/cmd/nop.rb +39 -0
  18. data/lib/irb/cmd/pushws.rb +41 -0
  19. data/lib/irb/cmd/subirb.rb +43 -0
  20. data/lib/irb/completion.rb +244 -0
  21. data/lib/irb/context.rb +425 -0
  22. data/lib/irb/ext/change-ws.rb +46 -0
  23. data/lib/irb/ext/history.rb +119 -0
  24. data/lib/irb/ext/loader.rb +129 -0
  25. data/lib/irb/ext/multi-irb.rb +265 -0
  26. data/lib/irb/ext/save-history.rb +105 -0
  27. data/lib/irb/ext/tracer.rb +72 -0
  28. data/lib/irb/ext/use-loader.rb +74 -0
  29. data/lib/irb/ext/workspaces.rb +67 -0
  30. data/lib/irb/extend-command.rb +306 -0
  31. data/lib/irb/frame.rb +81 -0
  32. data/lib/irb/help.rb +37 -0
  33. data/lib/irb/init.rb +302 -0
  34. data/lib/irb/input-method.rb +192 -0
  35. data/lib/irb/inspector.rb +132 -0
  36. data/lib/irb/lc/.document +4 -0
  37. data/lib/irb/lc/error.rb +32 -0
  38. data/lib/irb/lc/help-message +49 -0
  39. data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
  40. data/lib/irb/lc/ja/error.rb +31 -0
  41. data/lib/irb/lc/ja/help-message +52 -0
  42. data/lib/irb/locale.rb +182 -0
  43. data/lib/irb/magic-file.rb +38 -0
  44. data/lib/irb/notifier.rb +232 -0
  45. data/lib/irb/output-method.rb +92 -0
  46. data/lib/irb/ruby-lex.rb +1180 -0
  47. data/lib/irb/ruby-token.rb +267 -0
  48. data/lib/irb/slex.rb +282 -0
  49. data/lib/irb/src_encoding.rb +7 -0
  50. data/lib/irb/version.rb +17 -0
  51. data/lib/irb/workspace.rb +143 -0
  52. data/lib/irb/ws-for-case-2.rb +15 -0
  53. data/lib/irb/xmp.rb +170 -0
  54. 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