irb 1.1.0.pre.4

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +55 -0
  5. data/Rakefile +10 -0
  6. data/bin/console +6 -0
  7. data/bin/setup +6 -0
  8. data/doc/irb/irb-tools.rd.ja +184 -0
  9. data/doc/irb/irb.rd.ja +411 -0
  10. data/exe/irb +11 -0
  11. data/irb.gemspec +84 -0
  12. data/lib/irb.rb +870 -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 +46 -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/color.rb +233 -0
  21. data/lib/irb/completion.rb +339 -0
  22. data/lib/irb/context.rb +458 -0
  23. data/lib/irb/ext/change-ws.rb +46 -0
  24. data/lib/irb/ext/history.rb +157 -0
  25. data/lib/irb/ext/loader.rb +129 -0
  26. data/lib/irb/ext/multi-irb.rb +265 -0
  27. data/lib/irb/ext/save-history.rb +117 -0
  28. data/lib/irb/ext/tracer.rb +72 -0
  29. data/lib/irb/ext/use-loader.rb +77 -0
  30. data/lib/irb/ext/workspaces.rb +67 -0
  31. data/lib/irb/extend-command.rb +328 -0
  32. data/lib/irb/frame.rb +81 -0
  33. data/lib/irb/help.rb +37 -0
  34. data/lib/irb/init.rb +312 -0
  35. data/lib/irb/input-method.rb +298 -0
  36. data/lib/irb/inspector.rb +142 -0
  37. data/lib/irb/lc/.document +4 -0
  38. data/lib/irb/lc/error.rb +32 -0
  39. data/lib/irb/lc/help-message +52 -0
  40. data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
  41. data/lib/irb/lc/ja/error.rb +31 -0
  42. data/lib/irb/lc/ja/help-message +55 -0
  43. data/lib/irb/locale.rb +182 -0
  44. data/lib/irb/magic-file.rb +38 -0
  45. data/lib/irb/notifier.rb +232 -0
  46. data/lib/irb/output-method.rb +92 -0
  47. data/lib/irb/ruby-lex.rb +499 -0
  48. data/lib/irb/ruby_logo.aa +38 -0
  49. data/lib/irb/slex.rb +282 -0
  50. data/lib/irb/src_encoding.rb +7 -0
  51. data/lib/irb/version.rb +17 -0
  52. data/lib/irb/workspace.rb +181 -0
  53. data/lib/irb/ws-for-case-2.rb +15 -0
  54. data/lib/irb/xmp.rb +170 -0
  55. data/man/irb.1 +207 -0
  56. metadata +140 -0
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # irb/ext/cb.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
+ class Context
15
+
16
+ # Inherited from +TOPLEVEL_BINDING+.
17
+ def home_workspace
18
+ if defined? @home_workspace
19
+ @home_workspace
20
+ else
21
+ @home_workspace = @workspace
22
+ end
23
+ end
24
+
25
+ # Changes the current workspace to given object or binding.
26
+ #
27
+ # If the optional argument is omitted, the workspace will be
28
+ # #home_workspace which is inherited from +TOPLEVEL_BINDING+ or the main
29
+ # object, <code>IRB.conf[:MAIN_CONTEXT]</code> when irb was initialized.
30
+ #
31
+ # See IRB::WorkSpace.new for more information.
32
+ def change_workspace(*_main)
33
+ if _main.empty?
34
+ @workspace = home_workspace
35
+ return main
36
+ end
37
+
38
+ @workspace = WorkSpace.new(_main[0])
39
+
40
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
41
+ main.extend ExtendCommandBundle
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,157 @@
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 defined?(@eval_history) && @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
+ remove_method :eval_history= if method_defined?(:eval_history=)
34
+ # The command result history limit. This method is not available until
35
+ # #eval_history= was called with non-nil value (directly or via
36
+ # setting <code>IRB.conf[:EVAL_HISTORY]</code> in <code>.irbrc</code>).
37
+ attr_reader :eval_history
38
+ # Sets command result history limit. Default value is set from
39
+ # <code>IRB.conf[:EVAL_HISTORY]</code>.
40
+ #
41
+ # +no+ is an Integer or +nil+.
42
+ #
43
+ # Returns +no+ of history items if greater than 0.
44
+ #
45
+ # If +no+ is 0, the number of history items is unlimited.
46
+ #
47
+ # If +no+ is +nil+, execution result history isn't used (default).
48
+ #
49
+ # History values are available via <code>__</code> variable, see
50
+ # IRB::History.
51
+ def eval_history=(no)
52
+ if no
53
+ if defined?(@eval_history) && @eval_history
54
+ @eval_history_values.size(no)
55
+ else
56
+ @eval_history_values = History.new(no)
57
+ IRB.conf[:__TMP__EHV__] = @eval_history_values
58
+ @workspace.evaluate(self, "__ = IRB.conf[:__TMP__EHV__]")
59
+ IRB.conf.delete(:__TMP_EHV__)
60
+ end
61
+ else
62
+ @eval_history_values = nil
63
+ end
64
+ @eval_history = no
65
+ end
66
+ end
67
+
68
+ # Represents history of results of previously evaluated commands.
69
+ #
70
+ # Available via <code>__</code> variable, only if <code>IRB.conf[:EVAL_HISTORY]</code>
71
+ # or <code>IRB::CurrentContext().eval_history</code> is non-nil integer value
72
+ # (by default it is +nil+).
73
+ #
74
+ # Example (in `irb`):
75
+ #
76
+ # # Initialize history
77
+ # IRB::CurrentContext().eval_history = 10
78
+ # # => 10
79
+ #
80
+ # # Perform some commands...
81
+ # 1 + 2
82
+ # # => 3
83
+ # puts 'x'
84
+ # # x
85
+ # # => nil
86
+ # raise RuntimeError
87
+ # # ...error raised
88
+ #
89
+ # # Inspect history (format is "<item number> <evaluated value>":
90
+ # __
91
+ # # => 1 10
92
+ # # 2 3
93
+ # # 3 nil
94
+ #
95
+ # __[1]
96
+ # # => 10
97
+ #
98
+ class History
99
+
100
+ def initialize(size = 16) # :nodoc:
101
+ @size = size
102
+ @contents = []
103
+ end
104
+
105
+ def size(size) # :nodoc:
106
+ if size != 0 && size < @size
107
+ @contents = @contents[@size - size .. @size]
108
+ end
109
+ @size = size
110
+ end
111
+
112
+ # Get one item of the content (both positive and negative indexes work).
113
+ def [](idx)
114
+ begin
115
+ if idx >= 0
116
+ @contents.find{|no, val| no == idx}[1]
117
+ else
118
+ @contents[idx][1]
119
+ end
120
+ rescue NameError
121
+ nil
122
+ end
123
+ end
124
+
125
+ def push(no, val) # :nodoc:
126
+ @contents.push [no, val]
127
+ @contents.shift if @size != 0 && @contents.size > @size
128
+ end
129
+
130
+ alias real_inspect inspect
131
+
132
+ def inspect # :nodoc:
133
+ if @contents.empty?
134
+ return real_inspect
135
+ end
136
+
137
+ unless (last = @contents.pop)[1].equal?(self)
138
+ @contents.push last
139
+ last = nil
140
+ end
141
+ str = @contents.collect{|no, val|
142
+ if val.equal?(self)
143
+ "#{no} ...self-history..."
144
+ else
145
+ "#{no} #{val.inspect}"
146
+ end
147
+ }.join("\n")
148
+ if str == ""
149
+ str = "Empty."
150
+ end
151
+ @contents.push last if last
152
+ str
153
+ end
154
+ end
155
+ end
156
+
157
+
@@ -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