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.
Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +439 -16
  3. data/LICENSE +1 -1
  4. data/README.md +362 -302
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +84 -97
  10. data/lib/pry/code/code_file.rb +37 -26
  11. data/lib/pry/code/code_range.rb +7 -5
  12. data/lib/pry/code/loc.rb +26 -13
  13. data/lib/pry/code.rb +42 -31
  14. data/lib/pry/code_object.rb +53 -28
  15. data/lib/pry/color_printer.rb +46 -35
  16. data/lib/pry/command.rb +197 -369
  17. data/lib/pry/command_set.rb +89 -114
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -72
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -46
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +62 -54
  27. data/lib/pry/commands/cd.rb +40 -35
  28. data/lib/pry/commands/change_inspector.rb +29 -22
  29. data/lib/pry/commands/change_prompt.rb +48 -23
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  36. data/lib/pry/commands/edit.rb +185 -157
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -16
  40. data/lib/pry/commands/find_method.rb +168 -162
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +151 -149
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +35 -28
  47. data/lib/pry/commands/ls/constants.rb +59 -31
  48. data/lib/pry/commands/ls/formatter.rb +42 -36
  49. data/lib/pry/commands/ls/globals.rb +38 -36
  50. data/lib/pry/commands/ls/grep.rb +17 -15
  51. data/lib/pry/commands/ls/instance_vars.rb +29 -28
  52. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  53. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  54. data/lib/pry/commands/ls/local_names.rb +26 -24
  55. data/lib/pry/commands/ls/local_vars.rb +38 -30
  56. data/lib/pry/commands/ls/ls_entity.rb +47 -52
  57. data/lib/pry/commands/ls/methods.rb +49 -51
  58. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  59. data/lib/pry/commands/ls/self_methods.rb +23 -21
  60. data/lib/pry/commands/ls.rb +124 -103
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +92 -82
  63. data/lib/pry/commands/pry_backtrace.rb +22 -17
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +60 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -42
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +56 -29
  71. data/lib/pry/commands/shell_mode.rb +22 -18
  72. data/lib/pry/commands/show_doc.rb +80 -70
  73. data/lib/pry/commands/show_info.rb +194 -155
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +110 -42
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +20 -16
  79. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  80. data/lib/pry/commands/watch_expression.rb +89 -84
  81. data/lib/pry/commands/whereami.rb +156 -141
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +310 -20
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +22 -9
  90. data/lib/pry/editor.rb +56 -34
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +13 -18
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +20 -62
  96. data/lib/pry/helpers/command_helpers.rb +52 -62
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -12
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +55 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -85
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +81 -55
  104. data/lib/pry/hooks.rb +60 -110
  105. data/lib/pry/indent.rb +74 -68
  106. data/lib/pry/input_completer.rb +199 -158
  107. data/lib/pry/input_lock.rb +7 -10
  108. data/lib/pry/inspector.rb +36 -24
  109. data/lib/pry/last_exception.rb +45 -45
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/method/patcher.rb +14 -8
  112. data/lib/pry/method/weird_method_locator.rb +79 -45
  113. data/lib/pry/method.rb +178 -124
  114. data/lib/pry/object_path.rb +37 -28
  115. data/lib/pry/output.rb +102 -16
  116. data/lib/pry/pager.rb +187 -174
  117. data/lib/pry/prompt.rb +213 -25
  118. data/lib/pry/pry_class.rb +119 -98
  119. data/lib/pry/pry_instance.rb +261 -224
  120. data/lib/pry/repl.rb +83 -29
  121. data/lib/pry/repl_file_loader.rb +27 -22
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
  138. data/lib/pry/wrapped_module.rb +68 -63
  139. data/lib/pry.rb +133 -149
  140. metadata +58 -69
  141. data/lib/pry/commands/disabled_commands.rb +0 -2
  142. data/lib/pry/commands/gem_cd.rb +0 -26
  143. data/lib/pry/commands/gem_install.rb +0 -32
  144. data/lib/pry/commands/gem_list.rb +0 -33
  145. data/lib/pry/commands/gem_open.rb +0 -29
  146. data/lib/pry/commands/gist.rb +0 -101
  147. data/lib/pry/commands/install_command.rb +0 -53
  148. data/lib/pry/commands/list_prompts.rb +0 -35
  149. data/lib/pry/commands/simple_prompt.rb +0 -22
  150. data/lib/pry/commands.rb +0 -6
  151. data/lib/pry/config/behavior.rb +0 -139
  152. data/lib/pry/config/convenience.rb +0 -25
  153. data/lib/pry/config/default.rb +0 -161
  154. data/lib/pry/history_array.rb +0 -121
  155. data/lib/pry/plugins.rb +0 -103
  156. data/lib/pry/rbx_path.rb +0 -22
  157. data/lib/pry/rubygem.rb +0 -82
  158. data/lib/pry/terminal.rb +0 -79
  159. data/lib/pry/test/helper.rb +0 -170
@@ -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::InputCompleter
4
- NUMERIC_REGEXP = /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
5
- ARRAY_REGEXP = /^([^\]]*\])\.([^.]*)$/
6
- SYMBOL_REGEXP = /^(:[^:.]*)$/
7
- SYMBOL_METHOD_CALL_REGEXP = /^(:[^:.]+)\.([^.]*)$/
8
- REGEX_REGEXP = /^(\/[^\/]*\/)\.([^.]*)$/
9
- PROC_OR_HASH_REGEXP = /^([^\}]*\})\.([^.]*)$/
10
- TOPLEVEL_LOOKUP_REGEXP = /^::([A-Z][^:\.\(]*)$/
11
- CONSTANT_REGEXP = /^([A-Z][A-Za-z0-9]*)$/
12
- CONSTANT_OR_METHOD_REGEXP = /^([A-Z].*)::([^:.]*)$/
13
- HEX_REGEXP = /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
14
- GLOBALVARIABLE_REGEXP = /^(\$[^.]*)$/
15
- VARIABLE_REGEXP = /^([^."].*)\.([^.]*)$/
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
- # Return a new completion proc for use by Readline.
53
- #
54
- def call(str, options = {})
55
- custom_completions = options[:custom_completions] || []
56
- # if there are multiple contexts e.g. cd 1/2/3
57
- # get new target for 1/2 and find candidates for 3
58
- path, input = build_path(str)
59
-
60
- if path.call.empty?
61
- target = options[:target]
62
- else
63
- # Assume the user is tab-completing the 'cd' command
64
- begin
65
- target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last
66
- # but if that doesn't work, assume they're doing division with no spaces
67
- rescue Pry::CommandError
68
- target = options[:target]
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
- begin
73
- bind = target
74
- # Complete stdlib symbols
75
- case input
76
- when REGEX_REGEXP # Regexp
77
- receiver = $1
78
- message = Regexp.quote($2)
79
- candidates = Regexp.instance_methods.collect(&:to_s)
80
- select_message(path, receiver, message, candidates)
81
- when ARRAY_REGEXP # Array
82
- receiver = $1
83
- message = Regexp.quote($2)
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
- context = target.eval("self")
108
- context = context.class unless context.respond_to? :constants
109
- candidates = context.constants.collect(&:to_s)
110
- rescue
111
- candidates = []
112
- end
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 = $1
116
- message = Regexp.quote($2)
117
+ receiver = Regexp.last_match(1)
118
+ message = Regexp.quote(Regexp.last_match(2))
117
119
  begin
118
- candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
119
- candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
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 = $1
126
- message = Regexp.quote($2)
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 = $1
132
- message = Regexp.quote($5)
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 = $1
142
- message = Regexp.quote($2)
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($1))
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 = $1
154
- message = Regexp.quote($2)
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) or /^[A-Z]/ =~ receiver && /\./ !~ 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("#{receiver}.methods", bind).collect(&:to_s)
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
- candidates = []
171
- ObjectSpace.each_object(Module){|m|
172
- begin
173
- name = m.name.to_s
174
- rescue Pry::RescuableException
175
- name = ""
176
- end
177
- next if name != "IRB::Context" and
178
- /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
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.concat m.instance_methods(false).collect(&:to_s)
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($1)
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
- "methods | private_methods | local_variables | " \
199
- "self.class.constants | instance_variables",
200
- bind
201
- ).collect(&:to_s)
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("class_variables", bind).collect(&:to_s)
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 = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/)
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 { |e|
216
- case e
217
- when /^[a-zA-Z_]/
218
- path.call(receiver + "." << e)
219
- when /^[0-9]/
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
- return path, input
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
@@ -1,4 +1,4 @@
1
- require 'thread'
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(&block)
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
- block.call
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 ? block.call : __with_ownership(&block)
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(&block)
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
- block.call
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
- class Pry::Inspector
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
- "simple" => {
12
- value: Pry::SIMPLE_PRINT,
13
- description: <<-DESCRIPTION.each_line.map(&:lstrip)
14
- A simple inspector that uses #puts and #inspect when printing an
15
- object. It has no pager, color, or pretty_inspect support.
16
- DESCRIPTION
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
- "clipped" => {
20
- value: Pry::CLIPPED_PRINT,
21
- description: <<-DESCRIPTION.each_line.map(&:lstrip)
22
- The clipped inspector has the same features as the 'simple' inspector
23
- but prints large objects as a smaller string.
24
- DESCRIPTION
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