pry 0.10.3 → 0.14.2
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 +5 -5
- data/CHANGELOG.md +439 -16
- data/LICENSE +1 -1
- data/README.md +362 -302
- data/bin/pry +4 -7
- data/lib/pry/basic_object.rb +10 -0
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +84 -97
- data/lib/pry/code/code_file.rb +37 -26
- data/lib/pry/code/code_range.rb +7 -5
- data/lib/pry/code/loc.rb +26 -13
- data/lib/pry/code.rb +42 -31
- data/lib/pry/code_object.rb +53 -28
- data/lib/pry/color_printer.rb +46 -35
- data/lib/pry/command.rb +197 -369
- data/lib/pry/command_set.rb +89 -114
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -82
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +85 -72
- data/lib/pry/commands/cat/file_formatter.rb +56 -46
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cat.rb +62 -54
- data/lib/pry/commands/cd.rb +40 -35
- data/lib/pry/commands/change_inspector.rb +29 -22
- data/lib/pry/commands/change_prompt.rb +48 -23
- data/lib/pry/commands/clear_screen.rb +20 -0
- data/lib/pry/commands/code_collector.rb +148 -131
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +23 -34
- data/lib/pry/commands/edit/exception_patcher.rb +21 -17
- data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
- data/lib/pry/commands/edit.rb +185 -157
- data/lib/pry/commands/exit.rb +40 -35
- data/lib/pry/commands/exit_all.rb +24 -20
- data/lib/pry/commands/exit_program.rb +20 -16
- data/lib/pry/commands/find_method.rb +168 -162
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +151 -149
- data/lib/pry/commands/import_set.rb +20 -15
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +35 -28
- data/lib/pry/commands/ls/constants.rb +59 -31
- data/lib/pry/commands/ls/formatter.rb +42 -36
- data/lib/pry/commands/ls/globals.rb +38 -36
- data/lib/pry/commands/ls/grep.rb +17 -15
- data/lib/pry/commands/ls/instance_vars.rb +29 -28
- data/lib/pry/commands/ls/interrogatable.rb +18 -12
- data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
- data/lib/pry/commands/ls/local_names.rb +26 -24
- data/lib/pry/commands/ls/local_vars.rb +38 -30
- data/lib/pry/commands/ls/ls_entity.rb +47 -52
- data/lib/pry/commands/ls/methods.rb +49 -51
- data/lib/pry/commands/ls/methods_helper.rb +46 -42
- data/lib/pry/commands/ls/self_methods.rb +23 -21
- data/lib/pry/commands/ls.rb +124 -103
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +92 -82
- data/lib/pry/commands/pry_backtrace.rb +22 -17
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +33 -27
- data/lib/pry/commands/reload_code.rb +60 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +57 -42
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +56 -29
- data/lib/pry/commands/shell_mode.rb +22 -18
- data/lib/pry/commands/show_doc.rb +80 -70
- data/lib/pry/commands/show_info.rb +194 -155
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +110 -42
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +20 -16
- data/lib/pry/commands/watch_expression/expression.rb +32 -27
- data/lib/pry/commands/watch_expression.rb +89 -84
- data/lib/pry/commands/whereami.rb +156 -141
- data/lib/pry/commands/wtf.rb +78 -40
- data/lib/pry/config/attributable.rb +22 -0
- data/lib/pry/config/lazy_value.rb +29 -0
- data/lib/pry/config/memoized_value.rb +34 -0
- data/lib/pry/config/value.rb +24 -0
- data/lib/pry/config.rb +310 -20
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +22 -9
- data/lib/pry/editor.rb +56 -34
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +13 -18
- data/lib/pry/forwardable.rb +27 -0
- data/lib/pry/helpers/base_helpers.rb +20 -62
- data/lib/pry/helpers/command_helpers.rb +52 -62
- data/lib/pry/helpers/documentation_helpers.rb +21 -12
- data/lib/pry/helpers/options_helpers.rb +15 -8
- data/lib/pry/helpers/platform.rb +55 -0
- data/lib/pry/helpers/table.rb +44 -32
- data/lib/pry/helpers/text.rb +96 -85
- data/lib/pry/helpers.rb +3 -0
- data/lib/pry/history.rb +81 -55
- data/lib/pry/hooks.rb +60 -110
- data/lib/pry/indent.rb +74 -68
- data/lib/pry/input_completer.rb +199 -158
- data/lib/pry/input_lock.rb +7 -10
- data/lib/pry/inspector.rb +36 -24
- data/lib/pry/last_exception.rb +45 -45
- data/lib/pry/method/disowned.rb +19 -5
- data/lib/pry/method/patcher.rb +14 -8
- data/lib/pry/method/weird_method_locator.rb +79 -45
- data/lib/pry/method.rb +178 -124
- data/lib/pry/object_path.rb +37 -28
- data/lib/pry/output.rb +102 -16
- data/lib/pry/pager.rb +187 -174
- data/lib/pry/prompt.rb +213 -25
- data/lib/pry/pry_class.rb +119 -98
- data/lib/pry/pry_instance.rb +261 -224
- data/lib/pry/repl.rb +83 -29
- data/lib/pry/repl_file_loader.rb +27 -22
- data/lib/pry/ring.rb +89 -0
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +190 -0
- data/lib/pry/slop/option.rb +210 -0
- data/lib/pry/slop.rb +672 -0
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable/evalable.rb +24 -0
- data/lib/pry/testable/mockable.rb +22 -0
- data/lib/pry/testable/pry_tester.rb +88 -0
- data/lib/pry/testable/utility.rb +34 -0
- data/lib/pry/testable/variables.rb +52 -0
- data/lib/pry/testable.rb +68 -0
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +20 -0
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
- data/lib/pry/wrapped_module.rb +68 -63
- data/lib/pry.rb +133 -149
- metadata +58 -69
- data/lib/pry/commands/disabled_commands.rb +0 -2
- data/lib/pry/commands/gem_cd.rb +0 -26
- data/lib/pry/commands/gem_install.rb +0 -32
- data/lib/pry/commands/gem_list.rb +0 -33
- data/lib/pry/commands/gem_open.rb +0 -29
- data/lib/pry/commands/gist.rb +0 -101
- data/lib/pry/commands/install_command.rb +0 -53
- data/lib/pry/commands/list_prompts.rb +0 -35
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/config/behavior.rb +0 -139
- data/lib/pry/config/convenience.rb +0 -25
- data/lib/pry/config/default.rb +0 -161
- data/lib/pry/history_array.rb +0 -121
- data/lib/pry/plugins.rb +0 -103
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/rubygem.rb +0 -82
- data/lib/pry/terminal.rb +0 -79
- data/lib/pry/test/helper.rb +0 -170
data/lib/pry/input_completer.rb
CHANGED
@@ -1,226 +1,237 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# taken from irb
|
2
4
|
# Implements tab completion for Readline in Pry
|
3
|
-
class Pry
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
ReservedWords = [
|
18
|
-
"BEGIN", "END",
|
19
|
-
"alias", "and",
|
20
|
-
"begin", "break",
|
21
|
-
"case", "class",
|
22
|
-
"def", "defined", "do",
|
23
|
-
"else", "elsif", "end", "ensure",
|
24
|
-
"false", "for",
|
25
|
-
"if", "in",
|
26
|
-
"module",
|
27
|
-
"next", "nil", "not",
|
28
|
-
"or",
|
29
|
-
"redo", "rescue", "retry", "return",
|
30
|
-
"self", "super",
|
31
|
-
"then", "true",
|
32
|
-
"undef", "unless", "until",
|
33
|
-
"when", "while",
|
34
|
-
"yield" ]
|
35
|
-
|
36
|
-
Operators = [
|
37
|
-
"%", "&", "*", "**", "+", "-", "/",
|
38
|
-
"<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
|
39
|
-
"[]", "[]=", "^", "!", "!=", "!~"
|
40
|
-
]
|
41
|
-
|
42
|
-
WORD_ESCAPE_STR = " \t\n\"\\'`><=;|&{("
|
43
|
-
|
44
|
-
def initialize(input, pry = nil)
|
45
|
-
@pry = pry
|
46
|
-
@input = input
|
47
|
-
@input.basic_word_break_characters = WORD_ESCAPE_STR if @input.respond_to?(:basic_word_break_characters=)
|
48
|
-
@input.completion_append_character = nil if @input.respond_to?(:completion_append_character=)
|
49
|
-
end
|
5
|
+
class Pry
|
6
|
+
class InputCompleter
|
7
|
+
NUMERIC_REGEXP = /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/.freeze
|
8
|
+
ARRAY_REGEXP = /^([^\]]*\])\.([^.]*)$/.freeze
|
9
|
+
SYMBOL_REGEXP = /^(:[^:.]*)$/.freeze
|
10
|
+
SYMBOL_METHOD_CALL_REGEXP = /^(:[^:.]+)\.([^.]*)$/.freeze
|
11
|
+
REGEX_REGEXP = %r{^(/[^/]*/)\.([^.]*)$}.freeze
|
12
|
+
PROC_OR_HASH_REGEXP = /^([^\}]*\})\.([^.]*)$/.freeze
|
13
|
+
TOPLEVEL_LOOKUP_REGEXP = /^::([A-Z][^:\.\(]*)$/.freeze
|
14
|
+
CONSTANT_REGEXP = /^([A-Z][A-Za-z0-9]*)$/.freeze
|
15
|
+
CONSTANT_OR_METHOD_REGEXP = /^([A-Z].*)::([^:.]*)$/.freeze
|
16
|
+
HEX_REGEXP = /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/.freeze
|
17
|
+
GLOBALVARIABLE_REGEXP = /^(\$[^.]*)$/.freeze
|
18
|
+
VARIABLE_REGEXP = /^([^."].*)\.([^.]*)$/.freeze
|
50
19
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
20
|
+
RESERVED_WORDS = %w[
|
21
|
+
BEGIN END
|
22
|
+
alias and
|
23
|
+
begin break
|
24
|
+
case class
|
25
|
+
def defined do
|
26
|
+
else elsif end ensure
|
27
|
+
false for
|
28
|
+
if in
|
29
|
+
module
|
30
|
+
next nil not
|
31
|
+
or
|
32
|
+
redo rescue retry return
|
33
|
+
self super
|
34
|
+
then true
|
35
|
+
undef unless until
|
36
|
+
when while
|
37
|
+
yield
|
38
|
+
].freeze
|
39
|
+
|
40
|
+
WORD_ESCAPE_STR = " \t\n\"\\'`><=;|&{(".freeze
|
41
|
+
|
42
|
+
def initialize(input, pry = nil)
|
43
|
+
@pry = pry
|
44
|
+
@input = input
|
45
|
+
if @input.respond_to?(:basic_word_break_characters=)
|
46
|
+
@input.basic_word_break_characters = WORD_ESCAPE_STR
|
69
47
|
end
|
48
|
+
|
49
|
+
return unless @input.respond_to?(:completion_append_character=)
|
50
|
+
|
51
|
+
@input.completion_append_character = nil
|
70
52
|
end
|
71
53
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
candidates = Array.instance_methods.collect(&:to_s)
|
85
|
-
select_message(path, receiver, message, candidates)
|
86
|
-
when PROC_OR_HASH_REGEXP # Proc or Hash
|
87
|
-
receiver = $1
|
88
|
-
message = Regexp.quote($2)
|
89
|
-
candidates = Proc.instance_methods.collect(&:to_s)
|
90
|
-
candidates |= Hash.instance_methods.collect(&:to_s)
|
91
|
-
select_message(path, receiver, message, candidates)
|
92
|
-
when SYMBOL_REGEXP # Symbol
|
93
|
-
if Symbol.respond_to?(:all_symbols)
|
94
|
-
sym = Regexp.quote($1)
|
95
|
-
candidates = Symbol.all_symbols.collect{|s| ":" << s.id2name}
|
96
|
-
candidates.grep(/^#{sym}/)
|
97
|
-
else
|
98
|
-
[]
|
99
|
-
end
|
100
|
-
when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods
|
101
|
-
receiver = $1
|
102
|
-
candidates = Object.constants.collect(&:to_s)
|
103
|
-
candidates.grep(/^#{receiver}/).collect{|e| "::" << e}
|
104
|
-
when CONSTANT_REGEXP # Constant
|
105
|
-
message = $1
|
54
|
+
# Return a new completion proc for use by Readline.
|
55
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
56
|
+
def call(str, options = {})
|
57
|
+
custom_completions = options[:custom_completions] || []
|
58
|
+
# if there are multiple contexts e.g. cd 1/2/3
|
59
|
+
# get new target for 1/2 and find candidates for 3
|
60
|
+
path, input = build_path(str)
|
61
|
+
|
62
|
+
if path.call.empty?
|
63
|
+
target = options[:target]
|
64
|
+
else
|
65
|
+
# Assume the user is tab-completing the 'cd' command
|
106
66
|
begin
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
67
|
+
target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last
|
68
|
+
# but if that doesn't work, assume they're doing division with no spaces
|
69
|
+
rescue Pry::CommandError
|
70
|
+
target = options[:target]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
begin
|
75
|
+
bind = target
|
76
|
+
# Complete stdlib symbols
|
77
|
+
case input
|
78
|
+
when REGEX_REGEXP # Regexp
|
79
|
+
receiver = Regexp.last_match(1)
|
80
|
+
message = Regexp.quote(Regexp.last_match(2))
|
81
|
+
candidates = Regexp.instance_methods.collect(&:to_s)
|
82
|
+
select_message(path, receiver, message, candidates)
|
83
|
+
when ARRAY_REGEXP # Array
|
84
|
+
receiver = Regexp.last_match(1)
|
85
|
+
message = Regexp.quote(Regexp.last_match(2))
|
86
|
+
candidates = Array.instance_methods.collect(&:to_s)
|
87
|
+
select_message(path, receiver, message, candidates)
|
88
|
+
when PROC_OR_HASH_REGEXP # Proc or Hash
|
89
|
+
receiver = Regexp.last_match(1)
|
90
|
+
message = Regexp.quote(Regexp.last_match(2))
|
91
|
+
candidates = Proc.instance_methods.collect(&:to_s)
|
92
|
+
candidates |= Hash.instance_methods.collect(&:to_s)
|
93
|
+
select_message(path, receiver, message, candidates)
|
94
|
+
when SYMBOL_REGEXP # Symbol
|
95
|
+
if Symbol.respond_to?(:all_symbols)
|
96
|
+
sym = Regexp.quote(Regexp.last_match(1))
|
97
|
+
candidates = Symbol.all_symbols.collect { |s| ":" + s.id2name }
|
98
|
+
candidates.grep(/^#{sym}/)
|
99
|
+
else
|
100
|
+
[]
|
101
|
+
end
|
102
|
+
when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods
|
103
|
+
receiver = Regexp.last_match(1)
|
104
|
+
candidates = Object.constants.collect(&:to_s)
|
105
|
+
candidates.grep(/^#{receiver}/).collect { |e| "::" + e }
|
106
|
+
when CONSTANT_REGEXP # Constant
|
107
|
+
message = Regexp.last_match(1)
|
108
|
+
begin
|
109
|
+
context = target.eval("self")
|
110
|
+
context = context.class unless context.respond_to? :constants
|
111
|
+
candidates = context.constants.collect(&:to_s)
|
112
|
+
rescue StandardError
|
113
|
+
candidates = []
|
114
|
+
end
|
113
115
|
candidates = candidates.grep(/^#{message}/).collect(&path)
|
114
116
|
when CONSTANT_OR_METHOD_REGEXP # Constant or class methods
|
115
|
-
receiver =
|
116
|
-
message = Regexp.quote(
|
117
|
+
receiver = Regexp.last_match(1)
|
118
|
+
message = Regexp.quote(Regexp.last_match(2))
|
117
119
|
begin
|
118
|
-
candidates = eval(
|
119
|
-
|
120
|
+
candidates = eval( # rubocop:disable Security/Eval
|
121
|
+
"#{receiver}.constants.collect(&:to_s)", bind, __FILE__, __LINE__
|
122
|
+
)
|
123
|
+
candidates |= eval( # rubocop:disable Security/Eval
|
124
|
+
"#{receiver}.methods.collect(&:to_s)", bind, __FILE__, __LINE__
|
125
|
+
)
|
120
126
|
rescue Pry::RescuableException
|
121
127
|
candidates = []
|
122
128
|
end
|
123
|
-
candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
|
129
|
+
candidates.grep(/^#{message}/).collect { |e| receiver + "::" + e }
|
124
130
|
when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol
|
125
|
-
receiver =
|
126
|
-
message = Regexp.quote(
|
131
|
+
receiver = Regexp.last_match(1)
|
132
|
+
message = Regexp.quote(Regexp.last_match(2))
|
127
133
|
candidates = Symbol.instance_methods.collect(&:to_s)
|
128
134
|
select_message(path, receiver, message, candidates)
|
129
135
|
when NUMERIC_REGEXP
|
130
136
|
# Numeric
|
131
|
-
receiver =
|
132
|
-
message = Regexp.quote(
|
137
|
+
receiver = Regexp.last_match(1)
|
138
|
+
message = Regexp.quote(Regexp.last_match(5))
|
133
139
|
begin
|
140
|
+
# rubocop:disable Security/Eval
|
134
141
|
candidates = eval(receiver, bind).methods.collect(&:to_s)
|
142
|
+
# rubocop:enable Security/Eval
|
135
143
|
rescue Pry::RescuableException
|
136
144
|
candidates = []
|
137
145
|
end
|
138
146
|
select_message(path, receiver, message, candidates)
|
139
147
|
when HEX_REGEXP
|
140
148
|
# Numeric(0xFFFF)
|
141
|
-
receiver =
|
142
|
-
message = Regexp.quote(
|
149
|
+
receiver = Regexp.last_match(1)
|
150
|
+
message = Regexp.quote(Regexp.last_match(2))
|
143
151
|
begin
|
152
|
+
# rubocop:disable Security/Eval
|
144
153
|
candidates = eval(receiver, bind).methods.collect(&:to_s)
|
154
|
+
# rubocop:enable Security/Eval
|
145
155
|
rescue Pry::RescuableException
|
146
156
|
candidates = []
|
147
157
|
end
|
148
158
|
select_message(path, receiver, message, candidates)
|
149
159
|
when GLOBALVARIABLE_REGEXP # global
|
150
|
-
regmessage = Regexp.new(Regexp.quote(
|
160
|
+
regmessage = Regexp.new(Regexp.quote(Regexp.last_match(1)))
|
151
161
|
candidates = global_variables.collect(&:to_s).grep(regmessage)
|
152
162
|
when VARIABLE_REGEXP # variable
|
153
|
-
receiver =
|
154
|
-
message = Regexp.quote(
|
163
|
+
receiver = Regexp.last_match(1)
|
164
|
+
message = Regexp.quote(Regexp.last_match(2))
|
155
165
|
|
156
|
-
gv = eval("global_variables", bind).collect(&:to_s)
|
157
|
-
lv = eval("local_variables", bind).collect(&:to_s)
|
158
|
-
cv = eval("self.class.constants", bind).collect(&:to_s)
|
166
|
+
gv = eval("global_variables", bind, __FILE__, __LINE__).collect(&:to_s)
|
167
|
+
lv = eval("local_variables", bind, __FILE__, __LINE__).collect(&:to_s)
|
168
|
+
cv = eval("self.class.constants", bind, __FILE__, __LINE__).collect(&:to_s)
|
159
169
|
|
160
|
-
if (gv | lv | cv).include?(receiver)
|
170
|
+
if (gv | lv | cv).include?(receiver) || /^[A-Z]/ =~ receiver && /\./ !~ receiver
|
161
171
|
# foo.func and foo is local var. OR
|
162
172
|
# Foo::Bar.func
|
163
173
|
begin
|
164
|
-
candidates = eval(
|
174
|
+
candidates = eval( # rubocop:disable Security/Eval
|
175
|
+
"#{receiver}.methods", bind, __FILE__, __LINE__
|
176
|
+
).collect(&:to_s)
|
165
177
|
rescue Pry::RescuableException
|
166
178
|
candidates = []
|
167
179
|
end
|
168
180
|
else
|
169
181
|
# func1.func2
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
182
|
+
require 'set'
|
183
|
+
candidates = Set.new
|
184
|
+
to_ignore = ignored_modules
|
185
|
+
ObjectSpace.each_object(Module) do |m|
|
186
|
+
next if begin
|
187
|
+
to_ignore.include?(m)
|
188
|
+
rescue StandardError
|
189
|
+
true
|
190
|
+
end
|
179
191
|
|
180
192
|
# jruby doesn't always provide #instance_methods() on each
|
181
193
|
# object.
|
182
194
|
if m.respond_to?(:instance_methods)
|
183
|
-
candidates.
|
195
|
+
candidates.merge m.instance_methods(false).collect(&:to_s)
|
184
196
|
end
|
185
|
-
|
186
|
-
candidates.sort!
|
187
|
-
candidates.uniq!
|
197
|
+
end
|
188
198
|
end
|
189
|
-
select_message(path, receiver, message, candidates)
|
199
|
+
select_message(path, receiver, message, candidates.sort)
|
190
200
|
when /^\.([^.]*)$/
|
191
201
|
# Unknown(maybe String)
|
192
202
|
receiver = ""
|
193
|
-
message = Regexp.quote(
|
203
|
+
message = Regexp.quote(Regexp.last_match(1))
|
194
204
|
candidates = String.instance_methods(true).collect(&:to_s)
|
195
205
|
select_message(path, receiver, message, candidates)
|
196
206
|
else
|
197
207
|
candidates = eval(
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
208
|
+
"methods | private_methods | local_variables | " \
|
209
|
+
"self.class.constants | instance_variables",
|
210
|
+
bind, __FILE__, __LINE__ - 2
|
211
|
+
).collect(&:to_s)
|
202
212
|
|
203
|
-
if eval("respond_to?(:class_variables)", bind)
|
204
|
-
candidates += eval(
|
213
|
+
if eval("respond_to?(:class_variables)", bind, __FILE__, __LINE__)
|
214
|
+
candidates += eval(
|
215
|
+
"class_variables", bind, __FILE__, __LINE__
|
216
|
+
).collect(&:to_s)
|
205
217
|
end
|
206
|
-
candidates =
|
218
|
+
candidates =
|
219
|
+
(candidates | RESERVED_WORDS | custom_completions)
|
220
|
+
.grep(/^#{Regexp.quote(input)}/)
|
207
221
|
candidates.collect(&path)
|
208
222
|
end
|
209
223
|
rescue Pry::RescuableException
|
210
224
|
[]
|
211
225
|
end
|
212
226
|
end
|
227
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
213
228
|
|
214
229
|
def select_message(path, receiver, message, candidates)
|
215
|
-
candidates.grep(/^#{message}/).collect
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
when *Operators
|
221
|
-
#receiver + " " << e
|
222
|
-
end
|
223
|
-
}.compact
|
230
|
+
candidates.grep(/^#{message}/).collect do |e|
|
231
|
+
next unless e =~ /^[a-zA-Z_]/
|
232
|
+
|
233
|
+
path.call(receiver + "." + e)
|
234
|
+
end.compact
|
224
235
|
end
|
225
236
|
|
226
237
|
# build_path seperates the input into two parts: path and input.
|
@@ -228,15 +239,45 @@ class Pry::InputCompleter
|
|
228
239
|
# path is a proc that takes an input and builds a full path.
|
229
240
|
def build_path(input)
|
230
241
|
# check to see if the input is a regex
|
231
|
-
return proc {|i| i.to_s }, input if input[
|
242
|
+
return proc { |i| i.to_s }, input if input[%r{/\.}]
|
243
|
+
|
232
244
|
trailing_slash = input.end_with?('/')
|
233
|
-
contexts = input.chomp('/').split(
|
245
|
+
contexts = input.chomp('/').split(%r{/})
|
234
246
|
input = contexts[-1]
|
235
247
|
path = proc do |i|
|
236
248
|
p = contexts[0..-2].push(i).join('/')
|
237
249
|
p += '/' if trailing_slash && !i.nil?
|
238
250
|
p
|
239
251
|
end
|
240
|
-
|
252
|
+
[path, input]
|
241
253
|
end
|
254
|
+
|
255
|
+
def ignored_modules
|
256
|
+
# We could cache the result, but IRB is not loaded by default.
|
257
|
+
# And this is very fast anyway.
|
258
|
+
# By using this approach, we avoid Module#name calls, which are
|
259
|
+
# relatively slow when there are a lot of anonymous modules defined.
|
260
|
+
s = Set.new
|
261
|
+
|
262
|
+
scanner = lambda do |m|
|
263
|
+
next if s.include?(m) # IRB::ExtendCommandBundle::EXCB recurses.
|
264
|
+
|
265
|
+
s << m
|
266
|
+
m.constants(false).each do |c|
|
267
|
+
value = m.const_get(c)
|
268
|
+
scanner.call(value) if value.is_a?(Module)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# FIXME: Add Pry here as well?
|
273
|
+
%i[IRB SLex RubyLex RubyToken].each do |module_name|
|
274
|
+
next unless Object.const_defined?(module_name)
|
275
|
+
|
276
|
+
scanner.call(Object.const_get(module_name))
|
277
|
+
end
|
278
|
+
|
279
|
+
s.delete(IRB::Context) if defined?(IRB::Context)
|
280
|
+
s
|
281
|
+
end
|
282
|
+
end
|
242
283
|
end
|
data/lib/pry/input_lock.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Pry
|
4
4
|
# There is one InputLock per input (such as STDIN) as two REPLs on the same
|
@@ -6,7 +6,7 @@ class Pry
|
|
6
6
|
# that threads to not conflict with each other. The latest thread to request
|
7
7
|
# ownership of the input wins.
|
8
8
|
class InputLock
|
9
|
-
class Interrupt < Exception; end
|
9
|
+
class Interrupt < Exception; end # rubocop:disable Lint/InheritException
|
10
10
|
|
11
11
|
class << self
|
12
12
|
attr_accessor :input_locks
|
@@ -35,7 +35,7 @@ class Pry
|
|
35
35
|
|
36
36
|
# Adds ourselves to the ownership list. The last one in the list may access
|
37
37
|
# the input through interruptible_region().
|
38
|
-
def __with_ownership
|
38
|
+
def __with_ownership
|
39
39
|
@mutex.synchronize do
|
40
40
|
# Three cases:
|
41
41
|
# 1) There are no owners, in this case we are good to go.
|
@@ -58,8 +58,7 @@ class Pry
|
|
58
58
|
@owners << Thread.current
|
59
59
|
end
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
yield
|
63
62
|
ensure
|
64
63
|
@mutex.synchronize do
|
65
64
|
# We are releasing any desire to have the input ownership by removing
|
@@ -76,7 +75,7 @@ class Pry
|
|
76
75
|
def with_ownership(&block)
|
77
76
|
# If we are in a nested with_ownership() call (nested pry context), we do nothing.
|
78
77
|
nested = @mutex.synchronize { @owners.include?(Thread.current) }
|
79
|
-
nested ?
|
78
|
+
nested ? yield : __with_ownership(&block)
|
80
79
|
end
|
81
80
|
|
82
81
|
def enter_interruptible_region
|
@@ -106,14 +105,13 @@ class Pry
|
|
106
105
|
retry
|
107
106
|
end
|
108
107
|
|
109
|
-
def interruptible_region
|
108
|
+
def interruptible_region
|
110
109
|
enter_interruptible_region
|
111
110
|
|
112
111
|
# XXX Note that there is a chance that we get the interrupt right after
|
113
112
|
# the readline call succeeded, but we'll never know, and we will retry the
|
114
113
|
# call, discarding that piece of input.
|
115
|
-
|
116
|
-
|
114
|
+
yield
|
117
115
|
rescue Interrupt
|
118
116
|
# We were asked to back off. The one requesting the interrupt will be
|
119
117
|
# waiting on the conditional for the interruptible flag to change to false.
|
@@ -124,7 +122,6 @@ class Pry
|
|
124
122
|
leave_interruptible_region
|
125
123
|
sleep 0.01
|
126
124
|
retry
|
127
|
-
|
128
125
|
ensure
|
129
126
|
leave_interruptible_region
|
130
127
|
end
|
data/lib/pry/inspector.rb
CHANGED
@@ -1,27 +1,39 @@
|
|
1
|
-
|
2
|
-
MAP = {
|
3
|
-
"default" => {
|
4
|
-
value: Pry::DEFAULT_PRINT,
|
5
|
-
description: <<-DESCRIPTION.each_line.map(&:lstrip!)
|
6
|
-
The default Pry inspector. It has paging and color support, and uses
|
7
|
-
pretty_inspect when printing an object.
|
8
|
-
DESCRIPTION
|
9
|
-
},
|
1
|
+
# frozen_string_literal: true
|
10
2
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
class Pry
|
4
|
+
class Inspector
|
5
|
+
MAP = {
|
6
|
+
"default" => {
|
7
|
+
value: Pry.config.print,
|
8
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip!)
|
9
|
+
The default Pry inspector. It has paging and color support, and uses
|
10
|
+
pretty_inspect when printing an object.
|
11
|
+
DESCRIPTION
|
12
|
+
},
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
"simple" => {
|
15
|
+
value: proc do |output, value|
|
16
|
+
begin
|
17
|
+
output.puts value.inspect
|
18
|
+
rescue RescuableException
|
19
|
+
output.puts "unknown"
|
20
|
+
end
|
21
|
+
end,
|
22
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip)
|
23
|
+
A simple inspector that uses #puts and #inspect when printing an
|
24
|
+
object. It has no pager, color, or pretty_inspect support.
|
25
|
+
DESCRIPTION
|
26
|
+
},
|
27
|
+
|
28
|
+
"clipped" => {
|
29
|
+
value: proc do |output, value|
|
30
|
+
output.puts Pry.view_clip(value, id: true)
|
31
|
+
end,
|
32
|
+
description: <<-DESCRIPTION.each_line.map(&:lstrip)
|
33
|
+
The clipped inspector has the same features as the 'simple' inspector
|
34
|
+
but prints large objects as a smaller string.
|
35
|
+
DESCRIPTION
|
36
|
+
}
|
37
|
+
}.freeze
|
38
|
+
end
|
27
39
|
end
|