pry 0.10.pre.1-i386-mswin32 → 0.10.0.pre3-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +2 -2
  4. data/{README.markdown → README.md} +41 -35
  5. data/lib/pry.rb +82 -139
  6. data/lib/pry/cli.rb +77 -30
  7. data/lib/pry/code.rb +122 -183
  8. data/lib/pry/code/code_file.rb +103 -0
  9. data/lib/pry/code/code_range.rb +71 -0
  10. data/lib/pry/code/loc.rb +92 -0
  11. data/lib/pry/code_object.rb +172 -0
  12. data/lib/pry/color_printer.rb +55 -0
  13. data/lib/pry/command.rb +184 -28
  14. data/lib/pry/command_set.rb +113 -59
  15. data/lib/pry/commands.rb +4 -27
  16. data/lib/pry/commands/amend_line.rb +99 -0
  17. data/lib/pry/commands/bang.rb +20 -0
  18. data/lib/pry/commands/bang_pry.rb +17 -0
  19. data/lib/pry/commands/cat.rb +62 -0
  20. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  21. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  22. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  23. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  24. data/lib/pry/commands/cd.rb +41 -0
  25. data/lib/pry/commands/change_inspector.rb +27 -0
  26. data/lib/pry/commands/change_prompt.rb +26 -0
  27. data/lib/pry/commands/code_collector.rb +165 -0
  28. data/lib/pry/commands/disable_pry.rb +27 -0
  29. data/lib/pry/commands/disabled_commands.rb +2 -0
  30. data/lib/pry/commands/easter_eggs.rb +112 -0
  31. data/lib/pry/commands/edit.rb +195 -0
  32. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  33. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  34. data/lib/pry/commands/exit.rb +42 -0
  35. data/lib/pry/commands/exit_all.rb +29 -0
  36. data/lib/pry/commands/exit_program.rb +23 -0
  37. data/lib/pry/commands/find_method.rb +193 -0
  38. data/lib/pry/commands/fix_indent.rb +19 -0
  39. data/lib/pry/commands/gem_cd.rb +26 -0
  40. data/lib/pry/commands/gem_install.rb +32 -0
  41. data/lib/pry/commands/gem_list.rb +33 -0
  42. data/lib/pry/commands/gem_open.rb +29 -0
  43. data/lib/pry/commands/gist.rb +101 -0
  44. data/lib/pry/commands/help.rb +164 -0
  45. data/lib/pry/commands/hist.rb +180 -0
  46. data/lib/pry/commands/import_set.rb +22 -0
  47. data/lib/pry/commands/install_command.rb +53 -0
  48. data/lib/pry/commands/jump_to.rb +29 -0
  49. data/lib/pry/commands/list_inspectors.rb +35 -0
  50. data/lib/pry/commands/list_prompts.rb +35 -0
  51. data/lib/pry/commands/ls.rb +114 -0
  52. data/lib/pry/commands/ls/constants.rb +47 -0
  53. data/lib/pry/commands/ls/formatter.rb +49 -0
  54. data/lib/pry/commands/ls/globals.rb +48 -0
  55. data/lib/pry/commands/ls/grep.rb +21 -0
  56. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  57. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  58. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  59. data/lib/pry/commands/ls/local_names.rb +35 -0
  60. data/lib/pry/commands/ls/local_vars.rb +39 -0
  61. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  62. data/lib/pry/commands/ls/methods.rb +57 -0
  63. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  64. data/lib/pry/commands/ls/self_methods.rb +32 -0
  65. data/lib/pry/commands/nesting.rb +25 -0
  66. data/lib/pry/commands/play.rb +103 -0
  67. data/lib/pry/commands/pry_backtrace.rb +25 -0
  68. data/lib/pry/commands/pry_version.rb +17 -0
  69. data/lib/pry/commands/raise_up.rb +32 -0
  70. data/lib/pry/commands/reload_code.rb +62 -0
  71. data/lib/pry/commands/reset.rb +18 -0
  72. data/lib/pry/commands/ri.rb +60 -0
  73. data/lib/pry/commands/save_file.rb +61 -0
  74. data/lib/pry/commands/shell_command.rb +48 -0
  75. data/lib/pry/commands/shell_mode.rb +25 -0
  76. data/lib/pry/commands/show_doc.rb +83 -0
  77. data/lib/pry/commands/show_info.rb +195 -0
  78. data/lib/pry/commands/show_input.rb +17 -0
  79. data/lib/pry/commands/show_source.rb +50 -0
  80. data/lib/pry/commands/simple_prompt.rb +22 -0
  81. data/lib/pry/commands/stat.rb +40 -0
  82. data/lib/pry/commands/switch_to.rb +23 -0
  83. data/lib/pry/commands/toggle_color.rb +24 -0
  84. data/lib/pry/commands/watch_expression.rb +105 -0
  85. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  86. data/lib/pry/commands/whereami.rb +190 -0
  87. data/lib/pry/commands/wtf.rb +57 -0
  88. data/lib/pry/config.rb +20 -229
  89. data/lib/pry/config/behavior.rb +139 -0
  90. data/lib/pry/config/convenience.rb +26 -0
  91. data/lib/pry/config/default.rb +165 -0
  92. data/lib/pry/core_extensions.rb +59 -38
  93. data/lib/pry/editor.rb +133 -0
  94. data/lib/pry/exceptions.rb +77 -0
  95. data/lib/pry/helpers.rb +1 -0
  96. data/lib/pry/helpers/base_helpers.rb +40 -154
  97. data/lib/pry/helpers/command_helpers.rb +19 -130
  98. data/lib/pry/helpers/documentation_helpers.rb +21 -11
  99. data/lib/pry/helpers/table.rb +109 -0
  100. data/lib/pry/helpers/text.rb +8 -9
  101. data/lib/pry/history.rb +61 -45
  102. data/lib/pry/history_array.rb +11 -1
  103. data/lib/pry/hooks.rb +10 -32
  104. data/lib/pry/indent.rb +110 -38
  105. data/lib/pry/input_completer.rb +242 -0
  106. data/lib/pry/input_lock.rb +132 -0
  107. data/lib/pry/inspector.rb +27 -0
  108. data/lib/pry/last_exception.rb +61 -0
  109. data/lib/pry/method.rb +199 -200
  110. data/lib/pry/method/disowned.rb +53 -0
  111. data/lib/pry/method/patcher.rb +125 -0
  112. data/lib/pry/method/weird_method_locator.rb +186 -0
  113. data/lib/pry/module_candidate.rb +39 -33
  114. data/lib/pry/object_path.rb +82 -0
  115. data/lib/pry/output.rb +50 -0
  116. data/lib/pry/pager.rb +234 -0
  117. data/lib/pry/plugins.rb +4 -3
  118. data/lib/pry/prompt.rb +26 -0
  119. data/lib/pry/pry_class.rb +199 -227
  120. data/lib/pry/pry_instance.rb +344 -403
  121. data/lib/pry/rbx_path.rb +1 -1
  122. data/lib/pry/repl.rb +202 -0
  123. data/lib/pry/repl_file_loader.rb +20 -26
  124. data/lib/pry/rubygem.rb +82 -0
  125. data/lib/pry/terminal.rb +79 -0
  126. data/lib/pry/test/helper.rb +170 -0
  127. data/lib/pry/version.rb +1 -1
  128. data/lib/pry/wrapped_module.rb +133 -48
  129. metadata +132 -197
  130. data/.document +0 -2
  131. data/.gemtest +0 -0
  132. data/.gitignore +0 -16
  133. data/.travis.yml +0 -17
  134. data/.yardopts +0 -1
  135. data/CHANGELOG +0 -387
  136. data/CONTRIBUTORS +0 -36
  137. data/Gemfile +0 -2
  138. data/Rakefile +0 -137
  139. data/TODO +0 -117
  140. data/examples/example_basic.rb +0 -15
  141. data/examples/example_command_override.rb +0 -32
  142. data/examples/example_commands.rb +0 -36
  143. data/examples/example_hooks.rb +0 -9
  144. data/examples/example_image_edit.rb +0 -67
  145. data/examples/example_input.rb +0 -7
  146. data/examples/example_input2.rb +0 -29
  147. data/examples/example_output.rb +0 -11
  148. data/examples/example_print.rb +0 -6
  149. data/examples/example_prompt.rb +0 -9
  150. data/examples/helper.rb +0 -6
  151. data/lib/pry/completion.rb +0 -221
  152. data/lib/pry/custom_completions.rb +0 -6
  153. data/lib/pry/default_commands/cd.rb +0 -81
  154. data/lib/pry/default_commands/commands.rb +0 -62
  155. data/lib/pry/default_commands/context.rb +0 -98
  156. data/lib/pry/default_commands/easter_eggs.rb +0 -95
  157. data/lib/pry/default_commands/editing.rb +0 -420
  158. data/lib/pry/default_commands/find_method.rb +0 -169
  159. data/lib/pry/default_commands/gems.rb +0 -84
  160. data/lib/pry/default_commands/gist.rb +0 -187
  161. data/lib/pry/default_commands/help.rb +0 -127
  162. data/lib/pry/default_commands/hist.rb +0 -120
  163. data/lib/pry/default_commands/input_and_output.rb +0 -306
  164. data/lib/pry/default_commands/introspection.rb +0 -410
  165. data/lib/pry/default_commands/ls.rb +0 -272
  166. data/lib/pry/default_commands/misc.rb +0 -38
  167. data/lib/pry/default_commands/navigating_pry.rb +0 -110
  168. data/lib/pry/default_commands/whereami.rb +0 -92
  169. data/lib/pry/extended_commands/experimental.rb +0 -7
  170. data/lib/pry/rbx_method.rb +0 -13
  171. data/man/pry.1 +0 -195
  172. data/man/pry.1.html +0 -204
  173. data/man/pry.1.ronn +0 -141
  174. data/pry.gemspec +0 -46
  175. data/test/candidate_helper1.rb +0 -11
  176. data/test/candidate_helper2.rb +0 -8
  177. data/test/helper.rb +0 -223
  178. data/test/test_cli.rb +0 -78
  179. data/test/test_code.rb +0 -201
  180. data/test/test_command.rb +0 -712
  181. data/test/test_command_helpers.rb +0 -9
  182. data/test/test_command_integration.rb +0 -668
  183. data/test/test_command_set.rb +0 -610
  184. data/test/test_completion.rb +0 -62
  185. data/test/test_control_d_handler.rb +0 -45
  186. data/test/test_default_commands/example.erb +0 -5
  187. data/test/test_default_commands/test_cd.rb +0 -318
  188. data/test/test_default_commands/test_context.rb +0 -280
  189. data/test/test_default_commands/test_documentation.rb +0 -314
  190. data/test/test_default_commands/test_find_method.rb +0 -50
  191. data/test/test_default_commands/test_gems.rb +0 -18
  192. data/test/test_default_commands/test_help.rb +0 -57
  193. data/test/test_default_commands/test_input.rb +0 -428
  194. data/test/test_default_commands/test_introspection.rb +0 -511
  195. data/test/test_default_commands/test_ls.rb +0 -151
  196. data/test/test_default_commands/test_shell.rb +0 -343
  197. data/test/test_default_commands/test_show_source.rb +0 -432
  198. data/test/test_exception_whitelist.rb +0 -21
  199. data/test/test_history_array.rb +0 -65
  200. data/test/test_hooks.rb +0 -521
  201. data/test/test_indent.rb +0 -277
  202. data/test/test_input_stack.rb +0 -86
  203. data/test/test_method.rb +0 -401
  204. data/test/test_pry.rb +0 -463
  205. data/test/test_pry_defaults.rb +0 -419
  206. data/test/test_pry_history.rb +0 -84
  207. data/test/test_pry_output.rb +0 -41
  208. data/test/test_sticky_locals.rb +0 -155
  209. data/test/test_syntax_checking.rb +0 -65
  210. data/test/test_wrapped_module.rb +0 -174
  211. data/test/testrc +0 -2
  212. data/test/testrcbad +0 -2
  213. data/wiki/Customizing-pry.md +0 -397
  214. data/wiki/Home.md +0 -4
@@ -1,9 +1,14 @@
1
+ require 'delegate'
2
+ require 'pry/helpers/documentation_helpers'
3
+
1
4
  class Pry
2
5
 
3
6
  # The super-class of all commands, new commands should be created by calling
4
7
  # {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command}
5
8
  # which creates a ClassCommand. Please don't use this class directly.
6
9
  class Command
10
+ extend Helpers::DocumentationHelpers
11
+ extend CodeObject::Helpers
7
12
 
8
13
  # represents a void return value for a command
9
14
  VOID_VALUE = Object.new
@@ -20,19 +25,23 @@ class Pry
20
25
  attr_writer :match
21
26
 
22
27
  def match(arg=nil)
23
- @match = arg if arg
24
- @match
28
+ if arg
29
+ @command_options ||= default_options(arg)
30
+ @command_options[:listing] = arg.is_a?(String) ? arg : arg.inspect
31
+ @match = arg
32
+ end
33
+ @match ||= nil
25
34
  end
26
35
 
27
36
  # Define or get the command's description
28
37
  def description(arg=nil)
29
38
  @description = arg if arg
30
- @description
39
+ @description ||= nil
31
40
  end
32
41
 
33
42
  # Define or get the command's options
34
43
  def command_options(arg=nil)
35
- @command_options ||= {}
44
+ @command_options ||= default_options(match)
36
45
  @command_options.merge!(arg) if arg
37
46
  @command_options
38
47
  end
@@ -47,7 +56,43 @@ class Pry
47
56
  end
48
57
 
49
58
  def block
50
- @block || instance_method(:process) && instance_method(:process)
59
+ @block || instance_method(:process)
60
+ end
61
+
62
+ def source
63
+ file, line = block.source_location
64
+ strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line))
65
+ end
66
+
67
+ def doc
68
+ new.help
69
+ end
70
+
71
+ def source_location
72
+ block.source_location
73
+ end
74
+
75
+ def source_file
76
+ Array(block.source_location).first
77
+ end
78
+ alias_method :file, :source_file
79
+
80
+ def source_line
81
+ Array(block.source_location).last
82
+ end
83
+ alias_method :line, :source_line
84
+
85
+ def default_options(match)
86
+ {
87
+ :requires_gem => [],
88
+ :keep_retval => false,
89
+ :argument_required => false,
90
+ :interpolate => true,
91
+ :shellwords => true,
92
+ :listing => (String === match ? match : match.inspect),
93
+ :use_prefix => true,
94
+ :takes_block => false
95
+ }
51
96
  end
52
97
  end
53
98
 
@@ -57,16 +102,23 @@ class Pry
57
102
  def description; self.class.description; end
58
103
  def block; self.class.block; end
59
104
  def command_options; self.class.options; end
60
- def command_name; command_options[:listing]; end
105
+ def command_name; self.class.command_name; end
106
+ def source; self.class.source; end
107
+ def source_location; self.class.source_location; end
61
108
 
62
109
  class << self
63
110
  def name
64
111
  super.to_s == "" ? "#<class(Pry::Command #{match.inspect})>" : super
65
112
  end
113
+
66
114
  def inspect
67
115
  name
68
116
  end
69
117
 
118
+ def command_name
119
+ self.options[:listing]
120
+ end
121
+
70
122
  # Create a new command with the given properties.
71
123
  # @param [String, Regex] match The thing that triggers this command
72
124
  # @param [String] description The description to appear in `help`
@@ -123,7 +175,7 @@ class Pry
123
175
  end
124
176
 
125
177
  def command_regex
126
- pr = defined?(Pry.config.command_prefix) ? Pry.config.command_prefix : ""
178
+ pr = Pry.respond_to?(:config) ? Pry.config.command_prefix : ""
127
179
  prefix = convert_to_regex(pr)
128
180
  prefix = "(?:#{prefix})?" unless options[:use_prefix]
129
181
 
@@ -142,6 +194,7 @@ class Pry
142
194
  # The group in which the command should be displayed in "help" output.
143
195
  # This is usually auto-generated from directory naming, but it can be
144
196
  # manually overridden if necessary.
197
+ # Group should not be changed once it is initialized.
145
198
  def group(name=nil)
146
199
  @group ||= if name
147
200
  name
@@ -149,7 +202,7 @@ class Pry
149
202
  case Pry::Method(block).source_file
150
203
  when %r{/pry/.*_commands/(.*).rb}
151
204
  $1.capitalize.gsub(/_/, " ")
152
- when %r{(pry-\w+)-([\d\.]+([\w\d\.]+)?)}
205
+ when %r{(pry-\w+)-([\d\.]+([\w\.]+)?)}
153
206
  name, version = $1, $2
154
207
  "#{name.to_s} (v#{version.to_s})"
155
208
  when /pryrc/
@@ -190,12 +243,13 @@ class Pry
190
243
  # @example
191
244
  # run "amend-line", "5", 'puts "hello world"'
192
245
  def run(command_string, *args)
246
+ command_string = _pry_.config.command_prefix.to_s + command_string
193
247
  complete_string = "#{command_string} #{args.join(" ")}".rstrip
194
248
  command_set.process_line(complete_string, context)
195
249
  end
196
250
 
197
251
  def commands
198
- command_set.commands
252
+ command_set.to_hash
199
253
  end
200
254
 
201
255
  def text
@@ -209,7 +263,6 @@ class Pry
209
263
  include Pry::Helpers::BaseHelpers
210
264
  include Pry::Helpers::CommandHelpers
211
265
 
212
-
213
266
  # Instantiate a command, in preparation for calling it.
214
267
  # @param [Hash] context The runtime context to use with this command.
215
268
  def initialize(context={})
@@ -232,7 +285,7 @@ class Pry
232
285
  # state.my_state = "my state" # this will not conflict with any
233
286
  # # `state.my_state` used in another command.
234
287
  def state
235
- _pry_.command_state[match] ||= OpenStruct.new
288
+ _pry_.command_state[match] ||= Pry::Config.from_hash({})
236
289
  end
237
290
 
238
291
  # Revaluate the string (str) and perform interpolation.
@@ -256,8 +309,7 @@ class Pry
256
309
  collision_type ||= 'local-variable' if arg_string.match(%r{\A\s*[-+*/%&|^]*=})
257
310
 
258
311
  if collision_type
259
- output.puts "#{Pry::Helpers::Text.bold('WARNING:')} Calling Pry command '#{command_match}'," +
260
- "which conflicts with a #{collision_type}.\n\n"
312
+ output.puts "#{text.bold('WARNING:')} Calling Pry command '#{command_match}', which conflicts with a #{collision_type}.\n\n"
261
313
  end
262
314
  rescue Pry::RescuableException
263
315
  end
@@ -325,7 +377,10 @@ class Pry
325
377
  # Note that if we find the '| do' or '| {' we delete this and the
326
378
  # elements following it from `arg_string`.
327
379
  def pass_block(arg_string)
328
- block_index = arg_string.rindex(/\| *(?:do|\{)/)
380
+ # Workaround for weird JRuby bug where rindex in this case can return nil
381
+ # even when there's a match.
382
+ arg_string.scan(/\| *(?:do|\{)/)
383
+ block_index = $~ && $~.offset(0)[0]
329
384
 
330
385
  return if !block_index
331
386
 
@@ -358,8 +413,8 @@ class Pry
358
413
  def call_safely(*args)
359
414
  unless dependencies_met?
360
415
  gems_needed = Array(command_options[:requires_gem])
361
- gems_not_installed = gems_needed.select { |g| !gem_installed?(g) }
362
- output.puts "\nThe command '#{command_name}' is #{Helpers::Text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
416
+ gems_not_installed = gems_needed.select { |g| !Rubygem.installed?(g) }
417
+ output.puts "\nThe command '#{command_name}' is #{text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
363
418
  output.puts "-"
364
419
  output.puts "Type `install-command #{command_name}` to install the required gems and activate this command."
365
420
  return void
@@ -380,6 +435,14 @@ class Pry
380
435
  @dependencies_met ||= command_dependencies_met?(command_options)
381
436
  end
382
437
 
438
+ # Generate completions for this command
439
+ #
440
+ # @param [String] search The line typed so far
441
+ # @return [Array<String>] Completion words
442
+ def complete(search)
443
+ []
444
+ end
445
+
383
446
  private
384
447
 
385
448
  # Run the `#call` method and all the registered hooks.
@@ -437,7 +500,7 @@ class Pry
437
500
  end
438
501
  end
439
502
 
440
- # A super-class ofr Commands with structure.
503
+ # A super-class of Commands with structure.
441
504
  #
442
505
  # This class implements the bare-minimum functionality that a command should
443
506
  # have, namely a --help switch, and then delegates actual processing to its
@@ -449,13 +512,60 @@ class Pry
449
512
  # `setup` which will be called before `options`, for example to require any
450
513
  # gems your command needs to run, or to set up state.
451
514
  class ClassCommand < Command
515
+ class << self
516
+
517
+ # Ensure that subclasses inherit the options, description and
518
+ # match from a ClassCommand super class.
519
+ def inherited(klass)
520
+ klass.match match
521
+ klass.description description
522
+ klass.command_options options
523
+ end
524
+
525
+ def source
526
+ source_object.source
527
+ end
528
+
529
+ def doc
530
+ new.help
531
+ end
532
+
533
+ def source_location
534
+ source_object.source_location
535
+ end
536
+
537
+ def source_file
538
+ source_object.source_file
539
+ end
540
+ alias_method :file, :source_file
541
+
542
+ def source_line
543
+ source_object.source_line
544
+ end
545
+ alias_method :line, :source_line
546
+
547
+ private
548
+
549
+ # The object used to extract the source for the command.
550
+ #
551
+ # This should be a `Pry::Method(block)` for a command made with `create_command`
552
+ # and a `Pry::WrappedModule(self)` for a command that's a standard class.
553
+ # @return [Pry::WrappedModule, Pry::Method]
554
+ def source_object
555
+ @source_object ||= if name =~ /^[A-Z]/
556
+ Pry::WrappedModule(self)
557
+ else
558
+ Pry::Method(block)
559
+ end
560
+ end
561
+ end
452
562
 
453
563
  attr_accessor :opts
454
564
  attr_accessor :args
455
565
 
456
566
  # Set up `opts` and `args`, and then call `process`.
457
567
  #
458
- # This function will display help if necessary.
568
+ # This method will display help if necessary.
459
569
  #
460
570
  # @param [Array<String>] args The arguments passed
461
571
  # @return [Object] The return value of `process` or VOID_VALUE
@@ -478,32 +588,78 @@ class Pry
478
588
  slop.help
479
589
  end
480
590
 
481
- # Return an instance of Slop that can parse the options that this command accepts.
591
+ # Return an instance of Slop that can parse either subcommands or the
592
+ # options that this command accepts.
482
593
  def slop
483
594
  Slop.new do |opt|
484
595
  opt.banner(unindent(self.class.banner))
596
+ subcommands(opt)
485
597
  options(opt)
486
- opt.on(:h, :help, "Show this message.")
598
+ opt.on :h, :help, 'Show this message.'
487
599
  end
488
600
  end
489
601
 
490
- # A function called just before `options(opt)` as part of `call`.
602
+ # Generate shell completions
603
+ # @param [String] search The line typed so far
604
+ # @return [Array<String>] the words to complete
605
+ def complete(search)
606
+ slop.map do |opt|
607
+ [opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"]
608
+ end.flatten(1).compact + super
609
+ end
610
+
611
+ # A method called just before `options(opt)` as part of `call`.
491
612
  #
492
- # This function can be used to set up any context your command needs to run, for example
493
- # requiring gems, or setting default values for options.
613
+ # This method can be used to set up any context your command needs to run,
614
+ # for example requiring gems, or setting default values for options.
494
615
  #
495
616
  # @example
496
- # def setup;
617
+ # def setup
497
618
  # require 'gist'
498
619
  # @action = :method
499
620
  # end
500
621
  def setup; end
501
622
 
502
- # A function to setup Slop so it can parse the options your command expects.
623
+ # A method to setup Slop commands so it can parse the subcommands your
624
+ # command expects. If you need to set up default values, use `setup`
625
+ # instead.
626
+ #
627
+ # @example A minimal example
628
+ # def subcommands(cmd)
629
+ # cmd.command :download do |opt|
630
+ # description 'Downloads a content from a server'
631
+ #
632
+ # opt.on :verbose, 'Use verbose output'
633
+ #
634
+ # run do |options, arguments|
635
+ # ContentDownloader.download(options, arguments)
636
+ # end
637
+ # end
638
+ # end
639
+ #
640
+ # @example Define the invokation block anywhere you want
641
+ # def subcommands(cmd)
642
+ # cmd.command :download do |opt|
643
+ # description 'Downloads a content from a server'
644
+ #
645
+ # opt.on :verbose, 'Use verbose output'
646
+ # end
647
+ # end
648
+ #
649
+ # def process
650
+ # # Perform calculations...
651
+ # opts.fetch_command(:download).run do |options, arguments|
652
+ # ContentDownloader.download(options, arguments)
653
+ # end
654
+ # # More calculations...
655
+ # end
656
+ def subcommands(cmd); end
657
+
658
+ # A method to setup Slop so it can parse the options your command expects.
503
659
  #
504
- # NOTE: please don't do anything side-effecty in the main part of this method,
505
- # as it may be called by Pry at any time for introspection reasons. If you need
506
- # to set up default values, use `setup` instead.
660
+ # @note Please don't do anything side-effecty in the main part of this
661
+ # method, as it may be called by Pry at any time for introspection reasons.
662
+ # If you need to set up default values, use `setup` instead.
507
663
  #
508
664
  # @example
509
665
  # def options(opt)
@@ -10,19 +10,15 @@ class Pry
10
10
  class CommandSet
11
11
  include Enumerable
12
12
  include Pry::Helpers::BaseHelpers
13
-
14
- attr_reader :commands
15
13
  attr_reader :helper_module
16
14
 
17
- # @param [Array<CommandSet>] imported_sets Sets which will be imported
18
- # automatically
15
+ # @param [Array<Commandset>] imported_sets
16
+ # Sets which will be imported automatically
19
17
  # @yield Optional block run to define commands
20
18
  def initialize(*imported_sets, &block)
21
19
  @commands = {}
22
20
  @helper_module = Module.new
23
-
24
21
  import(*imported_sets)
25
-
26
22
  instance_eval(&block) if block
27
23
  end
28
24
 
@@ -81,9 +77,9 @@ class Pry
81
77
  # # number-N regex command
82
78
  def block_command(match, description="No description.", options={}, &block)
83
79
  description, options = ["No description.", description] if description.is_a?(Hash)
84
- options = default_options(match).merge!(options)
80
+ options = Pry::Command.default_options(match).merge!(options)
85
81
 
86
- commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block)
82
+ @commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block)
87
83
  end
88
84
  alias_method :command, :block_command
89
85
 
@@ -113,11 +109,11 @@ class Pry
113
109
  #
114
110
  def create_command(match, description="No description.", options={}, &block)
115
111
  description, options = ["No description.", description] if description.is_a?(Hash)
116
- options = default_options(match).merge!(options)
112
+ options = Pry::Command.default_options(match).merge!(options)
117
113
 
118
- commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block)
119
- commands[match].class_eval(&block)
120
- commands[match]
114
+ @commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block)
115
+ @commands[match].class_eval(&block)
116
+ @commands[match]
121
117
  end
122
118
 
123
119
  # Execute a block of code before a command is invoked. The block also
@@ -126,7 +122,7 @@ class Pry
126
122
  # @param [String, Regexp] search The match or listing of the command.
127
123
  # @yield The block to be run before the command.
128
124
  # @example Display parameter before invoking command
129
- # Pry.commands.before_command("whereami") do |n|
125
+ # Pry.config.commands.before_command("whereami") do |n|
130
126
  # output.puts "parameter passed was #{n}"
131
127
  # end
132
128
  def before_command(search, &block)
@@ -140,7 +136,7 @@ class Pry
140
136
  # @param [String, Regexp] search The match or listing of the command.
141
137
  # @yield The block to be run after the command.
142
138
  # @example Display text 'command complete' after invoking command
143
- # Pry.commands.after_command("whereami") do |n|
139
+ # Pry.config.commands.after_command("whereami") do |n|
144
140
  # output.puts "command complete!"
145
141
  # end
146
142
  def after_command(search, &block)
@@ -148,22 +144,16 @@ class Pry
148
144
  cmd.hooks[:after] << block
149
145
  end
150
146
 
151
- def each &block
147
+ def each(&block)
152
148
  @commands.each(&block)
153
149
  end
154
150
 
155
- # Add a given command object to this set.
156
- # @param [Command] command The subclass of Pry::Command you wish to add.
157
- def add_command(command)
158
- commands[command.match] = command
159
- end
160
-
161
151
  # Removes some commands from the set
162
152
  # @param [Array<String>] searches the matches or listings of the commands to remove
163
153
  def delete(*searches)
164
154
  searches.each do |search|
165
155
  cmd = find_command_by_match_or_listing(search)
166
- commands.delete cmd.match
156
+ @commands.delete cmd.match
167
157
  end
168
158
  end
169
159
 
@@ -173,7 +163,7 @@ class Pry
173
163
  # @return [Pry::CommandSet] Returns the reciever (a command set).
174
164
  def import(*sets)
175
165
  sets.each do |set|
176
- commands.merge! set.commands
166
+ @commands.merge! set.to_hash
177
167
  helper_module.send :include, set.helper_module
178
168
  end
179
169
  self
@@ -187,7 +177,7 @@ class Pry
187
177
  helper_module.send :include, set.helper_module
188
178
  matches.each do |match|
189
179
  cmd = set.find_command_by_match_or_listing(match)
190
- commands[cmd.match] = cmd
180
+ @commands[cmd.match] = cmd
191
181
  end
192
182
  self
193
183
  end
@@ -196,16 +186,10 @@ class Pry
196
186
  # of the command to retrieve.
197
187
  # @return [Command] The command object matched.
198
188
  def find_command_by_match_or_listing(match_or_listing)
199
- if commands[match_or_listing]
200
- cmd = commands[match_or_listing]
201
- else
202
- _, cmd = commands.find { |match, command| command.options[:listing] == match_or_listing }
203
- end
204
-
205
- raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!" if !cmd
206
- cmd
189
+ cmd = (@commands[match_or_listing] ||
190
+ Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands))
191
+ cmd or raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!"
207
192
  end
208
- protected :find_command_by_match_or_listing
209
193
 
210
194
  # Aliases a command
211
195
  # @param [String, Regex] match The match of the alias (can be a regex).
@@ -219,7 +203,8 @@ class Pry
219
203
  # @example Pass explicit description (overriding default).
220
204
  # Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie"
221
205
  def alias_command(match, action, options={})
222
- original_options = find_command(action).options.dup
206
+ cmd = find_command(action) or fail "Command: `#{action}` not found"
207
+ original_options = cmd.options.dup
223
208
 
224
209
  options = original_options.merge!({
225
210
  :desc => "Alias for `#{action}`",
@@ -233,6 +218,12 @@ class Pry
233
218
  run action, *args
234
219
  end
235
220
 
221
+ c.class_eval do
222
+ define_method(:complete) do |input|
223
+ cmd.new(context).complete(input)
224
+ end
225
+ end
226
+
236
227
  c.group "Aliases"
237
228
 
238
229
  c
@@ -255,11 +246,22 @@ class Pry
255
246
  :description => cmd.description
256
247
  }.merge!(options)
257
248
 
258
- commands[new_match] = cmd.dup
259
- commands[new_match].match = new_match
260
- commands[new_match].description = options.delete(:description)
261
- commands[new_match].options.merge!(options)
262
- commands.delete(cmd.match)
249
+ @commands[new_match] = cmd.dup
250
+ @commands[new_match].match = new_match
251
+ @commands[new_match].description = options.delete(:description)
252
+ @commands[new_match].options.merge!(options)
253
+ @commands.delete(cmd.match)
254
+ end
255
+
256
+ def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command)
257
+ create_command name_of_disabled_command do
258
+ match matcher
259
+ description ""
260
+
261
+ define_method(:process) do
262
+ output.puts "DISABLED: #{message}"
263
+ end
264
+ end
263
265
  end
264
266
 
265
267
  # Sets or gets the description for a command (replacing the old
@@ -297,18 +299,71 @@ class Pry
297
299
  end
298
300
 
299
301
 
300
- # @return [Array] The list of commands provided by the command set.
302
+ # @return [Array]
303
+ # The list of commands provided by the command set.
301
304
  def list_commands
302
- commands.keys
305
+ @commands.keys
303
306
  end
307
+ alias_method :keys, :list_commands
308
+
309
+ def to_hash
310
+ @commands.dup
311
+ end
312
+ alias_method :to_h, :to_hash
304
313
 
305
314
  # Find a command that matches the given line
306
- # @param [String] val The line that might be a command invocation
315
+ # @param [String] pattern The line that might be a command invocation
307
316
  # @return [Pry::Command, nil]
308
- def find_command(val)
309
- commands.values.select{ |c| c.matches?(val) }.sort_by{ |c| c.match_score(val) }.last
317
+ def [](pattern)
318
+ @commands.values.select do |command|
319
+ command.matches?(pattern)
320
+ end.sort_by do |command|
321
+ command.match_score(pattern)
322
+ end.last
323
+ end
324
+ alias_method :find_command, :[]
325
+
326
+ #
327
+ # Re-assign the command found at _pattern_ with _command_.
328
+ #
329
+ # @param [Regexp, String] pattern
330
+ # The command to add or replace(found at _pattern_).
331
+ #
332
+ # @param [Pry::Command] command
333
+ # The command to add.
334
+ #
335
+ # @return [Pry::Command]
336
+ # Returns the new command (matched with "pattern".)
337
+ #
338
+ # @example
339
+ # Pry.config.commands["help"] = MyHelpCommand
340
+ #
341
+ def []=(pattern, command)
342
+ if command.equal?(nil)
343
+ return @commands.delete(pattern)
344
+ end
345
+ unless Class === command && command < Pry::Command
346
+ raise TypeError, "command is not a subclass of Pry::Command"
347
+ end
348
+ bind_command_to_pattern = pattern != command.match
349
+ if bind_command_to_pattern
350
+ command_copy = command.dup
351
+ command_copy.match = pattern
352
+ @commands[pattern] = command_copy
353
+ else
354
+ @commands[pattern] = command
355
+ end
356
+ end
357
+
358
+ #
359
+ # Add a command to set.
360
+ #
361
+ # @param [Command] command
362
+ # a subclass of Pry::Command.
363
+ #
364
+ def add_command(command)
365
+ self[command.match] = command
310
366
  end
311
- alias_method :[], :find_command
312
367
 
313
368
  # Find the command that the user might be trying to refer to.
314
369
  # @param [String] search The user's search.
@@ -344,23 +399,22 @@ class Pry
344
399
 
345
400
  # @private (used for testing)
346
401
  def run_command(context, match, *args)
347
- command = commands[match] or raise NoCommandError.new(match, self)
402
+ command = @commands[match] or raise NoCommandError.new(match, self)
348
403
  command.new(context).call_safely(*args)
349
404
  end
350
405
 
351
- private
352
-
353
- def default_options(match)
354
- {
355
- :requires_gem => [],
356
- :keep_retval => false,
357
- :argument_required => false,
358
- :interpolate => true,
359
- :shellwords => true,
360
- :listing => (String === match ? match : match.inspect),
361
- :use_prefix => true,
362
- :takes_block => false
363
- }
406
+ # Generate completions for the user's search.
407
+ # @param [String] search The line to search for
408
+ # @param [Hash] context The context to create the command with
409
+ # @return [Array<String>]
410
+ def complete(search, context={})
411
+ if command = find_command(search)
412
+ command.new(context).complete(search)
413
+ else
414
+ @commands.keys.select do |key|
415
+ String === key && key.start_with?(search)
416
+ end.map{ |key| key + " " }
417
+ end
364
418
  end
365
419
  end
366
420