irb 1.14.0 → 1.14.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -2
- data/lib/irb/command/base.rb +10 -8
- data/lib/irb/command/debug.rb +8 -6
- data/lib/irb/command/help.rb +1 -1
- data/lib/irb/command/internal_helpers.rb +1 -1
- data/lib/irb/command/ls.rb +23 -11
- data/lib/irb/completion.rb +12 -5
- data/lib/irb/context.rb +60 -17
- data/lib/irb/debug/ui.rb +2 -4
- data/lib/irb/debug.rb +6 -10
- data/lib/irb/default_commands.rb +15 -7
- data/lib/irb/easter-egg.rb +10 -6
- data/lib/irb/history.rb +80 -55
- data/lib/irb/init.rb +1 -1
- data/lib/irb/input-method.rb +19 -18
- data/lib/irb/inspector.rb +31 -30
- data/lib/irb/lc/ja/help-message +4 -4
- data/lib/irb/nesting_parser.rb +196 -194
- data/lib/irb/pager.rb +10 -1
- data/lib/irb/ruby-lex.rb +84 -82
- data/lib/irb/ruby_logo.aa +75 -37
- data/lib/irb/source_finder.rb +3 -4
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +13 -31
- data/lib/irb.rb +44 -67
- data/man/irb.1 +35 -2
- metadata +2 -2
data/lib/irb/history.rb
CHANGED
@@ -1,6 +1,32 @@
|
|
1
1
|
require "pathname"
|
2
2
|
|
3
3
|
module IRB
|
4
|
+
module History
|
5
|
+
class << self
|
6
|
+
# Integer representation of <code>IRB.conf[:HISTORY_FILE]</code>.
|
7
|
+
def save_history
|
8
|
+
IRB.conf[:SAVE_HISTORY].to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def save_history?
|
12
|
+
!save_history.zero?
|
13
|
+
end
|
14
|
+
|
15
|
+
def infinite?
|
16
|
+
save_history.negative?
|
17
|
+
end
|
18
|
+
|
19
|
+
# Might be nil when HOME and XDG_CONFIG_HOME are not available.
|
20
|
+
def history_file
|
21
|
+
if (history_file = IRB.conf[:HISTORY_FILE])
|
22
|
+
File.expand_path(history_file)
|
23
|
+
else
|
24
|
+
IRB.rc_file("_history")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
4
30
|
module HistorySavingAbility # :nodoc:
|
5
31
|
def support_history_saving?
|
6
32
|
true
|
@@ -11,76 +37,75 @@ module IRB
|
|
11
37
|
end
|
12
38
|
|
13
39
|
def load_history
|
40
|
+
history_file = History.history_file
|
41
|
+
return unless File.exist?(history_file.to_s)
|
42
|
+
|
14
43
|
history = self.class::HISTORY
|
15
44
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
history.last << "\n" << l
|
27
|
-
else
|
28
|
-
history << l
|
29
|
-
end
|
30
|
-
}
|
31
|
-
end
|
32
|
-
@loaded_history_lines = history.size
|
33
|
-
@loaded_history_mtime = File.mtime(history_file)
|
45
|
+
File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
|
46
|
+
f.each { |l|
|
47
|
+
l = l.chomp
|
48
|
+
if self.class == RelineInputMethod and history.last&.end_with?("\\")
|
49
|
+
history.last.delete_suffix!("\\")
|
50
|
+
history.last << "\n" << l
|
51
|
+
else
|
52
|
+
history << l
|
53
|
+
end
|
54
|
+
}
|
34
55
|
end
|
56
|
+
@loaded_history_lines = history.size
|
57
|
+
@loaded_history_mtime = File.mtime(history_file)
|
35
58
|
end
|
36
59
|
|
37
60
|
def save_history
|
61
|
+
return unless History.save_history?
|
62
|
+
return unless (history_file = History.history_file)
|
63
|
+
unless ensure_history_file_writable(history_file)
|
64
|
+
warn <<~WARN
|
65
|
+
Can't write history to #{History.history_file.inspect} due to insufficient permissions.
|
66
|
+
Please verify the value of `IRB.conf[:HISTORY_FILE]`. Ensure the folder exists and that both the folder and file (if it exists) are writable.
|
67
|
+
WARN
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
38
71
|
history = self.class::HISTORY.to_a
|
39
72
|
|
40
|
-
if
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
73
|
+
if File.exist?(history_file) &&
|
74
|
+
File.mtime(history_file) != @loaded_history_mtime
|
75
|
+
history = history[@loaded_history_lines..-1] if @loaded_history_lines
|
76
|
+
append_history = true
|
77
|
+
end
|
45
78
|
|
46
|
-
|
47
|
-
|
79
|
+
File.open(history_file, (append_history ? "a" : "w"), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f|
|
80
|
+
hist = history.map { |l| l.scrub.split("\n").join("\\\n") }
|
48
81
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
File.chmod(0600, history_file)
|
53
|
-
end
|
54
|
-
rescue Errno::ENOENT
|
55
|
-
rescue Errno::EPERM
|
56
|
-
return
|
57
|
-
rescue
|
58
|
-
raise
|
82
|
+
unless append_history || History.infinite?
|
83
|
+
# Check size before slicing because array.last(huge_number) raises RangeError.
|
84
|
+
hist = hist.last(History.save_history) if hist.size > History.save_history
|
59
85
|
end
|
60
86
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
append_history = true
|
65
|
-
end
|
87
|
+
f.puts(hist)
|
88
|
+
end
|
89
|
+
end
|
66
90
|
|
67
|
-
|
68
|
-
unless Dir.exist?(pathname.dirname)
|
69
|
-
warn "Warning: The directory to save IRB's history file does not exist. Please double check `IRB.conf[:HISTORY_FILE]`'s value."
|
70
|
-
return
|
71
|
-
end
|
91
|
+
private
|
72
92
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
93
|
+
# Returns boolean whether writing to +history_file+ will be possible.
|
94
|
+
# Permissions of already existing +history_file+ are changed to
|
95
|
+
# owner-only-readable if necessary [BUG #7694].
|
96
|
+
def ensure_history_file_writable(history_file)
|
97
|
+
history_file = Pathname.new(history_file)
|
98
|
+
|
99
|
+
return false unless history_file.dirname.writable?
|
100
|
+
return true unless history_file.exist?
|
101
|
+
|
102
|
+
begin
|
103
|
+
if history_file.stat.mode & 0o66 != 0
|
104
|
+
history_file.chmod 0o600
|
83
105
|
end
|
106
|
+
true
|
107
|
+
rescue Errno::EPERM # no permissions
|
108
|
+
false
|
84
109
|
end
|
85
110
|
end
|
86
111
|
end
|
data/lib/irb/init.rb
CHANGED
@@ -80,7 +80,7 @@ module IRB # :nodoc:
|
|
80
80
|
@CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod)
|
81
81
|
@CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty?
|
82
82
|
@CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false"
|
83
|
-
@CONF[:COMPLETOR] = ENV
|
83
|
+
@CONF[:COMPLETOR] = ENV["IRB_COMPLETOR"]&.to_sym
|
84
84
|
@CONF[:INSPECT_MODE] = true
|
85
85
|
@CONF[:USE_TRACER] = false
|
86
86
|
@CONF[:USE_LOADER] = false
|
data/lib/irb/input-method.rb
CHANGED
@@ -67,7 +67,9 @@ module IRB
|
|
67
67
|
#
|
68
68
|
# See IO#gets for more information.
|
69
69
|
def gets
|
70
|
-
|
70
|
+
# Workaround for debug compatibility test https://github.com/ruby/debug/pull/1100
|
71
|
+
puts if ENV['RUBY_DEBUG_TEST_UI']
|
72
|
+
|
71
73
|
print @prompt
|
72
74
|
line = @stdin.gets
|
73
75
|
@line[@line_no += 1] = line
|
@@ -171,11 +173,13 @@ module IRB
|
|
171
173
|
end
|
172
174
|
|
173
175
|
class ReadlineInputMethod < StdioInputMethod
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
176
|
+
class << self
|
177
|
+
def initialize_readline
|
178
|
+
require "readline"
|
179
|
+
rescue LoadError
|
180
|
+
else
|
181
|
+
include ::Readline
|
182
|
+
end
|
179
183
|
end
|
180
184
|
|
181
185
|
include HistorySavingAbility
|
@@ -263,18 +267,9 @@ module IRB
|
|
263
267
|
@completion_params = [preposing, target, postposing, bind]
|
264
268
|
@completor.completion_candidates(preposing, target, postposing, bind: bind)
|
265
269
|
}
|
266
|
-
Reline.output_modifier_proc =
|
267
|
-
|
268
|
-
|
269
|
-
next unless IRB::Color.colorable?
|
270
|
-
lvars = IRB.CurrentContext&.local_variables || []
|
271
|
-
IRB::Color.colorize_code(output, complete: complete, local_variables: lvars)
|
272
|
-
end
|
273
|
-
else
|
274
|
-
proc do |output|
|
275
|
-
Reline::Unicode.escape_for_print(output)
|
276
|
-
end
|
277
|
-
end
|
270
|
+
Reline.output_modifier_proc = proc do |input, complete:|
|
271
|
+
IRB.CurrentContext.colorize_input(input, complete: complete)
|
272
|
+
end
|
278
273
|
Reline.dig_perfect_match_proc = ->(matched) { display_document(matched) }
|
279
274
|
Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE]
|
280
275
|
|
@@ -353,9 +348,15 @@ module IRB
|
|
353
348
|
if show_easter_egg
|
354
349
|
IRB.__send__(:easter_egg)
|
355
350
|
else
|
351
|
+
# RDoc::RI::Driver#display_names uses pager command internally.
|
352
|
+
# Some pager command like `more` doesn't use alternate screen
|
353
|
+
# so we need to turn on and off alternate screen manually.
|
356
354
|
begin
|
355
|
+
print "\e[?1049h"
|
357
356
|
driver.display_names([name])
|
358
357
|
rescue RDoc::RI::Driver::NotFoundError
|
358
|
+
ensure
|
359
|
+
print "\e[?1049l"
|
359
360
|
end
|
360
361
|
end
|
361
362
|
end
|
data/lib/irb/inspector.rb
CHANGED
@@ -6,7 +6,6 @@
|
|
6
6
|
|
7
7
|
module IRB # :nodoc:
|
8
8
|
|
9
|
-
|
10
9
|
# Convenience method to create a new Inspector, using the given +inspect+
|
11
10
|
# proc, and optional +init+ proc and passes them to Inspector.new
|
12
11
|
#
|
@@ -43,38 +42,40 @@ module IRB # :nodoc:
|
|
43
42
|
# +:marshal+:: Using Marshal.dump
|
44
43
|
INSPECTORS = {}
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# Example
|
53
|
-
#
|
54
|
-
# Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
|
55
|
-
# Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
|
56
|
-
# Inspector.def_inspector(key, inspector)
|
57
|
-
# Inspector.def_inspector([key1,...], inspector)
|
58
|
-
def self.def_inspector(key, arg=nil, &block)
|
59
|
-
if block_given?
|
60
|
-
inspector = IRB::Inspector(block, arg)
|
61
|
-
else
|
62
|
-
inspector = arg
|
45
|
+
class << self
|
46
|
+
# Determines the inspector to use where +inspector+ is one of the keys passed
|
47
|
+
# during inspector definition.
|
48
|
+
def keys_with_inspector(inspector)
|
49
|
+
INSPECTORS.select{|k, v| v == inspector}.collect{|k, v| k}
|
63
50
|
end
|
64
51
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
52
|
+
# Example
|
53
|
+
#
|
54
|
+
# Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
|
55
|
+
# Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
|
56
|
+
# Inspector.def_inspector(key, inspector)
|
57
|
+
# Inspector.def_inspector([key1,...], inspector)
|
58
|
+
def def_inspector(key, arg=nil, &block)
|
59
|
+
if block_given?
|
60
|
+
inspector = IRB::Inspector(block, arg)
|
61
|
+
else
|
62
|
+
inspector = arg
|
63
|
+
end
|
64
|
+
|
65
|
+
case key
|
66
|
+
when Array
|
67
|
+
for k in key
|
68
|
+
def_inspector(k, inspector)
|
69
|
+
end
|
70
|
+
when Symbol
|
71
|
+
INSPECTORS[key] = inspector
|
72
|
+
INSPECTORS[key.to_s] = inspector
|
73
|
+
when String
|
74
|
+
INSPECTORS[key] = inspector
|
75
|
+
INSPECTORS[key.intern] = inspector
|
76
|
+
else
|
77
|
+
INSPECTORS[key] = inspector
|
69
78
|
end
|
70
|
-
when Symbol
|
71
|
-
INSPECTORS[key] = inspector
|
72
|
-
INSPECTORS[key.to_s] = inspector
|
73
|
-
when String
|
74
|
-
INSPECTORS[key] = inspector
|
75
|
-
INSPECTORS[key.intern] = inspector
|
76
|
-
else
|
77
|
-
INSPECTORS[key] = inspector
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
data/lib/irb/lc/ja/help-message
CHANGED
@@ -8,7 +8,7 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
8
8
|
-w ruby -w と同じ.
|
9
9
|
-W[level=2] ruby -W と同じ.
|
10
10
|
--context-mode n 新しいワークスペースを作成した時に関連する Binding
|
11
|
-
オブジェクトの作成方法を 0 から
|
11
|
+
オブジェクトの作成方法を 0 から 4 のいずれかに設定する.
|
12
12
|
--extra-doc-dir 指定したディレクトリのドキュメントを追加で読み込む.
|
13
13
|
--echo 実行結果を表示する(デフォルト).
|
14
14
|
--noecho 実行結果を表示しない.
|
@@ -33,9 +33,9 @@ Usage: irb.rb [options] [programfile] [arguments]
|
|
33
33
|
補完に正規表現を利用する.
|
34
34
|
--type-completor 補完に型情報を利用する.
|
35
35
|
--prompt prompt-mode/--prompt-mode prompt-mode
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
プロンプトモードを切り替える.
|
37
|
+
現在定義されているプロンプトモードは,
|
38
|
+
default, classic, simple, inf-ruby, xmp, null.
|
39
39
|
--inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特
|
40
40
|
に指定がない限り, シングルラインエディタとマルチラ
|
41
41
|
インエディタは使わなくなる.
|