irb 1.1.0.pre.3

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