super-smart-mod 0.0.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.
Files changed (143) hide show
  1. checksums.yaml +7 -0
  2. data/pry-0.16.0/CHANGELOG.md +1211 -0
  3. data/pry-0.16.0/LICENSE +25 -0
  4. data/pry-0.16.0/README.md +469 -0
  5. data/pry-0.16.0/bin/pry +13 -0
  6. data/pry-0.16.0/lib/pry/basic_object.rb +10 -0
  7. data/pry-0.16.0/lib/pry/block_command.rb +22 -0
  8. data/pry-0.16.0/lib/pry/class_command.rb +194 -0
  9. data/pry-0.16.0/lib/pry/cli.rb +211 -0
  10. data/pry-0.16.0/lib/pry/code/code_file.rb +114 -0
  11. data/pry-0.16.0/lib/pry/code/code_range.rb +73 -0
  12. data/pry-0.16.0/lib/pry/code/loc.rb +105 -0
  13. data/pry-0.16.0/lib/pry/code.rb +357 -0
  14. data/pry-0.16.0/lib/pry/code_object.rb +197 -0
  15. data/pry-0.16.0/lib/pry/color_printer.rb +66 -0
  16. data/pry-0.16.0/lib/pry/command.rb +520 -0
  17. data/pry-0.16.0/lib/pry/command_set.rb +418 -0
  18. data/pry-0.16.0/lib/pry/command_state.rb +36 -0
  19. data/pry-0.16.0/lib/pry/commands/amend_line.rb +103 -0
  20. data/pry-0.16.0/lib/pry/commands/bang.rb +24 -0
  21. data/pry-0.16.0/lib/pry/commands/bang_pry.rb +21 -0
  22. data/pry-0.16.0/lib/pry/commands/cat/abstract_formatter.rb +32 -0
  23. data/pry-0.16.0/lib/pry/commands/cat/exception_formatter.rb +90 -0
  24. data/pry-0.16.0/lib/pry/commands/cat/file_formatter.rb +77 -0
  25. data/pry-0.16.0/lib/pry/commands/cat/input_expression_formatter.rb +48 -0
  26. data/pry-0.16.0/lib/pry/commands/cat.rb +70 -0
  27. data/pry-0.16.0/lib/pry/commands/cd.rb +48 -0
  28. data/pry-0.16.0/lib/pry/commands/change_inspector.rb +34 -0
  29. data/pry-0.16.0/lib/pry/commands/change_prompt.rb +51 -0
  30. data/pry-0.16.0/lib/pry/commands/clear_screen.rb +20 -0
  31. data/pry-0.16.0/lib/pry/commands/code_collector.rb +182 -0
  32. data/pry-0.16.0/lib/pry/commands/disable_pry.rb +31 -0
  33. data/pry-0.16.0/lib/pry/commands/easter_eggs.rb +101 -0
  34. data/pry-0.16.0/lib/pry/commands/edit/exception_patcher.rb +29 -0
  35. data/pry-0.16.0/lib/pry/commands/edit/file_and_line_locator.rb +47 -0
  36. data/pry-0.16.0/lib/pry/commands/edit.rb +225 -0
  37. data/pry-0.16.0/lib/pry/commands/exit.rb +47 -0
  38. data/pry-0.16.0/lib/pry/commands/exit_all.rb +33 -0
  39. data/pry-0.16.0/lib/pry/commands/exit_program.rb +27 -0
  40. data/pry-0.16.0/lib/pry/commands/find_method.rb +199 -0
  41. data/pry-0.16.0/lib/pry/commands/fix_indent.rb +23 -0
  42. data/pry-0.16.0/lib/pry/commands/help.rb +171 -0
  43. data/pry-0.16.0/lib/pry/commands/hist.rb +182 -0
  44. data/pry-0.16.0/lib/pry/commands/import_set.rb +27 -0
  45. data/pry-0.16.0/lib/pry/commands/jump_to.rb +33 -0
  46. data/pry-0.16.0/lib/pry/commands/list_inspectors.rb +42 -0
  47. data/pry-0.16.0/lib/pry/commands/ls/config.rb +54 -0
  48. data/pry-0.16.0/lib/pry/commands/ls/constants.rb +75 -0
  49. data/pry-0.16.0/lib/pry/commands/ls/formatter.rb +55 -0
  50. data/pry-0.16.0/lib/pry/commands/ls/globals.rb +50 -0
  51. data/pry-0.16.0/lib/pry/commands/ls/grep.rb +23 -0
  52. data/pry-0.16.0/lib/pry/commands/ls/instance_vars.rb +40 -0
  53. data/pry-0.16.0/lib/pry/commands/ls/interrogatable.rb +24 -0
  54. data/pry-0.16.0/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  55. data/pry-0.16.0/lib/pry/commands/ls/local_names.rb +37 -0
  56. data/pry-0.16.0/lib/pry/commands/ls/local_vars.rb +47 -0
  57. data/pry-0.16.0/lib/pry/commands/ls/ls_entity.rb +65 -0
  58. data/pry-0.16.0/lib/pry/commands/ls/methods.rb +55 -0
  59. data/pry-0.16.0/lib/pry/commands/ls/methods_helper.rb +50 -0
  60. data/pry-0.16.0/lib/pry/commands/ls/self_methods.rb +34 -0
  61. data/pry-0.16.0/lib/pry/commands/ls.rb +114 -0
  62. data/pry-0.16.0/lib/pry/commands/nesting.rb +29 -0
  63. data/pry-0.16.0/lib/pry/commands/play.rb +113 -0
  64. data/pry-0.16.0/lib/pry/commands/pry_backtrace.rb +30 -0
  65. data/pry-0.16.0/lib/pry/commands/pry_version.rb +21 -0
  66. data/pry-0.16.0/lib/pry/commands/raise_up.rb +38 -0
  67. data/pry-0.16.0/lib/pry/commands/reload_code.rb +74 -0
  68. data/pry-0.16.0/lib/pry/commands/reset.rb +22 -0
  69. data/pry-0.16.0/lib/pry/commands/ri.rb +75 -0
  70. data/pry-0.16.0/lib/pry/commands/save_file.rb +63 -0
  71. data/pry-0.16.0/lib/pry/commands/shell_command.rb +75 -0
  72. data/pry-0.16.0/lib/pry/commands/shell_mode.rb +30 -0
  73. data/pry-0.16.0/lib/pry/commands/show_doc.rb +84 -0
  74. data/pry-0.16.0/lib/pry/commands/show_info.rb +234 -0
  75. data/pry-0.16.0/lib/pry/commands/show_input.rb +22 -0
  76. data/pry-0.16.0/lib/pry/commands/show_source.rb +57 -0
  77. data/pry-0.16.0/lib/pry/commands/stat.rb +44 -0
  78. data/pry-0.16.0/lib/pry/commands/switch_to.rb +29 -0
  79. data/pry-0.16.0/lib/pry/commands/toggle_color.rb +28 -0
  80. data/pry-0.16.0/lib/pry/commands/watch_expression/expression.rb +43 -0
  81. data/pry-0.16.0/lib/pry/commands/watch_expression.rb +108 -0
  82. data/pry-0.16.0/lib/pry/commands/whereami.rb +205 -0
  83. data/pry-0.16.0/lib/pry/commands/wtf.rb +95 -0
  84. data/pry-0.16.0/lib/pry/config/attributable.rb +22 -0
  85. data/pry-0.16.0/lib/pry/config/lazy_value.rb +29 -0
  86. data/pry-0.16.0/lib/pry/config/memoized_value.rb +34 -0
  87. data/pry-0.16.0/lib/pry/config/value.rb +24 -0
  88. data/pry-0.16.0/lib/pry/config.rb +321 -0
  89. data/pry-0.16.0/lib/pry/control_d_handler.rb +28 -0
  90. data/pry-0.16.0/lib/pry/core_extensions.rb +144 -0
  91. data/pry-0.16.0/lib/pry/editor.rb +157 -0
  92. data/pry-0.16.0/lib/pry/env.rb +18 -0
  93. data/pry-0.16.0/lib/pry/exception_handler.rb +48 -0
  94. data/pry-0.16.0/lib/pry/exceptions.rb +73 -0
  95. data/pry-0.16.0/lib/pry/forwardable.rb +27 -0
  96. data/pry-0.16.0/lib/pry/helpers/base_helpers.rb +71 -0
  97. data/pry-0.16.0/lib/pry/helpers/command_helpers.rb +146 -0
  98. data/pry-0.16.0/lib/pry/helpers/documentation_helpers.rb +84 -0
  99. data/pry-0.16.0/lib/pry/helpers/options_helpers.rb +34 -0
  100. data/pry-0.16.0/lib/pry/helpers/platform.rb +55 -0
  101. data/pry-0.16.0/lib/pry/helpers/table.rb +121 -0
  102. data/pry-0.16.0/lib/pry/helpers/text.rb +118 -0
  103. data/pry-0.16.0/lib/pry/helpers.rb +8 -0
  104. data/pry-0.16.0/lib/pry/history.rb +153 -0
  105. data/pry-0.16.0/lib/pry/hooks.rb +180 -0
  106. data/pry-0.16.0/lib/pry/indent.rb +414 -0
  107. data/pry-0.16.0/lib/pry/input/simple_stdio.rb +13 -0
  108. data/pry-0.16.0/lib/pry/input_completer.rb +283 -0
  109. data/pry-0.16.0/lib/pry/input_lock.rb +129 -0
  110. data/pry-0.16.0/lib/pry/inspector.rb +39 -0
  111. data/pry-0.16.0/lib/pry/last_exception.rb +61 -0
  112. data/pry-0.16.0/lib/pry/method/disowned.rb +67 -0
  113. data/pry-0.16.0/lib/pry/method/patcher.rb +131 -0
  114. data/pry-0.16.0/lib/pry/method/weird_method_locator.rb +222 -0
  115. data/pry-0.16.0/lib/pry/method.rb +599 -0
  116. data/pry-0.16.0/lib/pry/object_path.rb +91 -0
  117. data/pry-0.16.0/lib/pry/output.rb +136 -0
  118. data/pry-0.16.0/lib/pry/pager.rb +249 -0
  119. data/pry-0.16.0/lib/pry/prompt.rb +214 -0
  120. data/pry-0.16.0/lib/pry/pry_class.rb +371 -0
  121. data/pry-0.16.0/lib/pry/pry_instance.rb +663 -0
  122. data/pry-0.16.0/lib/pry/repl.rb +326 -0
  123. data/pry-0.16.0/lib/pry/repl_file_loader.rb +79 -0
  124. data/pry-0.16.0/lib/pry/ring.rb +89 -0
  125. data/pry-0.16.0/lib/pry/slop/LICENSE +20 -0
  126. data/pry-0.16.0/lib/pry/slop/commands.rb +190 -0
  127. data/pry-0.16.0/lib/pry/slop/option.rb +210 -0
  128. data/pry-0.16.0/lib/pry/slop.rb +672 -0
  129. data/pry-0.16.0/lib/pry/syntax_highlighter.rb +26 -0
  130. data/pry-0.16.0/lib/pry/system_command_handler.rb +17 -0
  131. data/pry-0.16.0/lib/pry/testable/evalable.rb +24 -0
  132. data/pry-0.16.0/lib/pry/testable/mockable.rb +22 -0
  133. data/pry-0.16.0/lib/pry/testable/pry_tester.rb +88 -0
  134. data/pry-0.16.0/lib/pry/testable/utility.rb +34 -0
  135. data/pry-0.16.0/lib/pry/testable/variables.rb +52 -0
  136. data/pry-0.16.0/lib/pry/testable.rb +68 -0
  137. data/pry-0.16.0/lib/pry/version.rb +5 -0
  138. data/pry-0.16.0/lib/pry/warning.rb +20 -0
  139. data/pry-0.16.0/lib/pry/wrapped_module/candidate.rb +145 -0
  140. data/pry-0.16.0/lib/pry/wrapped_module.rb +382 -0
  141. data/pry-0.16.0/lib/pry.rb +148 -0
  142. data/super-smart-mod.gemspec +12 -0
  143. metadata +182 -0
@@ -0,0 +1,520 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+ require 'shellwords'
5
+
6
+ class Pry
7
+ # The super-class of all commands, new commands should be created by calling
8
+ # {Pry::CommandSet#command} which creates a BlockCommand or
9
+ # {Pry::CommandSet#create_command} which creates a ClassCommand. Please don't
10
+ # use this class directly.
11
+ class Command
12
+ extend Helpers::DocumentationHelpers
13
+ extend CodeObject::Helpers
14
+
15
+ include Pry::Helpers::BaseHelpers
16
+ include Pry::Helpers::CommandHelpers
17
+ include Pry::Helpers::Text
18
+
19
+ # represents a void return value for a command
20
+ VOID_VALUE = Object.new
21
+
22
+ # give it a nice inspect
23
+ def VOID_VALUE.inspect
24
+ "void"
25
+ end
26
+
27
+ # Properties of the command itself (as passed as arguments to
28
+ # {CommandSet#command} or {CommandSet#create_command}).
29
+ class << self
30
+ attr_writer :block
31
+ attr_writer :description
32
+ attr_writer :command_options
33
+ attr_writer :match
34
+
35
+ def match(arg = nil)
36
+ if arg
37
+ @command_options ||= default_options(arg)
38
+ @command_options[:listing] = arg.is_a?(String) ? arg : arg.inspect
39
+ @match = arg
40
+ end
41
+ @match ||= nil
42
+ end
43
+
44
+ # Define or get the command's description
45
+ def description(arg = nil)
46
+ @description = arg if arg
47
+ @description ||= nil
48
+ end
49
+
50
+ # Define or get the command's options
51
+ def command_options(arg = nil)
52
+ @command_options ||= default_options(match)
53
+ @command_options.merge!(arg) if arg
54
+ @command_options
55
+ end
56
+ # backward compatibility
57
+ alias options command_options
58
+ alias options= command_options=
59
+
60
+ # Define or get the command's banner
61
+ def banner(arg = nil)
62
+ @banner = arg if arg
63
+ @banner ||= description
64
+ end
65
+
66
+ def block
67
+ @block || instance_method(:process)
68
+ end
69
+
70
+ def source
71
+ file, line = block.source_location
72
+ strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line))
73
+ end
74
+
75
+ def doc
76
+ new.help
77
+ end
78
+
79
+ def source_file
80
+ Array(block.source_location).first
81
+ end
82
+ alias file source_file
83
+
84
+ def source_line
85
+ Array(block.source_location).last
86
+ end
87
+ alias line source_line
88
+
89
+ def default_options(match)
90
+ {
91
+ keep_retval: false,
92
+ argument_required: false,
93
+ interpolate: true,
94
+ shellwords: true,
95
+ listing: (match.is_a?(String) ? match : match.inspect),
96
+ use_prefix: true,
97
+ takes_block: false
98
+ }
99
+ end
100
+
101
+ def name
102
+ super.to_s == "" ? "#<class(Pry::Command #{match.inspect})>" : super
103
+ end
104
+
105
+ def inspect
106
+ name
107
+ end
108
+
109
+ def command_name
110
+ options[:listing]
111
+ end
112
+
113
+ # Create a new command with the given properties.
114
+ # @param [String, Regex] match The thing that triggers this command
115
+ # @param [String] description The description to appear in `help`
116
+ # @param [Hash] options Behavioral options (see {Pry::CommandSet#command})
117
+ # @param [Module] helpers A module of helper functions to be included.
118
+ # @yield optional, used for BlockCommands
119
+ # @return [Class] (a subclass of {Pry::Command})
120
+ def subclass(match, description, options, helpers, &block)
121
+ klass = Class.new(self)
122
+ klass.send(:include, helpers)
123
+ klass.match = match
124
+ klass.description = description
125
+ klass.command_options = options
126
+ klass.block = block
127
+ klass
128
+ end
129
+
130
+ # Should this command be called for the given line?
131
+ # @param [String] val A line input at the REPL
132
+ # @return [Boolean]
133
+ def matches?(val)
134
+ command_regex =~ val
135
+ end
136
+
137
+ # How well does this command match the given line?
138
+ #
139
+ # Higher scores are better because they imply that this command matches
140
+ # the line more closely.
141
+ #
142
+ # The score is calculated by taking the number of characters at the start
143
+ # of the string that are used only to identify the command, not as part of
144
+ # the arguments.
145
+ #
146
+ # @example
147
+ # /\.(.*)/.match_score(".foo") #=> 1
148
+ # /\.*(.*)/.match_score("...foo") #=> 3
149
+ # 'hi'.match_score("hi there") #=> 2
150
+ #
151
+ # @param [String] val A line input at the REPL
152
+ # @return [Fixnum]
153
+ def match_score(val)
154
+ if command_regex =~ val
155
+ if Regexp.last_match.size > 1
156
+ Regexp.last_match.begin(1)
157
+ else
158
+ Regexp.last_match.end(0)
159
+ end
160
+ else
161
+ -1
162
+ end
163
+ end
164
+
165
+ def command_regex
166
+ prefix = convert_to_regex(Pry.config.command_prefix)
167
+ prefix = "(?:#{prefix})?" unless options[:use_prefix]
168
+
169
+ /\A#{prefix}#{convert_to_regex(match)}(?!\S)/
170
+ end
171
+
172
+ def convert_to_regex(obj)
173
+ case obj
174
+ when String
175
+ Regexp.escape(obj)
176
+ else
177
+ obj
178
+ end
179
+ end
180
+
181
+ # The group in which the command should be displayed in "help" output.
182
+ # This is usually auto-generated from directory naming, but it can be
183
+ # manually overridden if necessary.
184
+ # Group should not be changed once it is initialized.
185
+ def group(name = nil)
186
+ @group ||= begin
187
+ name || case Pry::Method(block).source_file
188
+ when %r{/pry/.*_commands/(.*).rb}
189
+ Regexp.last_match(1).capitalize.tr('_', " ")
190
+ when /(pry-\w+)-([\d\.]+([\w\.]+)?)/
191
+ name = Regexp.last_match(1)
192
+ version = Regexp.last_match(2)
193
+ "#{name} (v#{version})"
194
+ when /pryrc/
195
+ "pryrc"
196
+ else
197
+ "(other)"
198
+ end
199
+ end
200
+ end
201
+
202
+ def state
203
+ Pry::CommandState.default.state_for(self)
204
+ end
205
+ end
206
+
207
+ # Properties of one execution of a command (passed by {Pry#run_command} as a hash of
208
+ # context and expanded in `#initialize`
209
+ attr_accessor :output
210
+ attr_accessor :target
211
+ attr_accessor :captures
212
+ attr_accessor :eval_string
213
+ attr_accessor :arg_string
214
+ attr_accessor :context
215
+ attr_accessor :command_set
216
+ attr_accessor :hooks
217
+ attr_accessor :pry_instance
218
+ alias _pry_= pry_instance=
219
+
220
+ # The block we pass *into* a command so long as `:takes_block` is
221
+ # not equal to `false`
222
+ # @example
223
+ # my-command | do
224
+ # puts "block content"
225
+ # end
226
+ attr_accessor :command_block
227
+
228
+ # Instantiate a command, in preparation for calling it.
229
+ # @param [Hash] context The runtime context to use with this command.
230
+ def initialize(context = {})
231
+ self.context = context
232
+ self.target = context[:target]
233
+ self.output = context[:output]
234
+ self.eval_string = context[:eval_string]
235
+ self.command_set = context[:command_set]
236
+ self.hooks = context[:hooks]
237
+ self.pry_instance = context[:pry_instance]
238
+ end
239
+
240
+ # Make those properties accessible to instances
241
+ def name
242
+ self.class.name
243
+ end
244
+
245
+ def match
246
+ self.class.match
247
+ end
248
+
249
+ def description
250
+ self.class.description
251
+ end
252
+
253
+ def block
254
+ self.class.block
255
+ end
256
+
257
+ def command_options
258
+ self.class.options
259
+ end
260
+
261
+ def command_name
262
+ self.class.command_name
263
+ end
264
+
265
+ def source
266
+ self.class.source
267
+ end
268
+
269
+ # Run a command from another command.
270
+ # @param [String] command_string The string that invokes the command
271
+ # @param [Array] args Further arguments to pass to the command
272
+ # @example
273
+ # run "show-input"
274
+ # @example
275
+ # run ".ls"
276
+ # @example
277
+ # run "amend-line", "5", 'puts "hello world"'
278
+ def run(command_string, *args)
279
+ command_string = pry_instance.config.command_prefix.to_s + command_string
280
+ complete_string = "#{command_string} #{args.join(' ')}".rstrip
281
+ command_set.process_line(complete_string, context)
282
+ end
283
+
284
+ def commands
285
+ command_set.to_hash
286
+ end
287
+
288
+ def void
289
+ VOID_VALUE
290
+ end
291
+
292
+ def _pry_
293
+ Pry::Warning.warn('_pry_ is deprecated, use pry_instance instead')
294
+ pry_instance
295
+ end
296
+
297
+ # @return [Object] The value of `self` inside the `target` binding.
298
+ def target_self
299
+ target.eval('self')
300
+ end
301
+
302
+ # @return [Hash] Pry commands can store arbitrary state
303
+ # here. This state persists between subsequent command invocations.
304
+ # All state saved here is unique to the command, it does not
305
+ # need to be namespaced.
306
+ # @example
307
+ # state.my_state = "my state" # this will not conflict with any
308
+ # # `state.my_state` used in another command.
309
+ def state
310
+ self.class.state
311
+ end
312
+
313
+ # Revaluate the string (str) and perform interpolation.
314
+ # @param [String] str The string to reevaluate with interpolation.
315
+ #
316
+ # @return [String] The reevaluated string with interpolations
317
+ # applied (if any).
318
+ def interpolate_string(str)
319
+ dumped_str = str.dump
320
+ if dumped_str.gsub!(/\\\#\{/, '#{')
321
+ target.eval(dumped_str)
322
+ else
323
+ str
324
+ end
325
+ end
326
+
327
+ # Display a warning if a command collides with a local/method in
328
+ # the current scope.
329
+ def check_for_command_collision(command_match, arg_string)
330
+ collision_type = target.eval("defined?(#{command_match})")
331
+ collision_type ||= 'local-variable' if arg_string =~ %r{\A\s*[-+*/%&|^]*=}
332
+
333
+ if collision_type
334
+ output.puts(
335
+ "#{Helpers::Text.bold('WARNING:')} Calling Pry command '#{command_match}', " \
336
+ "which conflicts with a #{collision_type}.\n\n"
337
+ )
338
+ end
339
+ rescue Pry::RescuableException # rubocop:disable Lint/HandleExceptions
340
+ end
341
+
342
+ # Extract necessary information from a line that Command.matches? this
343
+ # command.
344
+ #
345
+ # Returns an array of four elements:
346
+ #
347
+ # ```
348
+ # [String] the portion of the line that matched with the Command match
349
+ # [String] a string of all the arguments (i.e. everything but the match)
350
+ # [Array] the captures caught by the command_regex
351
+ # [Array] the arguments obtained by splitting the arg_string
352
+ # ```
353
+ #
354
+ # @param [String] val The line of input
355
+ # @return [Array]
356
+ def tokenize(val)
357
+ val = interpolate_string(val) if command_options[:interpolate]
358
+
359
+ self.class.command_regex =~ val
360
+
361
+ # please call Command.matches? before Command#call_safely
362
+ unless Regexp.last_match
363
+ raise CommandError, "fatal: called a command which didn't match?!"
364
+ end
365
+
366
+ captures = Regexp.last_match.captures
367
+ pos = Regexp.last_match.end(0)
368
+
369
+ arg_string = val[pos..-1]
370
+
371
+ # remove the one leading space if it exists
372
+ arg_string.slice!(0) if arg_string.start_with?(" ")
373
+
374
+ # process and pass a block if one is found
375
+ pass_block(arg_string) if command_options[:takes_block]
376
+
377
+ args =
378
+ if arg_string
379
+ if command_options[:shellwords]
380
+ Shellwords.shellwords(arg_string)
381
+ else
382
+ arg_string.split(" ")
383
+ end
384
+ else
385
+ []
386
+ end
387
+
388
+ [val[0..pos].rstrip, arg_string, captures, args]
389
+ end
390
+
391
+ # Process a line that Command.matches? this command.
392
+ # @param [String] line The line to process
393
+ # @return [Object, Command::VOID_VALUE]
394
+ def process_line(line)
395
+ command_match, arg_string, captures, args = tokenize(line)
396
+
397
+ if Pry.config.collision_warning
398
+ check_for_command_collision(command_match, arg_string)
399
+ end
400
+
401
+ self.arg_string = arg_string
402
+ self.captures = captures
403
+
404
+ call_safely(*(captures + args))
405
+ end
406
+
407
+ # Generate completions for this command
408
+ #
409
+ # @param [String] _search The line typed so far
410
+ # @return [Array<String>] Completion words
411
+ def complete(_search)
412
+ []
413
+ end
414
+
415
+ private
416
+
417
+ # Run the command with the given `args`.
418
+ #
419
+ # This is a public wrapper around `#call` which ensures all preconditions
420
+ # are met.
421
+ #
422
+ # @param [Array<String>] args The arguments to pass to this command.
423
+ # @return [Object] The return value of the `#call` method, or
424
+ # {Command::VOID_VALUE}.
425
+ def call_safely(*args)
426
+ if command_options[:argument_required] && args.empty?
427
+ raise CommandError, "The command '#{command_name}' requires an argument."
428
+ end
429
+
430
+ ret = use_unpatched_symbol do
431
+ call_with_hooks(*args)
432
+ end
433
+ command_options[:keep_retval] ? ret : void
434
+ end
435
+
436
+ def use_unpatched_symbol
437
+ call_method = Symbol.method_defined?(:call) && Symbol.instance_method(:call)
438
+ Symbol.class_eval { undef :call } if call_method
439
+ yield
440
+ ensure
441
+ Symbol.instance_eval { define_method(:call, call_method) } if call_method
442
+ end
443
+
444
+ # Pass a block argument to a command.
445
+ # @param [String] arg_string The arguments (as a string) passed to the command.
446
+ # We inspect these for a '| do' or a '| {' and if we find it we use it
447
+ # to start a block input sequence. Once we have a complete
448
+ # block, we save it to an accessor that can be retrieved from the command context.
449
+ # Note that if we find the '| do' or '| {' we delete this and the
450
+ # elements following it from `arg_string`.
451
+ def pass_block(arg_string)
452
+ # Workaround for weird JRuby bug where rindex in this case can return nil
453
+ # even when there's a match.
454
+ arg_string.scan(/\| *(?:do|\{)/)
455
+ block_index = $LAST_MATCH_INFO && $LAST_MATCH_INFO.offset(0)[0]
456
+
457
+ return unless block_index
458
+
459
+ block_init_string = arg_string.slice!(block_index..-1)[1..-1]
460
+ prime_string = "proc #{block_init_string}\n"
461
+
462
+ block_string =
463
+ if !Pry::Code.complete_expression?(prime_string)
464
+ pry_instance.r(target, prime_string)
465
+ else
466
+ prime_string
467
+ end
468
+
469
+ begin
470
+ self.command_block = target.eval(block_string)
471
+ rescue Pry::RescuableException
472
+ raise CommandError, "Incomplete block definition."
473
+ end
474
+ end
475
+
476
+ def find_hooks(event)
477
+ event_name = "#{event}_#{command_name}"
478
+ (hooks || Pry.hooks || self.class.hooks).get_hooks(event_name).values
479
+ end
480
+
481
+ def before_hooks
482
+ find_hooks('before')
483
+ end
484
+
485
+ def after_hooks
486
+ find_hooks('after')
487
+ end
488
+
489
+ # Run the `#call` method and all the registered hooks.
490
+ # @param [Array<String>] args The arguments to `#call`
491
+ # @return [Object] The return value from `#call`
492
+ def call_with_hooks(*args)
493
+ before_hooks.each { |block| instance_exec(*args, &block) }
494
+
495
+ ret = call(*args)
496
+
497
+ after_hooks.each do |block|
498
+ ret = instance_exec(*args, &block)
499
+ end
500
+
501
+ ret
502
+ end
503
+
504
+ # Normalize method arguments according to its arity.
505
+ #
506
+ # @param [Integer] method
507
+ # @param [Array] args
508
+ # @return [Array] a (possibly shorter) array of the arguments to pass
509
+ def normalize_method_args(method, args)
510
+ case method.arity
511
+ when -1
512
+ args
513
+ when 0
514
+ []
515
+ else
516
+ args.values_at(*(0..(method.arity - 1)).to_a)
517
+ end
518
+ end
519
+ end
520
+ end