irb 1.1.0.pre.3

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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +55 -0
  4. data/exe/irb +11 -0
  5. data/irb.gemspec +29 -0
  6. data/lib/irb.rb +855 -0
  7. data/lib/irb/cmd/chws.rb +34 -0
  8. data/lib/irb/cmd/fork.rb +39 -0
  9. data/lib/irb/cmd/help.rb +46 -0
  10. data/lib/irb/cmd/load.rb +67 -0
  11. data/lib/irb/cmd/nop.rb +39 -0
  12. data/lib/irb/cmd/pushws.rb +41 -0
  13. data/lib/irb/cmd/subirb.rb +43 -0
  14. data/lib/irb/color.rb +218 -0
  15. data/lib/irb/completion.rb +339 -0
  16. data/lib/irb/context.rb +459 -0
  17. data/lib/irb/ext/change-ws.rb +46 -0
  18. data/lib/irb/ext/history.rb +120 -0
  19. data/lib/irb/ext/loader.rb +129 -0
  20. data/lib/irb/ext/multi-irb.rb +265 -0
  21. data/lib/irb/ext/save-history.rb +117 -0
  22. data/lib/irb/ext/tracer.rb +72 -0
  23. data/lib/irb/ext/use-loader.rb +77 -0
  24. data/lib/irb/ext/workspaces.rb +67 -0
  25. data/lib/irb/extend-command.rb +328 -0
  26. data/lib/irb/frame.rb +81 -0
  27. data/lib/irb/help.rb +37 -0
  28. data/lib/irb/init.rb +312 -0
  29. data/lib/irb/input-method.rb +298 -0
  30. data/lib/irb/inspector.rb +142 -0
  31. data/lib/irb/lc/.document +4 -0
  32. data/lib/irb/lc/error.rb +32 -0
  33. data/lib/irb/lc/help-message +50 -0
  34. data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
  35. data/lib/irb/lc/ja/error.rb +31 -0
  36. data/lib/irb/lc/ja/help-message +52 -0
  37. data/lib/irb/locale.rb +182 -0
  38. data/lib/irb/magic-file.rb +38 -0
  39. data/lib/irb/notifier.rb +232 -0
  40. data/lib/irb/output-method.rb +92 -0
  41. data/lib/irb/ruby-lex.rb +492 -0
  42. data/lib/irb/ruby-token.rb +267 -0
  43. data/lib/irb/slex.rb +282 -0
  44. data/lib/irb/src_encoding.rb +7 -0
  45. data/lib/irb/version.rb +17 -0
  46. data/lib/irb/workspace.rb +190 -0
  47. data/lib/irb/ws-for-case-2.rb +15 -0
  48. data/lib/irb/xmp.rb +170 -0
  49. metadata +133 -0
@@ -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
@@ -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
+
@@ -0,0 +1,312 @@
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[:USE_COLORIZE] = true
48
+ @CONF[:INSPECT_MODE] = true
49
+ @CONF[:USE_TRACER] = false
50
+ @CONF[:USE_LOADER] = false
51
+ @CONF[:IGNORE_SIGINT] = true
52
+ @CONF[:IGNORE_EOF] = false
53
+ @CONF[:ECHO] = nil
54
+ @CONF[:ECHO_ON_ASSIGNMENT] = nil
55
+ @CONF[:VERBOSE] = nil
56
+
57
+ @CONF[:EVAL_HISTORY] = nil
58
+ @CONF[:SAVE_HISTORY] = 1000
59
+
60
+ @CONF[:BACK_TRACE_LIMIT] = 16
61
+
62
+ @CONF[:PROMPT] = {
63
+ :NULL => {
64
+ :PROMPT_I => nil,
65
+ :PROMPT_N => nil,
66
+ :PROMPT_S => nil,
67
+ :PROMPT_C => nil,
68
+ :RETURN => "%s\n"
69
+ },
70
+ :DEFAULT => {
71
+ :PROMPT_I => "%N(%m):%03n:%i> ",
72
+ :PROMPT_N => "%N(%m):%03n:%i> ",
73
+ :PROMPT_S => "%N(%m):%03n:%i%l ",
74
+ :PROMPT_C => "%N(%m):%03n:%i* ",
75
+ :RETURN => "=> %s\n"
76
+ },
77
+ :CLASSIC => {
78
+ :PROMPT_I => "%N(%m):%03n:%i> ",
79
+ :PROMPT_N => "%N(%m):%03n:%i> ",
80
+ :PROMPT_S => "%N(%m):%03n:%i%l ",
81
+ :PROMPT_C => "%N(%m):%03n:%i* ",
82
+ :RETURN => "%s\n"
83
+ },
84
+ :SIMPLE => {
85
+ :PROMPT_I => ">> ",
86
+ :PROMPT_N => ">> ",
87
+ :PROMPT_S => "%l> ",
88
+ :PROMPT_C => "?> ",
89
+ :RETURN => "=> %s\n"
90
+ },
91
+ :INF_RUBY => {
92
+ :PROMPT_I => "%N(%m):%03n:%i> ",
93
+ :PROMPT_N => nil,
94
+ :PROMPT_S => nil,
95
+ :PROMPT_C => nil,
96
+ :RETURN => "%s\n",
97
+ :AUTO_INDENT => true
98
+ },
99
+ :XMP => {
100
+ :PROMPT_I => nil,
101
+ :PROMPT_N => nil,
102
+ :PROMPT_S => nil,
103
+ :PROMPT_C => nil,
104
+ :RETURN => " ==>%s\n"
105
+ }
106
+ }
107
+
108
+ @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
109
+ @CONF[:AUTO_INDENT] = true
110
+
111
+ @CONF[:CONTEXT_MODE] = 3 # use binding in function on TOPLEVEL_BINDING
112
+ @CONF[:SINGLE_IRB] = false
113
+
114
+ @CONF[:LC_MESSAGES] = Locale.new
115
+
116
+ @CONF[:AT_EXIT] = []
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 "--reidline"
169
+ @CONF[:USE_REIDLINE] = true
170
+ when "--noreidline"
171
+ @CONF[:USE_REIDLINE] = false
172
+ when "--echo"
173
+ @CONF[:ECHO] = true
174
+ when "--noecho"
175
+ @CONF[:ECHO] = false
176
+ when "--echo-on-assignment"
177
+ @CONF[:ECHO_ON_ASSIGNMENT] = true
178
+ when "--noecho-on-assignment"
179
+ @CONF[:ECHO_ON_ASSIGNMENT] = false
180
+ when "--verbose"
181
+ @CONF[:VERBOSE] = true
182
+ when "--noverbose"
183
+ @CONF[:VERBOSE] = false
184
+ when "--colorize"
185
+ @CONF[:USE_COLORIZE] = true
186
+ when "--nocolorize"
187
+ @CONF[:USE_COLORIZE] = false
188
+ when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
189
+ opt = $1 || argv.shift
190
+ prompt_mode = opt.upcase.tr("-", "_").intern
191
+ @CONF[:PROMPT_MODE] = prompt_mode
192
+ when "--noprompt"
193
+ @CONF[:PROMPT_MODE] = :NULL
194
+ when "--inf-ruby-mode"
195
+ @CONF[:PROMPT_MODE] = :INF_RUBY
196
+ when "--sample-book-mode", "--simple-prompt"
197
+ @CONF[:PROMPT_MODE] = :SIMPLE
198
+ when "--tracer"
199
+ @CONF[:USE_TRACER] = true
200
+ when /^--back-trace-limit(?:=(.+))?/
201
+ @CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i
202
+ when /^--context-mode(?:=(.+))?/
203
+ @CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
204
+ when "--single-irb"
205
+ @CONF[:SINGLE_IRB] = true
206
+ when "-v", "--version"
207
+ print IRB.version, "\n"
208
+ exit 0
209
+ when "-h", "--help"
210
+ require_relative "help"
211
+ IRB.print_usage
212
+ exit 0
213
+ when "--"
214
+ if opt = argv.shift
215
+ @CONF[:SCRIPT] = opt
216
+ $0 = opt
217
+ end
218
+ break
219
+ when /^-/
220
+ IRB.fail UnrecognizedSwitch, opt
221
+ else
222
+ @CONF[:SCRIPT] = opt
223
+ $0 = opt
224
+ break
225
+ end
226
+ end
227
+ load_path.collect! do |path|
228
+ /\A\.\// =~ path ? path : File.expand_path(path)
229
+ end
230
+ $LOAD_PATH.unshift(*load_path)
231
+
232
+ end
233
+
234
+ # running config
235
+ def IRB.run_config
236
+ if @CONF[:RC]
237
+ begin
238
+ load rc_file
239
+ rescue LoadError, Errno::ENOENT
240
+ rescue # StandardError, ScriptError
241
+ print "load error: #{rc_file}\n"
242
+ print $!.class, ": ", $!, "\n"
243
+ for err in $@[0, $@.size - 2]
244
+ print "\t", err, "\n"
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ IRBRC_EXT = "rc"
251
+ def IRB.rc_file(ext = IRBRC_EXT)
252
+ if !@CONF[:RC_NAME_GENERATOR]
253
+ rc_file_generators do |rcgen|
254
+ @CONF[:RC_NAME_GENERATOR] ||= rcgen
255
+ if File.exist?(rcgen.call(IRBRC_EXT))
256
+ @CONF[:RC_NAME_GENERATOR] = rcgen
257
+ break
258
+ end
259
+ end
260
+ end
261
+ case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
262
+ when String
263
+ return rc_file
264
+ else
265
+ IRB.fail IllegalRCNameGenerator
266
+ end
267
+ end
268
+
269
+ # enumerate possible rc-file base name generators
270
+ def IRB.rc_file_generators
271
+ if irbrc = ENV["IRBRC"]
272
+ yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
273
+ end
274
+ if home = ENV["HOME"]
275
+ yield proc{|rc| home+"/.irb#{rc}"}
276
+ end
277
+ home = Dir.pwd
278
+ yield proc{|rc| home+"/.irb#{rc}"}
279
+ yield proc{|rc| home+"/irb#{rc.sub(/\A_?/, '.')}"}
280
+ yield proc{|rc| home+"/_irb#{rc}"}
281
+ yield proc{|rc| home+"/$irb#{rc}"}
282
+ end
283
+
284
+ # loading modules
285
+ def IRB.load_modules
286
+ for m in @CONF[:LOAD_MODULES]
287
+ begin
288
+ require m
289
+ rescue LoadError => err
290
+ warn "#{err.class}: #{err}", uplevel: 0
291
+ end
292
+ end
293
+ end
294
+
295
+
296
+ DefaultEncodings = Struct.new(:external, :internal)
297
+ class << IRB
298
+ private
299
+ def set_encoding(extern, intern = nil)
300
+ verbose, $VERBOSE = $VERBOSE, nil
301
+ Encoding.default_external = extern unless extern.nil? || extern.empty?
302
+ Encoding.default_internal = intern unless intern.nil? || intern.empty?
303
+ @CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
304
+ [$stdin, $stdout, $stderr].each do |io|
305
+ io.set_encoding(extern, intern)
306
+ end
307
+ @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
308
+ ensure
309
+ $VERBOSE = verbose
310
+ end
311
+ end
312
+ end
@@ -0,0 +1,298 @@
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
+ require_relative 'completion'
15
+ require 'reline'
16
+
17
+ module IRB
18
+ STDIN_FILE_NAME = "(line)" # :nodoc:
19
+ class InputMethod
20
+
21
+ # Creates a new input method object
22
+ def initialize(file = STDIN_FILE_NAME)
23
+ @file_name = file
24
+ end
25
+ # The file name of this input method, usually given during initialization.
26
+ attr_reader :file_name
27
+
28
+ # The irb prompt associated with this input method
29
+ attr_accessor :prompt
30
+
31
+ # Reads the next line from this input method.
32
+ #
33
+ # See IO#gets for more information.
34
+ def gets
35
+ IRB.fail NotImplementedError, "gets"
36
+ end
37
+ public :gets
38
+
39
+ # Whether this input method is still readable when there is no more data to
40
+ # read.
41
+ #
42
+ # See IO#eof for more information.
43
+ def readable_after_eof?
44
+ false
45
+ end
46
+ end
47
+
48
+ class StdioInputMethod < InputMethod
49
+ # Creates a new input method object
50
+ def initialize
51
+ super
52
+ @line_no = 0
53
+ @line = []
54
+ @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
55
+ @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
56
+ end
57
+
58
+ # Reads the next line from this input method.
59
+ #
60
+ # See IO#gets for more information.
61
+ def gets
62
+ print @prompt
63
+ line = @stdin.gets
64
+ @line[@line_no += 1] = line
65
+ end
66
+
67
+ # Whether the end of this input method has been reached, returns +true+ if
68
+ # there is no more data to read.
69
+ #
70
+ # See IO#eof? for more information.
71
+ def eof?
72
+ @stdin.eof?
73
+ end
74
+
75
+ # Whether this input method is still readable when there is no more data to
76
+ # read.
77
+ #
78
+ # See IO#eof for more information.
79
+ def readable_after_eof?
80
+ true
81
+ end
82
+
83
+ # Returns the current line number for #io.
84
+ #
85
+ # #line counts the number of times #gets is called.
86
+ #
87
+ # See IO#lineno for more information.
88
+ def line(line_no)
89
+ @line[line_no]
90
+ end
91
+
92
+ # The external encoding for standard input.
93
+ def encoding
94
+ @stdin.external_encoding
95
+ end
96
+ end
97
+
98
+ # Use a File for IO with irb, see InputMethod
99
+ class FileInputMethod < InputMethod
100
+ # Creates a new input method object
101
+ def initialize(file)
102
+ super
103
+ @io = IRB::MagicFile.open(file)
104
+ end
105
+ # The file name of this input method, usually given during initialization.
106
+ attr_reader :file_name
107
+
108
+ # Whether the end of this input method has been reached, returns +true+ if
109
+ # there is no more data to read.
110
+ #
111
+ # See IO#eof? for more information.
112
+ def eof?
113
+ @io.eof?
114
+ end
115
+
116
+ # Reads the next line from this input method.
117
+ #
118
+ # See IO#gets for more information.
119
+ def gets
120
+ print @prompt
121
+ l = @io.gets
122
+ l
123
+ end
124
+
125
+ # The external encoding for standard input.
126
+ def encoding
127
+ @io.external_encoding
128
+ end
129
+ end
130
+
131
+ begin
132
+ require "readline"
133
+ class ReadlineInputMethod < InputMethod
134
+ include Readline
135
+ # Creates a new input method object using Readline
136
+ def initialize
137
+ super
138
+
139
+ @line_no = 0
140
+ @line = []
141
+ @eof = false
142
+
143
+ @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
144
+ @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
145
+
146
+ if Readline.respond_to?("basic_word_break_characters=")
147
+ Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
148
+ end
149
+ Readline.completion_append_character = nil
150
+ Readline.completion_proc = IRB::InputCompletor::CompletionProc
151
+ end
152
+
153
+ # Reads the next line from this input method.
154
+ #
155
+ # See IO#gets for more information.
156
+ def gets
157
+ Readline.input = @stdin
158
+ Readline.output = @stdout
159
+ if l = readline(@prompt, false)
160
+ HISTORY.push(l) if !l.empty?
161
+ @line[@line_no += 1] = l + "\n"
162
+ else
163
+ @eof = true
164
+ l
165
+ end
166
+ end
167
+
168
+ # Whether the end of this input method has been reached, returns +true+
169
+ # if there is no more data to read.
170
+ #
171
+ # See IO#eof? for more information.
172
+ def eof?
173
+ @eof
174
+ end
175
+
176
+ # Whether this input method is still readable when there is no more data to
177
+ # read.
178
+ #
179
+ # See IO#eof for more information.
180
+ def readable_after_eof?
181
+ true
182
+ end
183
+
184
+ # Returns the current line number for #io.
185
+ #
186
+ # #line counts the number of times #gets is called.
187
+ #
188
+ # See IO#lineno for more information.
189
+ def line(line_no)
190
+ @line[line_no]
191
+ end
192
+
193
+ # The external encoding for standard input.
194
+ def encoding
195
+ @stdin.external_encoding
196
+ end
197
+
198
+ if Readline.respond_to?("basic_word_break_characters=")
199
+ Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
200
+ end
201
+ Readline.completion_append_character = nil
202
+ Readline.completion_proc = IRB::InputCompletor::CompletionProc
203
+ end
204
+ rescue LoadError
205
+ end
206
+
207
+ class ReidlineInputMethod < InputMethod
208
+ include Reline
209
+ # Creates a new input method object using Readline
210
+ def initialize
211
+ super
212
+
213
+ @line_no = 0
214
+ @line = []
215
+ @eof = false
216
+
217
+ @stdin = ::IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
218
+ @stdout = ::IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
219
+
220
+ if Reline.respond_to?("basic_word_break_characters=")
221
+ Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
222
+ end
223
+ Reline.completion_append_character = nil
224
+ Reline.completion_proc = IRB::InputCompletor::CompletionProc
225
+ Reline.output_modifier_proc =
226
+ if IRB.conf[:USE_COLORIZE]
227
+ proc do |output, complete:|
228
+ next unless IRB::Color.colorable?
229
+ IRB::Color.colorize_code(output, complete: complete)
230
+ end
231
+ else
232
+ proc do |output|
233
+ Reline::Unicode.escape_for_print(output)
234
+ end
235
+ end
236
+ Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
237
+ end
238
+
239
+ def check_termination(&block)
240
+ @check_termination_proc = block
241
+ end
242
+
243
+ def dynamic_prompt(&block)
244
+ @prompt_proc = block
245
+ end
246
+
247
+ def auto_indent(&block)
248
+ @auto_indent_proc = block
249
+ end
250
+
251
+ # Reads the next line from this input method.
252
+ #
253
+ # See IO#gets for more information.
254
+ def gets
255
+ Reline.input = @stdin
256
+ Reline.output = @stdout
257
+ Reline.prompt_proc = @prompt_proc
258
+ Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc
259
+ if l = readmultiline(@prompt, false, &@check_termination_proc)
260
+ HISTORY.push(l) if !l.empty?
261
+ @line[@line_no += 1] = l + "\n"
262
+ else
263
+ @eof = true
264
+ l
265
+ end
266
+ end
267
+
268
+ # Whether the end of this input method has been reached, returns +true+
269
+ # if there is no more data to read.
270
+ #
271
+ # See IO#eof? for more information.
272
+ def eof?
273
+ super
274
+ end
275
+
276
+ # Whether this input method is still readable when there is no more data to
277
+ # read.
278
+ #
279
+ # See IO#eof for more information.
280
+ def readable_after_eof?
281
+ true
282
+ end
283
+
284
+ # Returns the current line number for #io.
285
+ #
286
+ # #line counts the number of times #gets is called.
287
+ #
288
+ # See IO#lineno for more information.
289
+ def line(line_no)
290
+ @line[line_no]
291
+ end
292
+
293
+ # The external encoding for standard input.
294
+ def encoding
295
+ @stdin.external_encoding
296
+ end
297
+ end
298
+ end