irb 1.0.0 → 1.4.1
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.
- checksums.yaml +4 -4
- data/.document +4 -0
- data/Gemfile +10 -2
- data/LICENSE.txt +3 -3
- data/README.md +3 -3
- data/Rakefile +17 -1
- data/doc/irb/irb-tools.rd.ja +184 -0
- data/doc/irb/irb.rd.ja +427 -0
- data/irb.gemspec +18 -4
- data/lib/irb/cmd/fork.rb +2 -4
- data/lib/irb/cmd/help.rb +10 -5
- data/lib/irb/cmd/info.rb +32 -0
- data/lib/irb/cmd/ls.rb +101 -0
- data/lib/irb/cmd/measure.rb +43 -0
- data/lib/irb/cmd/nop.rb +10 -4
- data/lib/irb/cmd/pushws.rb +0 -1
- data/lib/irb/cmd/show_source.rb +93 -0
- data/lib/irb/cmd/whereami.rb +20 -0
- data/lib/irb/color.rb +246 -0
- data/lib/irb/color_printer.rb +47 -0
- data/lib/irb/completion.rb +254 -55
- data/lib/irb/context.rb +165 -72
- data/lib/irb/easter-egg.rb +138 -0
- data/lib/irb/ext/change-ws.rb +0 -1
- data/lib/irb/ext/history.rb +47 -11
- data/lib/irb/ext/loader.rb +46 -20
- data/lib/irb/ext/multi-irb.rb +7 -7
- data/lib/irb/ext/save-history.rb +36 -11
- data/lib/irb/ext/tracer.rb +14 -2
- data/lib/irb/ext/use-loader.rb +4 -3
- data/lib/irb/ext/workspaces.rb +0 -1
- data/lib/irb/extend-command.rb +113 -63
- data/lib/irb/frame.rb +12 -7
- data/lib/irb/help.rb +0 -1
- data/lib/irb/init.rb +146 -26
- data/lib/irb/input-method.rb +287 -9
- data/lib/irb/inspector.rb +15 -11
- data/lib/irb/lc/error.rb +55 -16
- data/lib/irb/lc/help-message +25 -13
- data/lib/irb/lc/ja/error.rb +55 -14
- data/lib/irb/lc/ja/help-message +11 -6
- data/lib/irb/locale.rb +13 -4
- data/lib/irb/notifier.rb +12 -8
- data/lib/irb/output-method.rb +6 -6
- data/lib/irb/ruby-lex.rb +673 -992
- data/lib/irb/ruby_logo.aa +37 -0
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +65 -21
- data/lib/irb/xmp.rb +1 -1
- data/lib/irb.rb +276 -96
- data/man/irb.1 +229 -0
- metadata +25 -31
- data/.gitignore +0 -9
- data/.travis.yml +0 -6
- data/lib/irb/lc/.document +0 -4
- data/lib/irb/ruby-token.rb +0 -267
- data/lib/irb/slex.rb +0 -282
data/lib/irb/init.rb
CHANGED
@@ -21,7 +21,7 @@ module IRB # :nodoc:
|
|
21
21
|
IRB.load_modules
|
22
22
|
|
23
23
|
unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]]
|
24
|
-
|
24
|
+
fail UndefinedPromptMode, @CONF[:PROMPT_MODE]
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -43,17 +43,21 @@ module IRB # :nodoc:
|
|
43
43
|
@CONF[:LOAD_MODULES] = []
|
44
44
|
@CONF[:IRB_RC] = nil
|
45
45
|
|
46
|
-
@CONF[:
|
46
|
+
@CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
|
47
|
+
@CONF[:USE_COLORIZE] = !ENV['NO_COLOR']
|
48
|
+
@CONF[:USE_AUTOCOMPLETE] = true
|
47
49
|
@CONF[:INSPECT_MODE] = true
|
48
50
|
@CONF[:USE_TRACER] = false
|
49
51
|
@CONF[:USE_LOADER] = false
|
50
52
|
@CONF[:IGNORE_SIGINT] = true
|
51
53
|
@CONF[:IGNORE_EOF] = false
|
54
|
+
@CONF[:EXTRA_DOC_DIRS] = []
|
52
55
|
@CONF[:ECHO] = nil
|
56
|
+
@CONF[:ECHO_ON_ASSIGNMENT] = nil
|
53
57
|
@CONF[:VERBOSE] = nil
|
54
58
|
|
55
59
|
@CONF[:EVAL_HISTORY] = nil
|
56
|
-
@CONF[:SAVE_HISTORY] =
|
60
|
+
@CONF[:SAVE_HISTORY] = 1000
|
57
61
|
|
58
62
|
@CONF[:BACK_TRACE_LIMIT] = 16
|
59
63
|
|
@@ -82,7 +86,7 @@ module IRB # :nodoc:
|
|
82
86
|
:SIMPLE => {
|
83
87
|
:PROMPT_I => ">> ",
|
84
88
|
:PROMPT_N => ">> ",
|
85
|
-
:PROMPT_S =>
|
89
|
+
:PROMPT_S => "%l> ",
|
86
90
|
:PROMPT_C => "?> ",
|
87
91
|
:RETURN => "=> %s\n"
|
88
92
|
},
|
@@ -104,16 +108,101 @@ module IRB # :nodoc:
|
|
104
108
|
}
|
105
109
|
|
106
110
|
@CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL)
|
107
|
-
@CONF[:AUTO_INDENT] =
|
111
|
+
@CONF[:AUTO_INDENT] = true
|
108
112
|
|
109
|
-
@CONF[:CONTEXT_MODE] =
|
113
|
+
@CONF[:CONTEXT_MODE] = 4 # use a copy of TOPLEVEL_BINDING
|
110
114
|
@CONF[:SINGLE_IRB] = false
|
111
115
|
|
116
|
+
@CONF[:MEASURE] = false
|
117
|
+
@CONF[:MEASURE_PROC] = {}
|
118
|
+
@CONF[:MEASURE_PROC][:TIME] = proc { |context, code, line_no, &block|
|
119
|
+
time = Time.now
|
120
|
+
result = block.()
|
121
|
+
now = Time.now
|
122
|
+
puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE]
|
123
|
+
result
|
124
|
+
}
|
125
|
+
# arg can be either a symbol for the mode (:cpu, :wall, ..) or a hash for
|
126
|
+
# a more complete configuration.
|
127
|
+
# See https://github.com/tmm1/stackprof#all-options.
|
128
|
+
@CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, arg, &block|
|
129
|
+
return block.() unless IRB.conf[:MEASURE]
|
130
|
+
success = false
|
131
|
+
begin
|
132
|
+
require 'stackprof'
|
133
|
+
success = true
|
134
|
+
rescue LoadError
|
135
|
+
puts 'Please run "gem install stackprof" before measuring by StackProf.'
|
136
|
+
end
|
137
|
+
if success
|
138
|
+
result = nil
|
139
|
+
arg = { mode: arg || :cpu } unless arg.is_a?(Hash)
|
140
|
+
stackprof_result = StackProf.run(**arg) do
|
141
|
+
result = block.()
|
142
|
+
end
|
143
|
+
case stackprof_result
|
144
|
+
when File
|
145
|
+
puts "StackProf report saved to #{stackprof_result.path}"
|
146
|
+
when Hash
|
147
|
+
StackProf::Report.new(stackprof_result).print_text
|
148
|
+
else
|
149
|
+
puts "Stackprof ran with #{arg.inspect}"
|
150
|
+
end
|
151
|
+
result
|
152
|
+
else
|
153
|
+
block.()
|
154
|
+
end
|
155
|
+
}
|
156
|
+
@CONF[:MEASURE_CALLBACKS] = []
|
157
|
+
|
112
158
|
@CONF[:LC_MESSAGES] = Locale.new
|
113
159
|
|
114
160
|
@CONF[:AT_EXIT] = []
|
161
|
+
end
|
115
162
|
|
116
|
-
|
163
|
+
def IRB.set_measure_callback(type = nil, arg = nil, &block)
|
164
|
+
added = nil
|
165
|
+
if type
|
166
|
+
type_sym = type.upcase.to_sym
|
167
|
+
if IRB.conf[:MEASURE_PROC][type_sym]
|
168
|
+
added = [type_sym, IRB.conf[:MEASURE_PROC][type_sym], arg]
|
169
|
+
end
|
170
|
+
elsif IRB.conf[:MEASURE_PROC][:CUSTOM]
|
171
|
+
added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM], arg]
|
172
|
+
elsif block_given?
|
173
|
+
added = [:BLOCK, block, arg]
|
174
|
+
found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
|
175
|
+
if found
|
176
|
+
found[1] = block
|
177
|
+
return added
|
178
|
+
else
|
179
|
+
IRB.conf[:MEASURE_CALLBACKS] << added
|
180
|
+
return added
|
181
|
+
end
|
182
|
+
else
|
183
|
+
added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg]
|
184
|
+
end
|
185
|
+
if added
|
186
|
+
found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] }
|
187
|
+
if found
|
188
|
+
# already added
|
189
|
+
nil
|
190
|
+
else
|
191
|
+
IRB.conf[:MEASURE_CALLBACKS] << added if added
|
192
|
+
added
|
193
|
+
end
|
194
|
+
else
|
195
|
+
nil
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def IRB.unset_measure_callback(type = nil)
|
200
|
+
if type.nil?
|
201
|
+
IRB.conf[:MEASURE_CALLBACKS].clear
|
202
|
+
else
|
203
|
+
type_sym = type.upcase.to_sym
|
204
|
+
IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, | t == type_sym }
|
205
|
+
end
|
117
206
|
end
|
118
207
|
|
119
208
|
def IRB.init_error
|
@@ -131,7 +220,7 @@ module IRB # :nodoc:
|
|
131
220
|
$DEBUG = true
|
132
221
|
$VERBOSE = true
|
133
222
|
when "-w"
|
134
|
-
$VERBOSE = true
|
223
|
+
Warning[:deprecated] = $VERBOSE = true
|
135
224
|
when /^-W(.+)?/
|
136
225
|
opt = $1 || argv.shift
|
137
226
|
case opt
|
@@ -140,7 +229,7 @@ module IRB # :nodoc:
|
|
140
229
|
when "1"
|
141
230
|
$VERBOSE = false
|
142
231
|
else
|
143
|
-
$VERBOSE = true
|
232
|
+
Warning[:deprecated] = $VERBOSE = true
|
144
233
|
end
|
145
234
|
when /^-r(.+)?/
|
146
235
|
opt = $1 || argv.shift
|
@@ -161,18 +250,39 @@ module IRB # :nodoc:
|
|
161
250
|
end
|
162
251
|
when "--noinspect"
|
163
252
|
@CONF[:INSPECT_MODE] = false
|
164
|
-
when "--readline"
|
165
|
-
@CONF[:
|
166
|
-
when "--noreadline"
|
167
|
-
@CONF[:
|
253
|
+
when "--singleline", "--readline", "--legacy"
|
254
|
+
@CONF[:USE_SINGLELINE] = true
|
255
|
+
when "--nosingleline", "--noreadline"
|
256
|
+
@CONF[:USE_SINGLELINE] = false
|
257
|
+
when "--multiline", "--reidline"
|
258
|
+
@CONF[:USE_MULTILINE] = true
|
259
|
+
when "--nomultiline", "--noreidline"
|
260
|
+
@CONF[:USE_MULTILINE] = false
|
261
|
+
when /^--extra-doc-dir(?:=(.+))?/
|
262
|
+
opt = $1 || argv.shift
|
263
|
+
@CONF[:EXTRA_DOC_DIRS] << opt
|
168
264
|
when "--echo"
|
169
265
|
@CONF[:ECHO] = true
|
170
266
|
when "--noecho"
|
171
267
|
@CONF[:ECHO] = false
|
268
|
+
when "--echo-on-assignment"
|
269
|
+
@CONF[:ECHO_ON_ASSIGNMENT] = true
|
270
|
+
when "--noecho-on-assignment"
|
271
|
+
@CONF[:ECHO_ON_ASSIGNMENT] = false
|
272
|
+
when "--truncate-echo-on-assignment"
|
273
|
+
@CONF[:ECHO_ON_ASSIGNMENT] = :truncate
|
172
274
|
when "--verbose"
|
173
275
|
@CONF[:VERBOSE] = true
|
174
276
|
when "--noverbose"
|
175
277
|
@CONF[:VERBOSE] = false
|
278
|
+
when "--colorize"
|
279
|
+
@CONF[:USE_COLORIZE] = true
|
280
|
+
when "--nocolorize"
|
281
|
+
@CONF[:USE_COLORIZE] = false
|
282
|
+
when "--autocomplete"
|
283
|
+
@CONF[:USE_AUTOCOMPLETE] = true
|
284
|
+
when "--noautocomplete"
|
285
|
+
@CONF[:USE_AUTOCOMPLETE] = false
|
176
286
|
when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/
|
177
287
|
opt = $1 || argv.shift
|
178
288
|
prompt_mode = opt.upcase.tr("-", "_").intern
|
@@ -191,8 +301,6 @@ module IRB # :nodoc:
|
|
191
301
|
@CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i
|
192
302
|
when "--single-irb"
|
193
303
|
@CONF[:SINGLE_IRB] = true
|
194
|
-
when /^--irb_debug(?:=(.+))?/
|
195
|
-
@CONF[:DEBUG_LEVEL] = ($1 || argv.shift).to_i
|
196
304
|
when "-v", "--version"
|
197
305
|
print IRB.version, "\n"
|
198
306
|
exit 0
|
@@ -207,18 +315,18 @@ module IRB # :nodoc:
|
|
207
315
|
end
|
208
316
|
break
|
209
317
|
when /^-/
|
210
|
-
|
318
|
+
fail UnrecognizedSwitch, opt
|
211
319
|
else
|
212
320
|
@CONF[:SCRIPT] = opt
|
213
321
|
$0 = opt
|
214
322
|
break
|
215
323
|
end
|
216
324
|
end
|
325
|
+
|
217
326
|
load_path.collect! do |path|
|
218
327
|
/\A\.\// =~ path ? path : File.expand_path(path)
|
219
328
|
end
|
220
329
|
$LOAD_PATH.unshift(*load_path)
|
221
|
-
|
222
330
|
end
|
223
331
|
|
224
332
|
# running config
|
@@ -252,7 +360,7 @@ module IRB # :nodoc:
|
|
252
360
|
when String
|
253
361
|
return rc_file
|
254
362
|
else
|
255
|
-
|
363
|
+
fail IllegalRCNameGenerator
|
256
364
|
end
|
257
365
|
end
|
258
366
|
|
@@ -261,14 +369,23 @@ module IRB # :nodoc:
|
|
261
369
|
if irbrc = ENV["IRBRC"]
|
262
370
|
yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc}
|
263
371
|
end
|
372
|
+
if xdg_config_home = ENV["XDG_CONFIG_HOME"]
|
373
|
+
irb_home = File.join(xdg_config_home, "irb")
|
374
|
+
unless File.exist? irb_home
|
375
|
+
require 'fileutils'
|
376
|
+
FileUtils.mkdir_p irb_home
|
377
|
+
end
|
378
|
+
yield proc{|rc| irb_home + "/irb#{rc}"}
|
379
|
+
end
|
264
380
|
if home = ENV["HOME"]
|
265
381
|
yield proc{|rc| home+"/.irb#{rc}"}
|
266
382
|
end
|
267
|
-
|
268
|
-
yield proc{|rc|
|
269
|
-
yield proc{|rc|
|
270
|
-
yield proc{|rc|
|
271
|
-
yield proc{|rc|
|
383
|
+
current_dir = Dir.pwd
|
384
|
+
yield proc{|rc| current_dir+"/.config/irb/irb#{rc}"}
|
385
|
+
yield proc{|rc| current_dir+"/.irb#{rc}"}
|
386
|
+
yield proc{|rc| current_dir+"/irb#{rc.sub(/\A_?/, '.')}"}
|
387
|
+
yield proc{|rc| current_dir+"/_irb#{rc}"}
|
388
|
+
yield proc{|rc| current_dir+"/$irb#{rc}"}
|
272
389
|
end
|
273
390
|
|
274
391
|
# loading modules
|
@@ -286,15 +403,18 @@ module IRB # :nodoc:
|
|
286
403
|
DefaultEncodings = Struct.new(:external, :internal)
|
287
404
|
class << IRB
|
288
405
|
private
|
289
|
-
def set_encoding(extern, intern = nil)
|
406
|
+
def set_encoding(extern, intern = nil, override: true)
|
290
407
|
verbose, $VERBOSE = $VERBOSE, nil
|
291
408
|
Encoding.default_external = extern unless extern.nil? || extern.empty?
|
292
409
|
Encoding.default_internal = intern unless intern.nil? || intern.empty?
|
293
|
-
@CONF[:ENCODINGS] = IRB::DefaultEncodings.new(extern, intern)
|
294
410
|
[$stdin, $stdout, $stderr].each do |io|
|
295
411
|
io.set_encoding(extern, intern)
|
296
412
|
end
|
297
|
-
|
413
|
+
if override
|
414
|
+
@CONF[:LC_MESSAGES].instance_variable_set(:@override_encoding, extern)
|
415
|
+
else
|
416
|
+
@CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern)
|
417
|
+
end
|
298
418
|
ensure
|
299
419
|
$VERBOSE = verbose
|
300
420
|
end
|
data/lib/irb/input-method.rb
CHANGED
@@ -11,6 +11,10 @@
|
|
11
11
|
#
|
12
12
|
require_relative 'src_encoding'
|
13
13
|
require_relative 'magic-file'
|
14
|
+
require_relative 'completion'
|
15
|
+
require 'io/console'
|
16
|
+
require 'reline'
|
17
|
+
require 'rdoc'
|
14
18
|
|
15
19
|
module IRB
|
16
20
|
STDIN_FILE_NAME = "(line)" # :nodoc:
|
@@ -30,10 +34,18 @@ module IRB
|
|
30
34
|
#
|
31
35
|
# See IO#gets for more information.
|
32
36
|
def gets
|
33
|
-
|
37
|
+
fail NotImplementedError, "gets"
|
34
38
|
end
|
35
39
|
public :gets
|
36
40
|
|
41
|
+
def winsize
|
42
|
+
if instance_variable_defined?(:@stdout)
|
43
|
+
@stdout.winsize
|
44
|
+
else
|
45
|
+
[24, 80]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
37
49
|
# Whether this input method is still readable when there is no more data to
|
38
50
|
# read.
|
39
51
|
#
|
@@ -41,6 +53,11 @@ module IRB
|
|
41
53
|
def readable_after_eof?
|
42
54
|
false
|
43
55
|
end
|
56
|
+
|
57
|
+
# For debug message
|
58
|
+
def inspect
|
59
|
+
'Abstract InputMethod'
|
60
|
+
end
|
44
61
|
end
|
45
62
|
|
46
63
|
class StdioInputMethod < InputMethod
|
@@ -67,7 +84,15 @@ module IRB
|
|
67
84
|
#
|
68
85
|
# See IO#eof? for more information.
|
69
86
|
def eof?
|
70
|
-
@stdin.
|
87
|
+
rs, = IO.select([@stdin], [], [], 0.00001)
|
88
|
+
if rs and rs[0]
|
89
|
+
c = @stdin.getc
|
90
|
+
result = c.nil? ? true : false
|
91
|
+
@stdin.ungetc(c) unless c.nil?
|
92
|
+
result
|
93
|
+
else # buffer is empty
|
94
|
+
false
|
95
|
+
end
|
71
96
|
end
|
72
97
|
|
73
98
|
# Whether this input method is still readable when there is no more data to
|
@@ -91,14 +116,31 @@ module IRB
|
|
91
116
|
def encoding
|
92
117
|
@stdin.external_encoding
|
93
118
|
end
|
119
|
+
|
120
|
+
# For debug message
|
121
|
+
def inspect
|
122
|
+
'StdioInputMethod'
|
123
|
+
end
|
94
124
|
end
|
95
125
|
|
96
126
|
# Use a File for IO with irb, see InputMethod
|
97
127
|
class FileInputMethod < InputMethod
|
128
|
+
class << self
|
129
|
+
def open(file, &block)
|
130
|
+
begin
|
131
|
+
io = new(file)
|
132
|
+
block.call(io)
|
133
|
+
ensure
|
134
|
+
io&.close
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
98
139
|
# Creates a new input method object
|
99
140
|
def initialize(file)
|
100
141
|
super
|
101
142
|
@io = IRB::MagicFile.open(file)
|
143
|
+
@external_encoding = @io.external_encoding
|
102
144
|
end
|
103
145
|
# The file name of this input method, usually given during initialization.
|
104
146
|
attr_reader :file_name
|
@@ -108,7 +150,7 @@ module IRB
|
|
108
150
|
#
|
109
151
|
# See IO#eof? for more information.
|
110
152
|
def eof?
|
111
|
-
@io.eof?
|
153
|
+
@io.closed? || @io.eof?
|
112
154
|
end
|
113
155
|
|
114
156
|
# Reads the next line from this input method.
|
@@ -116,22 +158,39 @@ module IRB
|
|
116
158
|
# See IO#gets for more information.
|
117
159
|
def gets
|
118
160
|
print @prompt
|
119
|
-
|
120
|
-
l
|
161
|
+
@io.gets
|
121
162
|
end
|
122
163
|
|
123
164
|
# The external encoding for standard input.
|
124
165
|
def encoding
|
125
|
-
@
|
166
|
+
@external_encoding
|
167
|
+
end
|
168
|
+
|
169
|
+
# For debug message
|
170
|
+
def inspect
|
171
|
+
'FileInputMethod'
|
172
|
+
end
|
173
|
+
|
174
|
+
def close
|
175
|
+
@io.close
|
126
176
|
end
|
127
177
|
end
|
128
178
|
|
129
179
|
begin
|
130
|
-
require "readline"
|
131
180
|
class ReadlineInputMethod < InputMethod
|
132
|
-
|
181
|
+
def self.initialize_readline
|
182
|
+
require "readline"
|
183
|
+
rescue LoadError
|
184
|
+
else
|
185
|
+
include ::Readline
|
186
|
+
end
|
187
|
+
|
133
188
|
# Creates a new input method object using Readline
|
134
189
|
def initialize
|
190
|
+
self.class.initialize_readline
|
191
|
+
if Readline.respond_to?(:encoding_system_needs)
|
192
|
+
IRB.__send__(:set_encoding, Readline.encoding_system_needs.name, override: false)
|
193
|
+
end
|
135
194
|
super
|
136
195
|
|
137
196
|
@line_no = 0
|
@@ -140,6 +199,12 @@ module IRB
|
|
140
199
|
|
141
200
|
@stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
142
201
|
@stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
202
|
+
|
203
|
+
if Readline.respond_to?("basic_word_break_characters=")
|
204
|
+
Readline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
|
205
|
+
end
|
206
|
+
Readline.completion_append_character = nil
|
207
|
+
Readline.completion_proc = IRB::InputCompletor::CompletionProc
|
143
208
|
end
|
144
209
|
|
145
210
|
# Reads the next line from this input method.
|
@@ -186,7 +251,220 @@ module IRB
|
|
186
251
|
def encoding
|
187
252
|
@stdin.external_encoding
|
188
253
|
end
|
254
|
+
|
255
|
+
# For debug message
|
256
|
+
def inspect
|
257
|
+
readline_impl = (defined?(Reline) && Readline == Reline) ? 'Reline' : 'ext/readline'
|
258
|
+
str = "ReadlineInputMethod with #{readline_impl} #{Readline::VERSION}"
|
259
|
+
inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
|
260
|
+
str += " and #{inputrc_path}" if File.exist?(inputrc_path)
|
261
|
+
str
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
class ReidlineInputMethod < InputMethod
|
267
|
+
include Reline
|
268
|
+
|
269
|
+
# Creates a new input method object using Reline
|
270
|
+
def initialize
|
271
|
+
IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false)
|
272
|
+
super
|
273
|
+
|
274
|
+
@line_no = 0
|
275
|
+
@line = []
|
276
|
+
@eof = false
|
277
|
+
|
278
|
+
@stdin = ::IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
279
|
+
@stdout = ::IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
|
280
|
+
|
281
|
+
if Reline.respond_to?("basic_word_break_characters=")
|
282
|
+
Reline.basic_word_break_characters = IRB::InputCompletor::BASIC_WORD_BREAK_CHARACTERS
|
283
|
+
end
|
284
|
+
Reline.completion_append_character = nil
|
285
|
+
Reline.completer_quote_characters = ''
|
286
|
+
Reline.completion_proc = IRB::InputCompletor::CompletionProc
|
287
|
+
Reline.output_modifier_proc =
|
288
|
+
if IRB.conf[:USE_COLORIZE]
|
289
|
+
proc do |output, complete: |
|
290
|
+
next unless IRB::Color.colorable?
|
291
|
+
IRB::Color.colorize_code(output, complete: complete)
|
292
|
+
end
|
293
|
+
else
|
294
|
+
proc do |output|
|
295
|
+
Reline::Unicode.escape_for_print(output)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
Reline.dig_perfect_match_proc = IRB::InputCompletor::PerfectMatchedProc
|
299
|
+
Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
|
300
|
+
if IRB.conf[:USE_AUTOCOMPLETE]
|
301
|
+
Reline.add_dialog_proc(:show_doc, SHOW_DOC_DIALOG, Reline::DEFAULT_DIALOG_CONTEXT)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def check_termination(&block)
|
306
|
+
@check_termination_proc = block
|
307
|
+
end
|
308
|
+
|
309
|
+
def dynamic_prompt(&block)
|
310
|
+
@prompt_proc = block
|
311
|
+
end
|
312
|
+
|
313
|
+
def auto_indent(&block)
|
314
|
+
@auto_indent_proc = block
|
315
|
+
end
|
316
|
+
|
317
|
+
SHOW_DOC_DIALOG = ->() {
|
318
|
+
dialog.trap_key = nil
|
319
|
+
alt_d = [
|
320
|
+
[Reline::Key.new(nil, 0xE4, true)], # Normal Alt+d.
|
321
|
+
[27, 100], # Normal Alt+d when convert-meta isn't used.
|
322
|
+
[195, 164], # The "ä" that appears when Alt+d is pressed on xterm.
|
323
|
+
[226, 136, 130] # The "∂" that appears when Alt+d in pressed on iTerm2.
|
324
|
+
]
|
325
|
+
|
326
|
+
if just_cursor_moving and completion_journey_data.nil?
|
327
|
+
return nil
|
328
|
+
end
|
329
|
+
cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4)
|
330
|
+
return nil if result.nil? or pointer.nil? or pointer < 0
|
331
|
+
name = result[pointer]
|
332
|
+
name = IRB::InputCompletor.retrieve_completion_data(name, doc_namespace: true)
|
333
|
+
|
334
|
+
options = {}
|
335
|
+
options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty?
|
336
|
+
driver = RDoc::RI::Driver.new(options)
|
337
|
+
|
338
|
+
if key.match?(dialog.name)
|
339
|
+
begin
|
340
|
+
driver.display_names([name])
|
341
|
+
rescue RDoc::RI::Driver::NotFoundError
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
begin
|
346
|
+
name = driver.expand_name(name)
|
347
|
+
rescue RDoc::RI::Driver::NotFoundError
|
348
|
+
return nil
|
349
|
+
rescue
|
350
|
+
return nil # unknown error
|
351
|
+
end
|
352
|
+
doc = nil
|
353
|
+
used_for_class = false
|
354
|
+
if not name =~ /#|\./
|
355
|
+
found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name)
|
356
|
+
if not found.empty?
|
357
|
+
doc = driver.class_document(name, found, klasses, includes, extends)
|
358
|
+
used_for_class = true
|
359
|
+
end
|
360
|
+
end
|
361
|
+
unless used_for_class
|
362
|
+
doc = RDoc::Markup::Document.new
|
363
|
+
begin
|
364
|
+
driver.add_method(doc, name)
|
365
|
+
rescue RDoc::RI::Driver::NotFoundError
|
366
|
+
doc = nil
|
367
|
+
rescue
|
368
|
+
return nil # unknown error
|
369
|
+
end
|
370
|
+
end
|
371
|
+
return nil if doc.nil?
|
372
|
+
width = 40
|
373
|
+
|
374
|
+
right_x = cursor_pos_to_render.x + autocomplete_dialog.width
|
375
|
+
if right_x + width > screen_width
|
376
|
+
right_width = screen_width - (right_x + 1)
|
377
|
+
left_x = autocomplete_dialog.column - width
|
378
|
+
left_x = 0 if left_x < 0
|
379
|
+
left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width
|
380
|
+
if right_width.positive? and left_width.positive?
|
381
|
+
if right_width >= left_width
|
382
|
+
width = right_width
|
383
|
+
x = right_x
|
384
|
+
else
|
385
|
+
width = left_width
|
386
|
+
x = left_x
|
387
|
+
end
|
388
|
+
elsif right_width.positive? and left_width <= 0
|
389
|
+
width = right_width
|
390
|
+
x = right_x
|
391
|
+
elsif right_width <= 0 and left_width.positive?
|
392
|
+
width = left_width
|
393
|
+
x = left_x
|
394
|
+
else # Both are negative width.
|
395
|
+
return nil
|
396
|
+
end
|
397
|
+
else
|
398
|
+
x = right_x
|
399
|
+
end
|
400
|
+
formatter = RDoc::Markup::ToAnsi.new
|
401
|
+
formatter.width = width
|
402
|
+
dialog.trap_key = alt_d
|
403
|
+
message = 'Press Alt+d to read the full document'
|
404
|
+
contents = [message] + doc.accept(formatter).split("\n")
|
405
|
+
|
406
|
+
y = cursor_pos_to_render.y
|
407
|
+
DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49')
|
408
|
+
}
|
409
|
+
|
410
|
+
# Reads the next line from this input method.
|
411
|
+
#
|
412
|
+
# See IO#gets for more information.
|
413
|
+
def gets
|
414
|
+
Reline.input = @stdin
|
415
|
+
Reline.output = @stdout
|
416
|
+
Reline.prompt_proc = @prompt_proc
|
417
|
+
Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc
|
418
|
+
if l = readmultiline(@prompt, false, &@check_termination_proc)
|
419
|
+
HISTORY.push(l) if !l.empty?
|
420
|
+
@line[@line_no += 1] = l + "\n"
|
421
|
+
else
|
422
|
+
@eof = true
|
423
|
+
l
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
# Whether the end of this input method has been reached, returns +true+
|
428
|
+
# if there is no more data to read.
|
429
|
+
#
|
430
|
+
# See IO#eof? for more information.
|
431
|
+
def eof?
|
432
|
+
@eof
|
433
|
+
end
|
434
|
+
|
435
|
+
# Whether this input method is still readable when there is no more data to
|
436
|
+
# read.
|
437
|
+
#
|
438
|
+
# See IO#eof for more information.
|
439
|
+
def readable_after_eof?
|
440
|
+
true
|
441
|
+
end
|
442
|
+
|
443
|
+
# Returns the current line number for #io.
|
444
|
+
#
|
445
|
+
# #line counts the number of times #gets is called.
|
446
|
+
#
|
447
|
+
# See IO#lineno for more information.
|
448
|
+
def line(line_no)
|
449
|
+
@line[line_no]
|
450
|
+
end
|
451
|
+
|
452
|
+
# The external encoding for standard input.
|
453
|
+
def encoding
|
454
|
+
@stdin.external_encoding
|
455
|
+
end
|
456
|
+
|
457
|
+
# For debug message
|
458
|
+
def inspect
|
459
|
+
config = Reline::Config.new
|
460
|
+
str = "ReidlineInputMethod with Reline #{Reline::VERSION}"
|
461
|
+
if config.respond_to?(:inputrc_path)
|
462
|
+
inputrc_path = File.expand_path(config.inputrc_path)
|
463
|
+
else
|
464
|
+
inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc')
|
465
|
+
end
|
466
|
+
str += " and #{inputrc_path}" if File.exist?(inputrc_path)
|
467
|
+
str
|
189
468
|
end
|
190
|
-
rescue LoadError
|
191
469
|
end
|
192
470
|
end
|
data/lib/irb/inspector.rb
CHANGED
@@ -100,18 +100,27 @@ module IRB # :nodoc:
|
|
100
100
|
# Proc to call when the input is evaluated and output in irb.
|
101
101
|
def inspect_value(v)
|
102
102
|
@inspect.call(v)
|
103
|
+
rescue
|
104
|
+
puts "(Object doesn't support #inspect)"
|
105
|
+
''
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
106
109
|
Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s}
|
107
|
-
Inspector.def_inspector([
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
110
|
+
Inspector.def_inspector([:p, :inspect]){|v|
|
111
|
+
result = v.inspect
|
112
|
+
if IRB.conf[:MAIN_CONTEXT]&.use_colorize? && Color.inspect_colorable?(v)
|
113
|
+
result = Color.colorize_code(result)
|
114
|
+
end
|
115
|
+
result
|
116
|
+
}
|
117
|
+
Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require "irb/color_printer"}){|v|
|
118
|
+
if IRB.conf[:MAIN_CONTEXT]&.use_colorize?
|
119
|
+
IRB::ColorPrinter.pp(v, '').chomp
|
120
|
+
else
|
121
|
+
v.pretty_inspect.chomp
|
112
122
|
end
|
113
123
|
}
|
114
|
-
Inspector.def_inspector([:pp, :pretty_inspect], proc{require "pp"}){|v| v.pretty_inspect.chomp}
|
115
124
|
Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
|
116
125
|
begin
|
117
126
|
YAML.dump(v)
|
@@ -125,8 +134,3 @@ module IRB # :nodoc:
|
|
125
134
|
Marshal.dump(v)
|
126
135
|
}
|
127
136
|
end
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|