irb 1.6.4 → 1.8.0
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/Gemfile +1 -0
- data/README.md +135 -14
- data/Rakefile +0 -7
- data/doc/irb/irb.rd.ja +1 -3
- data/irb.gemspec +2 -1
- data/lib/irb/cmd/chws.rb +2 -2
- data/lib/irb/cmd/debug.rb +36 -92
- data/lib/irb/cmd/edit.rb +6 -7
- data/lib/irb/cmd/help.rb +12 -46
- data/lib/irb/cmd/irb_info.rb +14 -18
- data/lib/irb/cmd/ls.rb +17 -7
- data/lib/irb/cmd/nop.rb +4 -8
- data/lib/irb/cmd/pushws.rb +3 -3
- data/lib/irb/cmd/show_cmds.rb +17 -3
- data/lib/irb/cmd/show_doc.rb +48 -0
- data/lib/irb/cmd/show_source.rb +4 -60
- data/lib/irb/cmd/subirb.rb +49 -6
- data/lib/irb/color.rb +2 -0
- data/lib/irb/completion.rb +2 -2
- data/lib/irb/context.rb +52 -21
- data/lib/irb/debug/ui.rb +104 -0
- data/lib/irb/debug.rb +115 -0
- data/lib/irb/ext/{history.rb → eval_history.rb} +4 -4
- data/lib/irb/ext/loader.rb +2 -0
- data/lib/irb/ext/tracer.rb +1 -1
- data/lib/irb/extend-command.rb +7 -5
- data/lib/irb/help.rb +1 -3
- data/lib/irb/{ext/save-history.rb → history.rb} +4 -55
- data/lib/irb/init.rb +4 -10
- data/lib/irb/input-method.rb +65 -131
- data/lib/irb/locale.rb +10 -43
- data/lib/irb/nesting_parser.rb +227 -0
- data/lib/irb/pager.rb +86 -0
- data/lib/irb/ruby-lex.rb +401 -747
- data/lib/irb/source_finder.rb +64 -0
- data/lib/irb/statement.rb +80 -0
- data/lib/irb/version.rb +2 -2
- data/lib/irb/workspace.rb +4 -0
- data/lib/irb.rb +222 -120
- metadata +28 -11
- data/lib/irb/cmd/fork.rb +0 -34
- data/lib/irb/lc/ja/encoding_aliases.rb +0 -13
- data/lib/irb/magic-file.rb +0 -38
- data/lib/irb/src_encoding.rb +0 -7
data/lib/irb/cmd/ls.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "reline"
|
4
|
+
require "stringio"
|
4
5
|
require_relative "nop"
|
6
|
+
require_relative "../pager"
|
5
7
|
require_relative "../color"
|
6
8
|
|
7
9
|
module IRB
|
@@ -33,14 +35,18 @@ module IRB
|
|
33
35
|
o.dump("instance variables", obj.instance_variables)
|
34
36
|
o.dump("class variables", klass.class_variables)
|
35
37
|
o.dump("locals", locals)
|
36
|
-
|
38
|
+
o.print_result
|
37
39
|
end
|
38
40
|
|
39
41
|
def dump_methods(o, klass, obj)
|
40
42
|
singleton_class = begin obj.singleton_class; rescue TypeError; nil end
|
41
43
|
dumped_mods = Array.new
|
44
|
+
ancestors = klass.ancestors
|
45
|
+
ancestors = ancestors.reject { |c| c >= Object } if klass < Object
|
46
|
+
singleton_ancestors = (singleton_class&.ancestors || []).reject { |c| c >= Class }
|
47
|
+
|
42
48
|
# singleton_class' ancestors should be at the front
|
43
|
-
maps = class_method_map(
|
49
|
+
maps = class_method_map(singleton_ancestors, dumped_mods) + class_method_map(ancestors, dumped_mods)
|
44
50
|
maps.each do |mod, methods|
|
45
51
|
name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods"
|
46
52
|
o.dump(name, methods)
|
@@ -49,7 +55,6 @@ module IRB
|
|
49
55
|
|
50
56
|
def class_method_map(classes, dumped_mods)
|
51
57
|
dumped_methods = Array.new
|
52
|
-
classes = classes.reject { |mod| mod >= Object }
|
53
58
|
classes.map do |mod|
|
54
59
|
next if dumped_mods.include? mod
|
55
60
|
|
@@ -74,6 +79,11 @@ module IRB
|
|
74
79
|
def initialize(grep: nil)
|
75
80
|
@grep = grep
|
76
81
|
@line_width = screen_width - MARGIN.length # right padding
|
82
|
+
@io = StringIO.new
|
83
|
+
end
|
84
|
+
|
85
|
+
def print_result
|
86
|
+
Pager.page_content(@io.string)
|
77
87
|
end
|
78
88
|
|
79
89
|
def dump(name, strs)
|
@@ -82,12 +92,12 @@ module IRB
|
|
82
92
|
return if strs.empty?
|
83
93
|
|
84
94
|
# Attempt a single line
|
85
|
-
print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
|
95
|
+
@io.print "#{Color.colorize(name, [:BOLD, :BLUE])}: "
|
86
96
|
if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length)
|
87
|
-
puts strs.join(MARGIN)
|
97
|
+
@io.puts strs.join(MARGIN)
|
88
98
|
return
|
89
99
|
end
|
90
|
-
puts
|
100
|
+
@io.puts
|
91
101
|
|
92
102
|
# Dump with the largest # of columns that fits on a line
|
93
103
|
cols = strs.size
|
@@ -96,7 +106,7 @@ module IRB
|
|
96
106
|
end
|
97
107
|
widths = col_widths(strs, cols: cols)
|
98
108
|
strs.each_slice(cols) do |ss|
|
99
|
-
puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
|
109
|
+
@io.puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join
|
100
110
|
end
|
101
111
|
end
|
102
112
|
|
data/lib/irb/cmd/nop.rb
CHANGED
@@ -30,23 +30,19 @@ module IRB
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def self.execute(
|
34
|
-
command = new(
|
33
|
+
def self.execute(irb_context, *opts, **kwargs, &block)
|
34
|
+
command = new(irb_context)
|
35
35
|
command.execute(*opts, **kwargs, &block)
|
36
36
|
rescue CommandArgumentError => e
|
37
37
|
puts e.message
|
38
38
|
end
|
39
39
|
|
40
|
-
def initialize(
|
41
|
-
@irb_context =
|
40
|
+
def initialize(irb_context)
|
41
|
+
@irb_context = irb_context
|
42
42
|
end
|
43
43
|
|
44
44
|
attr_reader :irb_context
|
45
45
|
|
46
|
-
def irb
|
47
|
-
@irb_context.irb
|
48
|
-
end
|
49
|
-
|
50
46
|
def execute(*opts)
|
51
47
|
#nop
|
52
48
|
end
|
data/lib/irb/cmd/pushws.rb
CHANGED
@@ -12,7 +12,7 @@ module IRB
|
|
12
12
|
|
13
13
|
module ExtendCommand
|
14
14
|
class Workspaces < Nop
|
15
|
-
category "
|
15
|
+
category "Workspace"
|
16
16
|
description "Show workspaces."
|
17
17
|
|
18
18
|
def execute(*obj)
|
@@ -21,7 +21,7 @@ module IRB
|
|
21
21
|
end
|
22
22
|
|
23
23
|
class PushWorkspace < Workspaces
|
24
|
-
category "
|
24
|
+
category "Workspace"
|
25
25
|
description "Push an object to the workspace stack."
|
26
26
|
|
27
27
|
def execute(*obj)
|
@@ -31,7 +31,7 @@ module IRB
|
|
31
31
|
end
|
32
32
|
|
33
33
|
class PopWorkspace < Workspaces
|
34
|
-
category "
|
34
|
+
category "Workspace"
|
35
35
|
description "Pop a workspace from the workspace stack."
|
36
36
|
|
37
37
|
def execute(*obj)
|
data/lib/irb/cmd/show_cmds.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "stringio"
|
4
4
|
require_relative "nop"
|
5
|
+
require_relative "../pager"
|
5
6
|
|
6
7
|
module IRB
|
7
8
|
# :stopdoc:
|
@@ -14,7 +15,17 @@ module IRB
|
|
14
15
|
def execute(*args)
|
15
16
|
commands_info = IRB::ExtendCommandBundle.all_commands_info
|
16
17
|
commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] }
|
17
|
-
|
18
|
+
|
19
|
+
if irb_context.with_debugger
|
20
|
+
# Remove the original "Debugging" category
|
21
|
+
commands_grouped_by_categories.delete("Debugging")
|
22
|
+
# Remove the `help` command as it's delegated to the debugger
|
23
|
+
commands_grouped_by_categories["Context"].delete_if { |cmd| cmd[:display_name] == :help }
|
24
|
+
# Add an empty "Debugging (from debug.gem)" category at the end
|
25
|
+
commands_grouped_by_categories["Debugging (from debug.gem)"] = []
|
26
|
+
end
|
27
|
+
|
28
|
+
longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max
|
18
29
|
|
19
30
|
output = StringIO.new
|
20
31
|
|
@@ -28,9 +39,12 @@ module IRB
|
|
28
39
|
output.puts
|
29
40
|
end
|
30
41
|
|
31
|
-
|
42
|
+
# Append the debugger help at the end
|
43
|
+
if irb_context.with_debugger
|
44
|
+
output.puts DEBUGGER__.help
|
45
|
+
end
|
32
46
|
|
33
|
-
|
47
|
+
Pager.page_content(output.string)
|
34
48
|
end
|
35
49
|
end
|
36
50
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "nop"
|
4
|
+
|
5
|
+
module IRB
|
6
|
+
module ExtendCommand
|
7
|
+
class ShowDoc < Nop
|
8
|
+
class << self
|
9
|
+
def transform_args(args)
|
10
|
+
# Return a string literal as is for backward compatibility
|
11
|
+
if args.empty? || string_literal?(args)
|
12
|
+
args
|
13
|
+
else # Otherwise, consider the input as a String for convenience
|
14
|
+
args.strip.dump
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
category "Context"
|
20
|
+
description "Enter the mode to look up RI documents."
|
21
|
+
|
22
|
+
def execute(*names)
|
23
|
+
require 'rdoc/ri/driver'
|
24
|
+
|
25
|
+
unless ShowDoc.const_defined?(:Ri)
|
26
|
+
opts = RDoc::RI::Driver.process_args([])
|
27
|
+
ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts))
|
28
|
+
end
|
29
|
+
|
30
|
+
if names.empty?
|
31
|
+
Ri.interactive
|
32
|
+
else
|
33
|
+
names.each do |name|
|
34
|
+
begin
|
35
|
+
Ri.display_name(name.to_s)
|
36
|
+
rescue RDoc::RI::Error
|
37
|
+
puts $!.message
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
nil
|
43
|
+
rescue LoadError, SystemExit
|
44
|
+
warn "Can't display document because `rdoc` is not installed."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/irb/cmd/show_source.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "nop"
|
4
|
+
require_relative "../source_finder"
|
4
5
|
require_relative "../color"
|
5
|
-
require_relative "../ruby-lex"
|
6
6
|
|
7
7
|
module IRB
|
8
|
-
# :stopdoc:
|
9
|
-
|
10
8
|
module ExtendCommand
|
11
9
|
class ShowSource < Nop
|
12
10
|
category "Context"
|
@@ -21,50 +19,6 @@ module IRB
|
|
21
19
|
args.strip.dump
|
22
20
|
end
|
23
21
|
end
|
24
|
-
|
25
|
-
def find_source(str, irb_context)
|
26
|
-
case str
|
27
|
-
when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
|
28
|
-
eval(str, irb_context.workspace.binding) # trigger autoload
|
29
|
-
base = irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
|
30
|
-
file, line = base.const_source_location(str)
|
31
|
-
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
|
32
|
-
owner = eval(Regexp.last_match[:owner], irb_context.workspace.binding)
|
33
|
-
method = Regexp.last_match[:method]
|
34
|
-
if owner.respond_to?(:instance_method) && owner.instance_methods.include?(method.to_sym)
|
35
|
-
file, line = owner.instance_method(method).source_location
|
36
|
-
end
|
37
|
-
when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
|
38
|
-
receiver = eval(Regexp.last_match[:receiver] || 'self', irb_context.workspace.binding)
|
39
|
-
method = Regexp.last_match[:method]
|
40
|
-
file, line = receiver.method(method).source_location if receiver.respond_to?(method)
|
41
|
-
end
|
42
|
-
if file && line
|
43
|
-
Source.new(file: file, first_line: line, last_line: find_end(file, line, irb_context))
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def find_end(file, first_line, irb_context)
|
50
|
-
return first_line unless File.exist?(file)
|
51
|
-
lex = RubyLex.new(irb_context)
|
52
|
-
lines = File.read(file).lines[(first_line - 1)..-1]
|
53
|
-
tokens = RubyLex.ripper_lex_without_warning(lines.join)
|
54
|
-
prev_tokens = []
|
55
|
-
|
56
|
-
# chunk with line number
|
57
|
-
tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
|
58
|
-
code = lines[0..lnum].join
|
59
|
-
prev_tokens.concat chunk
|
60
|
-
continue = lex.process_continue(prev_tokens)
|
61
|
-
code_block_open = lex.check_code_block(code, prev_tokens)
|
62
|
-
if !continue && !code_block_open
|
63
|
-
return first_line + lnum
|
64
|
-
end
|
65
|
-
end
|
66
|
-
first_line
|
67
|
-
end
|
68
22
|
end
|
69
23
|
|
70
24
|
def execute(str = nil)
|
@@ -73,8 +27,9 @@ module IRB
|
|
73
27
|
return
|
74
28
|
end
|
75
29
|
|
76
|
-
source =
|
77
|
-
|
30
|
+
source = SourceFinder.new(@irb_context).find_source(str)
|
31
|
+
|
32
|
+
if source
|
78
33
|
show_source(source)
|
79
34
|
else
|
80
35
|
puts "Error: Couldn't locate a definition for #{str}"
|
@@ -84,7 +39,6 @@ module IRB
|
|
84
39
|
|
85
40
|
private
|
86
41
|
|
87
|
-
# @param [IRB::ExtendCommand::ShowSource::Source] source
|
88
42
|
def show_source(source)
|
89
43
|
puts
|
90
44
|
puts "#{bold("From")}: #{source.file}:#{source.first_line}"
|
@@ -97,16 +51,6 @@ module IRB
|
|
97
51
|
def bold(str)
|
98
52
|
Color.colorize(str, [:BOLD])
|
99
53
|
end
|
100
|
-
|
101
|
-
Source = Struct.new(
|
102
|
-
:file, # @param [String] - file name
|
103
|
-
:first_line, # @param [String] - first line
|
104
|
-
:last_line, # @param [String] - last line
|
105
|
-
keyword_init: true,
|
106
|
-
)
|
107
|
-
private_constant :Source
|
108
54
|
end
|
109
55
|
end
|
110
|
-
|
111
|
-
# :startdoc:
|
112
56
|
end
|
data/lib/irb/cmd/subirb.rb
CHANGED
@@ -11,52 +11,95 @@ module IRB
|
|
11
11
|
|
12
12
|
module ExtendCommand
|
13
13
|
class MultiIRBCommand < Nop
|
14
|
-
def
|
15
|
-
super
|
14
|
+
def execute(*args)
|
16
15
|
extend_irb_context
|
17
16
|
end
|
18
17
|
|
19
18
|
private
|
20
19
|
|
20
|
+
def print_deprecated_warning
|
21
|
+
warn <<~MSG
|
22
|
+
Multi-irb commands are deprecated and will be removed in IRB 2.0.0. Please use workspace commands instead.
|
23
|
+
If you have any use case for multi-irb, please leave a comment at https://github.com/ruby/irb/issues/653
|
24
|
+
MSG
|
25
|
+
end
|
26
|
+
|
21
27
|
def extend_irb_context
|
22
28
|
# this extension patches IRB context like IRB.CurrentContext
|
23
29
|
require_relative "../ext/multi-irb"
|
24
30
|
end
|
31
|
+
|
32
|
+
def print_debugger_warning
|
33
|
+
warn "Multi-IRB commands are not available when the debugger is enabled."
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
37
|
class IrbCommand < MultiIRBCommand
|
28
|
-
category "
|
38
|
+
category "Multi-irb (DEPRECATED)"
|
29
39
|
description "Start a child IRB."
|
30
40
|
|
31
41
|
def execute(*obj)
|
42
|
+
print_deprecated_warning
|
43
|
+
|
44
|
+
if irb_context.with_debugger
|
45
|
+
print_debugger_warning
|
46
|
+
return
|
47
|
+
end
|
48
|
+
|
49
|
+
super
|
32
50
|
IRB.irb(nil, *obj)
|
33
51
|
end
|
34
52
|
end
|
35
53
|
|
36
54
|
class Jobs < MultiIRBCommand
|
37
|
-
category "
|
55
|
+
category "Multi-irb (DEPRECATED)"
|
38
56
|
description "List of current sessions."
|
39
57
|
|
40
58
|
def execute
|
59
|
+
print_deprecated_warning
|
60
|
+
|
61
|
+
if irb_context.with_debugger
|
62
|
+
print_debugger_warning
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
super
|
41
67
|
IRB.JobManager
|
42
68
|
end
|
43
69
|
end
|
44
70
|
|
45
71
|
class Foreground < MultiIRBCommand
|
46
|
-
category "
|
72
|
+
category "Multi-irb (DEPRECATED)"
|
47
73
|
description "Switches to the session of the given number."
|
48
74
|
|
49
75
|
def execute(key = nil)
|
76
|
+
print_deprecated_warning
|
77
|
+
|
78
|
+
if irb_context.with_debugger
|
79
|
+
print_debugger_warning
|
80
|
+
return
|
81
|
+
end
|
82
|
+
|
83
|
+
super
|
84
|
+
|
50
85
|
raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key
|
51
86
|
IRB.JobManager.switch(key)
|
52
87
|
end
|
53
88
|
end
|
54
89
|
|
55
90
|
class Kill < MultiIRBCommand
|
56
|
-
category "
|
91
|
+
category "Multi-irb (DEPRECATED)"
|
57
92
|
description "Kills the session with the given number."
|
58
93
|
|
59
94
|
def execute(*keys)
|
95
|
+
print_deprecated_warning
|
96
|
+
|
97
|
+
if irb_context.with_debugger
|
98
|
+
print_debugger_warning
|
99
|
+
return
|
100
|
+
end
|
101
|
+
|
102
|
+
super
|
60
103
|
IRB.JobManager.kill(*keys)
|
61
104
|
end
|
62
105
|
end
|
data/lib/irb/color.rb
CHANGED
@@ -9,12 +9,14 @@ module IRB # :nodoc:
|
|
9
9
|
BOLD = 1
|
10
10
|
UNDERLINE = 4
|
11
11
|
REVERSE = 7
|
12
|
+
BLACK = 30
|
12
13
|
RED = 31
|
13
14
|
GREEN = 32
|
14
15
|
YELLOW = 33
|
15
16
|
BLUE = 34
|
16
17
|
MAGENTA = 35
|
17
18
|
CYAN = 36
|
19
|
+
WHITE = 37
|
18
20
|
|
19
21
|
TOKEN_KEYWORDS = {
|
20
22
|
on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__', '__ENCODING__'],
|
data/lib/irb/completion.rb
CHANGED
@@ -218,7 +218,7 @@ module IRB
|
|
218
218
|
else
|
219
219
|
sym = $1
|
220
220
|
candidates = Symbol.all_symbols.collect do |s|
|
221
|
-
|
221
|
+
s.inspect
|
222
222
|
rescue EncodingError
|
223
223
|
# ignore
|
224
224
|
end
|
@@ -233,7 +233,7 @@ module IRB
|
|
233
233
|
if doc_namespace
|
234
234
|
candidates.find { |i| i == receiver }
|
235
235
|
else
|
236
|
-
candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
|
236
|
+
candidates.grep(/^#{Regexp.quote(receiver)}/).collect{|e| "::" + e}
|
237
237
|
end
|
238
238
|
|
239
239
|
when /^([A-Z].*)::([^:.]*)$/
|
data/lib/irb/context.rb
CHANGED
@@ -129,8 +129,6 @@ module IRB
|
|
129
129
|
else
|
130
130
|
@io = input_method
|
131
131
|
end
|
132
|
-
self.save_history = IRB.conf[:SAVE_HISTORY] if IRB.conf[:SAVE_HISTORY]
|
133
|
-
|
134
132
|
@extra_doc_dirs = IRB.conf[:EXTRA_DOC_DIRS]
|
135
133
|
|
136
134
|
@echo = IRB.conf[:ECHO]
|
@@ -151,6 +149,24 @@ module IRB
|
|
151
149
|
@command_aliases = IRB.conf[:COMMAND_ALIASES]
|
152
150
|
end
|
153
151
|
|
152
|
+
def save_history=(val)
|
153
|
+
IRB.conf[:SAVE_HISTORY] = val
|
154
|
+
end
|
155
|
+
|
156
|
+
def save_history
|
157
|
+
IRB.conf[:SAVE_HISTORY]
|
158
|
+
end
|
159
|
+
|
160
|
+
# A copy of the default <code>IRB.conf[:HISTORY_FILE]</code>
|
161
|
+
def history_file
|
162
|
+
IRB.conf[:HISTORY_FILE]
|
163
|
+
end
|
164
|
+
|
165
|
+
# Set <code>IRB.conf[:HISTORY_FILE]</code> to the given +hist+.
|
166
|
+
def history_file=(hist)
|
167
|
+
IRB.conf[:HISTORY_FILE] = hist
|
168
|
+
end
|
169
|
+
|
154
170
|
# The top-level workspace, see WorkSpace#main
|
155
171
|
def main
|
156
172
|
@workspace.main
|
@@ -213,8 +229,19 @@ module IRB
|
|
213
229
|
#
|
214
230
|
# See IRB@Customizing+the+IRB+Prompt for more information.
|
215
231
|
attr_accessor :prompt_c
|
216
|
-
|
217
|
-
|
232
|
+
|
233
|
+
# TODO: Remove this when developing v2.0
|
234
|
+
def prompt_n
|
235
|
+
warn "IRB::Context#prompt_n is deprecated and will be removed in the next major release."
|
236
|
+
""
|
237
|
+
end
|
238
|
+
|
239
|
+
# TODO: Remove this when developing v2.0
|
240
|
+
def prompt_n=(_)
|
241
|
+
warn "IRB::Context#prompt_n= is deprecated and will be removed in the next major release."
|
242
|
+
""
|
243
|
+
end
|
244
|
+
|
218
245
|
# Can be either the default <code>IRB.conf[:AUTO_INDENT]</code>, or the
|
219
246
|
# mode set by #prompt_mode=
|
220
247
|
#
|
@@ -329,6 +356,8 @@ module IRB
|
|
329
356
|
# User-defined IRB command aliases
|
330
357
|
attr_accessor :command_aliases
|
331
358
|
|
359
|
+
attr_accessor :with_debugger
|
360
|
+
|
332
361
|
# Alias for #use_multiline
|
333
362
|
alias use_multiline? use_multiline
|
334
363
|
# Alias for #use_singleline
|
@@ -396,7 +425,6 @@ module IRB
|
|
396
425
|
@prompt_i = pconf[:PROMPT_I]
|
397
426
|
@prompt_s = pconf[:PROMPT_S]
|
398
427
|
@prompt_c = pconf[:PROMPT_C]
|
399
|
-
@prompt_n = pconf[:PROMPT_N]
|
400
428
|
@return_format = pconf[:RETURN]
|
401
429
|
@return_format = "%s\n" if @return_format == nil
|
402
430
|
if ai = pconf.include?(:AUTO_INDENT)
|
@@ -473,28 +501,31 @@ module IRB
|
|
473
501
|
@inspect_mode
|
474
502
|
end
|
475
503
|
|
476
|
-
def evaluate(line, line_no
|
504
|
+
def evaluate(line, line_no) # :nodoc:
|
477
505
|
@line_no = line_no
|
478
|
-
|
479
|
-
line_no -= 1
|
480
|
-
line = "begin ::Kernel.raise _; rescue _.class\n#{line}\n""end"
|
481
|
-
@workspace.local_variable_set(:_, exception)
|
482
|
-
end
|
506
|
+
result = nil
|
483
507
|
|
484
|
-
|
485
|
-
|
486
|
-
if original = command_aliases[command.to_sym]
|
487
|
-
line = line.gsub(/\A#{Regexp.escape(command)}/, original.to_s)
|
488
|
-
command = original
|
508
|
+
if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty?
|
509
|
+
IRB.set_measure_callback
|
489
510
|
end
|
490
511
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
512
|
+
if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty?
|
513
|
+
last_proc = proc do
|
514
|
+
result = @workspace.evaluate(line, irb_path, line_no)
|
515
|
+
end
|
516
|
+
IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) do |chain, item|
|
517
|
+
_name, callback, arg = item
|
518
|
+
proc do
|
519
|
+
callback.(self, line, line_no, arg) do
|
520
|
+
chain.call
|
521
|
+
end
|
522
|
+
end
|
523
|
+
end.call
|
524
|
+
else
|
525
|
+
result = @workspace.evaluate(line, irb_path, line_no)
|
495
526
|
end
|
496
527
|
|
497
|
-
set_last_value(
|
528
|
+
set_last_value(result)
|
498
529
|
end
|
499
530
|
|
500
531
|
def inspect_last_value # :nodoc:
|
data/lib/irb/debug/ui.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'io/console/size'
|
2
|
+
require 'debug/console'
|
3
|
+
|
4
|
+
module IRB
|
5
|
+
module Debug
|
6
|
+
class UI < DEBUGGER__::UI_Base
|
7
|
+
def initialize(thread, irb)
|
8
|
+
@thread = thread
|
9
|
+
@irb = irb
|
10
|
+
end
|
11
|
+
|
12
|
+
def remote?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
|
16
|
+
def activate session, on_fork: false
|
17
|
+
end
|
18
|
+
|
19
|
+
def deactivate
|
20
|
+
end
|
21
|
+
|
22
|
+
def width
|
23
|
+
if (w = IO.console_size[1]) == 0 # for tests PTY
|
24
|
+
80
|
25
|
+
else
|
26
|
+
w
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def quit n
|
31
|
+
yield
|
32
|
+
exit n
|
33
|
+
end
|
34
|
+
|
35
|
+
def ask prompt
|
36
|
+
setup_interrupt do
|
37
|
+
print prompt
|
38
|
+
($stdin.gets || '').strip
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def puts str = nil
|
43
|
+
case str
|
44
|
+
when Array
|
45
|
+
str.each{|line|
|
46
|
+
$stdout.puts line.chomp
|
47
|
+
}
|
48
|
+
when String
|
49
|
+
str.each_line{|line|
|
50
|
+
$stdout.puts line.chomp
|
51
|
+
}
|
52
|
+
when nil
|
53
|
+
$stdout.puts
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def readline _
|
58
|
+
setup_interrupt do
|
59
|
+
tc = DEBUGGER__::SESSION.get_thread_client(@thread)
|
60
|
+
cmd = @irb.debug_readline(tc.current_frame.binding || TOPLEVEL_BINDING)
|
61
|
+
|
62
|
+
case cmd
|
63
|
+
when nil # when user types C-d
|
64
|
+
"continue"
|
65
|
+
else
|
66
|
+
cmd
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def setup_interrupt
|
72
|
+
DEBUGGER__::SESSION.intercept_trap_sigint false do
|
73
|
+
current_thread = Thread.current # should be session_server thread
|
74
|
+
|
75
|
+
prev_handler = trap(:INT){
|
76
|
+
current_thread.raise Interrupt
|
77
|
+
}
|
78
|
+
|
79
|
+
yield
|
80
|
+
ensure
|
81
|
+
trap(:INT, prev_handler)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def after_fork_parent
|
86
|
+
parent_pid = Process.pid
|
87
|
+
|
88
|
+
at_exit{
|
89
|
+
DEBUGGER__::SESSION.intercept_trap_sigint_end
|
90
|
+
trap(:SIGINT, :IGNORE)
|
91
|
+
|
92
|
+
if Process.pid == parent_pid
|
93
|
+
# only check child process from its parent
|
94
|
+
begin
|
95
|
+
# wait for all child processes to keep terminal
|
96
|
+
Process.waitpid
|
97
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
98
|
+
end
|
99
|
+
end
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|