irb 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
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