pry 0.9.10pre1-i386-mingw32 → 0.9.11-i386-mingw32

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 (194) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG +63 -2
  3. data/CONTRIBUTORS +43 -25
  4. data/Gemfile +7 -0
  5. data/Guardfile +62 -0
  6. data/README.markdown +4 -4
  7. data/Rakefile +34 -35
  8. data/lib/pry.rb +107 -54
  9. data/lib/pry/cli.rb +34 -11
  10. data/lib/pry/code.rb +165 -182
  11. data/lib/pry/code/code_range.rb +70 -0
  12. data/lib/pry/code/loc.rb +92 -0
  13. data/lib/pry/code_object.rb +153 -0
  14. data/lib/pry/command.rb +160 -22
  15. data/lib/pry/command_set.rb +37 -26
  16. data/lib/pry/commands.rb +4 -27
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +53 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +78 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +84 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +30 -0
  26. data/lib/pry/commands/code_collector.rb +165 -0
  27. data/lib/pry/commands/deprecated_commands.rb +2 -0
  28. data/lib/pry/commands/disable_pry.rb +27 -0
  29. data/lib/pry/commands/easter_eggs.rb +112 -0
  30. data/lib/pry/commands/edit.rb +206 -0
  31. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  32. data/lib/pry/commands/edit/file_and_line_locator.rb +38 -0
  33. data/lib/pry/commands/edit/method_patcher.rb +122 -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 +24 -0
  37. data/lib/pry/commands/find_method.rb +199 -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 +29 -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 +95 -0
  44. data/lib/pry/commands/help.rb +164 -0
  45. data/lib/pry/commands/hist.rb +161 -0
  46. data/lib/pry/commands/import_set.rb +22 -0
  47. data/lib/pry/commands/install_command.rb +51 -0
  48. data/lib/pry/commands/jump_to.rb +29 -0
  49. data/lib/pry/commands/ls.rb +339 -0
  50. data/lib/pry/commands/nesting.rb +25 -0
  51. data/lib/pry/commands/play.rb +69 -0
  52. data/lib/pry/commands/pry_backtrace.rb +26 -0
  53. data/lib/pry/commands/pry_version.rb +17 -0
  54. data/lib/pry/commands/raise_up.rb +32 -0
  55. data/lib/pry/commands/reload_code.rb +39 -0
  56. data/lib/pry/commands/reset.rb +18 -0
  57. data/lib/pry/commands/ri.rb +56 -0
  58. data/lib/pry/commands/save_file.rb +61 -0
  59. data/lib/pry/commands/shell_command.rb +43 -0
  60. data/lib/pry/commands/shell_mode.rb +27 -0
  61. data/lib/pry/commands/show_doc.rb +78 -0
  62. data/lib/pry/commands/show_info.rb +139 -0
  63. data/lib/pry/commands/show_input.rb +17 -0
  64. data/lib/pry/commands/show_source.rb +37 -0
  65. data/lib/pry/commands/simple_prompt.rb +22 -0
  66. data/lib/pry/commands/stat.rb +40 -0
  67. data/lib/pry/commands/switch_to.rb +23 -0
  68. data/lib/pry/commands/toggle_color.rb +20 -0
  69. data/lib/pry/commands/whereami.rb +114 -0
  70. data/lib/pry/commands/wtf.rb +57 -0
  71. data/lib/pry/completion.rb +120 -46
  72. data/lib/pry/config.rb +11 -0
  73. data/lib/pry/core_extensions.rb +30 -19
  74. data/lib/pry/editor.rb +129 -0
  75. data/lib/pry/helpers.rb +1 -0
  76. data/lib/pry/helpers/base_helpers.rb +89 -119
  77. data/lib/pry/helpers/command_helpers.rb +7 -122
  78. data/lib/pry/helpers/table.rb +100 -0
  79. data/lib/pry/helpers/text.rb +4 -4
  80. data/lib/pry/history_array.rb +5 -0
  81. data/lib/pry/hooks.rb +1 -3
  82. data/lib/pry/indent.rb +104 -30
  83. data/lib/pry/method.rb +66 -22
  84. data/lib/pry/module_candidate.rb +26 -15
  85. data/lib/pry/pager.rb +70 -0
  86. data/lib/pry/plugins.rb +1 -2
  87. data/lib/pry/pry_class.rb +63 -22
  88. data/lib/pry/pry_instance.rb +58 -37
  89. data/lib/pry/rubygem.rb +74 -0
  90. data/lib/pry/terminal_info.rb +43 -0
  91. data/lib/pry/test/helper.rb +185 -0
  92. data/lib/pry/version.rb +1 -1
  93. data/lib/pry/wrapped_module.rb +58 -24
  94. data/pry.gemspec +21 -37
  95. data/{test/test_cli.rb → spec/cli_spec.rb} +0 -0
  96. data/spec/code_object_spec.rb +277 -0
  97. data/{test/test_code.rb → spec/code_spec.rb} +19 -1
  98. data/{test/test_command_helpers.rb → spec/command_helpers_spec.rb} +0 -0
  99. data/{test/test_command_integration.rb → spec/command_integration_spec.rb} +38 -46
  100. data/{test/test_command_set.rb → spec/command_set_spec.rb} +18 -1
  101. data/{test/test_command.rb → spec/command_spec.rb} +250 -149
  102. data/spec/commands/amend_line_spec.rb +247 -0
  103. data/spec/commands/bang_spec.rb +19 -0
  104. data/spec/commands/cat_spec.rb +164 -0
  105. data/spec/commands/cd_spec.rb +250 -0
  106. data/spec/commands/disable_pry_spec.rb +25 -0
  107. data/spec/commands/edit_spec.rb +727 -0
  108. data/spec/commands/exit_all_spec.rb +34 -0
  109. data/spec/commands/exit_program_spec.rb +19 -0
  110. data/spec/commands/exit_spec.rb +34 -0
  111. data/{test/test_default_commands/test_find_method.rb → spec/commands/find_method_spec.rb} +27 -7
  112. data/spec/commands/gem_list_spec.rb +26 -0
  113. data/spec/commands/gist_spec.rb +75 -0
  114. data/{test/test_default_commands/test_help.rb → spec/commands/help_spec.rb} +8 -9
  115. data/spec/commands/hist_spec.rb +181 -0
  116. data/spec/commands/jump_to_spec.rb +15 -0
  117. data/spec/commands/ls_spec.rb +177 -0
  118. data/spec/commands/play_spec.rb +140 -0
  119. data/spec/commands/raise_up_spec.rb +56 -0
  120. data/spec/commands/save_file_spec.rb +177 -0
  121. data/spec/commands/show_doc_spec.rb +378 -0
  122. data/spec/commands/show_input_spec.rb +17 -0
  123. data/spec/commands/show_source_spec.rb +597 -0
  124. data/spec/commands/whereami_spec.rb +154 -0
  125. data/spec/completion_spec.rb +233 -0
  126. data/spec/control_d_handler_spec.rb +58 -0
  127. data/spec/editor_spec.rb +79 -0
  128. data/{test/test_exception_whitelist.rb → spec/exception_whitelist_spec.rb} +0 -0
  129. data/{test → spec/fixtures}/candidate_helper1.rb +0 -0
  130. data/{test → spec/fixtures}/candidate_helper2.rb +0 -0
  131. data/{test/test_default_commands → spec/fixtures}/example.erb +0 -0
  132. data/spec/fixtures/example_nesting.rb +33 -0
  133. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  134. data/{test → spec/fixtures}/testrc +0 -0
  135. data/{test → spec/fixtures}/testrcbad +0 -0
  136. data/spec/helper.rb +34 -0
  137. data/spec/helpers/bacon.rb +86 -0
  138. data/spec/helpers/mock_pry.rb +43 -0
  139. data/spec/helpers/table_spec.rb +83 -0
  140. data/{test/test_history_array.rb → spec/history_array_spec.rb} +21 -19
  141. data/{test/test_hooks.rb → spec/hooks_spec.rb} +0 -0
  142. data/{test/test_indent.rb → spec/indent_spec.rb} +24 -0
  143. data/{test/test_input_stack.rb → spec/input_stack_spec.rb} +4 -0
  144. data/{test/test_method.rb → spec/method_spec.rb} +65 -1
  145. data/{test/test_prompt.rb → spec/prompt_spec.rb} +0 -0
  146. data/{test/test_pry_defaults.rb → spec/pry_defaults_spec.rb} +14 -14
  147. data/{test/test_pry_history.rb → spec/pry_history_spec.rb} +15 -0
  148. data/spec/pry_output_spec.rb +95 -0
  149. data/{test/test_pry.rb → spec/pry_spec.rb} +74 -32
  150. data/{test/test_sticky_locals.rb → spec/sticky_locals_spec.rb} +27 -25
  151. data/{test/test_syntax_checking.rb → spec/syntax_checking_spec.rb} +17 -1
  152. data/{test/test_wrapped_module.rb → spec/wrapped_module_spec.rb} +92 -5
  153. metadata +239 -115
  154. data/examples/example_basic.rb +0 -15
  155. data/examples/example_command_override.rb +0 -32
  156. data/examples/example_commands.rb +0 -36
  157. data/examples/example_hooks.rb +0 -9
  158. data/examples/example_image_edit.rb +0 -67
  159. data/examples/example_input.rb +0 -7
  160. data/examples/example_input2.rb +0 -29
  161. data/examples/example_output.rb +0 -11
  162. data/examples/example_print.rb +0 -6
  163. data/examples/example_prompt.rb +0 -9
  164. data/examples/helper.rb +0 -6
  165. data/lib/pry/default_commands/cd.rb +0 -81
  166. data/lib/pry/default_commands/commands.rb +0 -62
  167. data/lib/pry/default_commands/context.rb +0 -98
  168. data/lib/pry/default_commands/easter_eggs.rb +0 -95
  169. data/lib/pry/default_commands/editing.rb +0 -420
  170. data/lib/pry/default_commands/find_method.rb +0 -169
  171. data/lib/pry/default_commands/gems.rb +0 -84
  172. data/lib/pry/default_commands/gist.rb +0 -187
  173. data/lib/pry/default_commands/help.rb +0 -127
  174. data/lib/pry/default_commands/hist.rb +0 -120
  175. data/lib/pry/default_commands/input_and_output.rb +0 -306
  176. data/lib/pry/default_commands/introspection.rb +0 -410
  177. data/lib/pry/default_commands/ls.rb +0 -272
  178. data/lib/pry/default_commands/misc.rb +0 -38
  179. data/lib/pry/default_commands/navigating_pry.rb +0 -110
  180. data/lib/pry/default_commands/whereami.rb +0 -92
  181. data/lib/pry/extended_commands/experimental.rb +0 -7
  182. data/test/helper.rb +0 -223
  183. data/test/test_completion.rb +0 -62
  184. data/test/test_control_d_handler.rb +0 -45
  185. data/test/test_default_commands/test_cd.rb +0 -321
  186. data/test/test_default_commands/test_context.rb +0 -288
  187. data/test/test_default_commands/test_documentation.rb +0 -315
  188. data/test/test_default_commands/test_gems.rb +0 -18
  189. data/test/test_default_commands/test_input.rb +0 -428
  190. data/test/test_default_commands/test_introspection.rb +0 -511
  191. data/test/test_default_commands/test_ls.rb +0 -151
  192. data/test/test_default_commands/test_shell.rb +0 -343
  193. data/test/test_default_commands/test_show_source.rb +0 -432
  194. data/test/test_pry_output.rb +0 -41
@@ -0,0 +1,70 @@
1
+ class Pry
2
+ class Code
3
+
4
+ # Represents a range of lines in a code listing.
5
+ #
6
+ # @api private
7
+ class CodeRange
8
+
9
+ # @param [Integer] start_line
10
+ # @param [Integer?] end_line
11
+ def initialize(start_line, end_line = nil)
12
+ @start_line = start_line
13
+ @end_line = end_line
14
+ force_set_end_line
15
+ end
16
+
17
+ # @param [Array<LOC>] lines
18
+ # @return [Range]
19
+ def indices_range(lines)
20
+ Range.new(*indices(lines))
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :start_line, :end_line
26
+
27
+ # If `end_line` is equal to `nil`, then calculate it from the first
28
+ # parameter, `start_line`. Otherwise, leave it as it is.
29
+ # @return [void]
30
+ def force_set_end_line
31
+ if start_line.is_a?(Range)
32
+ set_end_line_from_range
33
+ else
34
+ @end_line ||= start_line
35
+ end
36
+ end
37
+
38
+ # Finds indices of `start_line` and `end_line` in the given Array of
39
+ # +lines+.
40
+ #
41
+ # @param [Array<LOC>] lines
42
+ # @return [Array<Integer>]
43
+ def indices(lines)
44
+ [find_start_index(lines), find_end_index(lines)]
45
+ end
46
+
47
+ # @return [Integer]
48
+ def find_start_index(lines)
49
+ return start_line if start_line < 0
50
+ lines.index { |loc| loc.lineno >= start_line } || lines.length
51
+ end
52
+
53
+ # @return [Integer]
54
+ def find_end_index(lines)
55
+ return end_line if end_line < 0
56
+ (lines.index { |loc| loc.lineno > end_line } || 0) - 1
57
+ end
58
+
59
+ # For example, if the range is 4..10, then `start_line` would be equal to
60
+ # 4 and `end_line` to 10.
61
+ # @return [void]
62
+ def set_end_line_from_range
63
+ @end_line = start_line.last
64
+ @end_line -= 1 if start_line.exclude_end?
65
+ @start_line = start_line.first
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,92 @@
1
+ class Pry
2
+ class Code
3
+
4
+ # Represents a line of code. A line of code is a tuple, which consists of a
5
+ # line and a line number. A `LOC` object's state (namely, the line
6
+ # parameter) can be changed via instance methods. `Pry::Code` heavily uses
7
+ # this class.
8
+ #
9
+ # @api private
10
+ # @example
11
+ # loc = LOC.new("def example\n :example\nend", 1)
12
+ # puts loc.line
13
+ # def example
14
+ # :example
15
+ # end
16
+ # #=> nil
17
+ #
18
+ # loc.indent(3)
19
+ # loc.line #=> " def example\n :example\nend"
20
+ class LOC
21
+
22
+ # @return [Array<String, Integer>]
23
+ attr_reader :tuple
24
+
25
+ # @param [String] line The line of code.
26
+ # @param [Integer] lineno The position of the +line+.
27
+ def initialize(line, lineno)
28
+ @tuple = [line.chomp, lineno.to_i]
29
+ end
30
+
31
+ # @return [Boolean]
32
+ def ==(other)
33
+ other.tuple == tuple
34
+ end
35
+
36
+ def dup
37
+ self.class.new(line, lineno)
38
+ end
39
+
40
+ # @return [String]
41
+ def line
42
+ tuple.first
43
+ end
44
+
45
+ # @return [Integer]
46
+ def lineno
47
+ tuple.last
48
+ end
49
+
50
+ # Paints the `line` of code.
51
+ #
52
+ # @param [Symbol] code_type
53
+ # @return [void]
54
+ def colorize(code_type)
55
+ tuple[0] = CodeRay.scan(line, code_type).term
56
+ end
57
+
58
+ # Prepends the line number `lineno` to the `line`.
59
+ #
60
+ # @param [Integer] max_width
61
+ # @return [void]
62
+ def add_line_number(max_width = 0)
63
+ padded = lineno.to_s.rjust(max_width)
64
+ colorized_lineno = Pry::Helpers::BaseHelpers.colorize_code(padded)
65
+ tuple[0] = "#{ colorized_lineno }: #{ line }"
66
+ end
67
+
68
+ # Prepends a marker "=>" or an empty marker to the +line+.
69
+ #
70
+ # @param [Integer] marker_lineno If it is equal to the `lineno`, then
71
+ # prepend a hashrocket. Otherwise, an empty marker.
72
+ # @return [void]
73
+ def add_marker(marker_lineno)
74
+ tuple[0] =
75
+ if lineno == marker_lineno
76
+ " => #{ line }"
77
+ else
78
+ " #{ line }"
79
+ end
80
+ end
81
+
82
+ # Indents the `line` with +distance+ spaces.
83
+ #
84
+ # @param [Integer] distance
85
+ # @return [void]
86
+ def indent(distance)
87
+ tuple[0] = "#{ ' ' * distance }#{ line }"
88
+ end
89
+ end
90
+
91
+ end
92
+ end
@@ -0,0 +1,153 @@
1
+ class Pry
2
+ class CodeObject
3
+ module Helpers
4
+ # we need this helper as some Pry::Method objects can wrap Procs
5
+ # @return [Boolean]
6
+ def real_method_object?
7
+ is_a?(::Method) || is_a?(::UnboundMethod)
8
+ end
9
+
10
+ def c_method?
11
+ real_method_object? && source_type == :c
12
+ end
13
+
14
+ def module_with_yard_docs?
15
+ is_a?(WrappedModule) && yard_docs?
16
+ end
17
+
18
+ def command?
19
+ is_a?(Module) && self <= Pry::Command
20
+ end
21
+ end
22
+
23
+ include Pry::Helpers::CommandHelpers
24
+
25
+ class << self
26
+ def lookup(str, _pry_, options={})
27
+ co = new(str, _pry_, options)
28
+
29
+ co.default_lookup || co.method_or_class_lookup ||
30
+ co.command_lookup || co.empty_lookup
31
+ end
32
+ end
33
+
34
+ attr_accessor :str
35
+ attr_accessor :target
36
+ attr_accessor :pry
37
+ attr_accessor :super_level
38
+
39
+ def initialize(str, _pry_, options={})
40
+ options = {
41
+ :super => 0,
42
+ }.merge!(options)
43
+
44
+ @str = str
45
+ @pry = _pry_
46
+ @target = _pry_.current_context
47
+ @super_level = options[:super]
48
+ end
49
+
50
+ def command_lookup
51
+ # TODO: just make it so find_command_by_match_or_listing doesn't
52
+ # raise?
53
+ pry.commands.find_command_by_match_or_listing(str) rescue nil
54
+ end
55
+
56
+ def empty_lookup
57
+ return nil if str && !str.empty?
58
+
59
+ if internal_binding?(target)
60
+ mod = target_self.is_a?(Module) ? target_self : target_self.class
61
+ Pry::WrappedModule(mod)
62
+ else
63
+ Pry::Method.from_binding(target)
64
+ end
65
+ end
66
+
67
+ # lookup variables and constants and `self` that are not modules
68
+ def default_lookup
69
+
70
+ # we skip instance methods as we want those to fall through to method_or_class_lookup()
71
+ if safe_to_evaluate?(str) && !looks_like_an_instance_method?(str)
72
+ obj = target.eval(str)
73
+
74
+ # restrict to only objects we KNOW for sure support the full API
75
+ # Do NOT support just any object that responds to source_location
76
+ if sourcable_object?(obj)
77
+ Pry::Method(obj)
78
+ elsif !obj.is_a?(Module)
79
+ Pry::WrappedModule(obj.class)
80
+ else
81
+ nil
82
+ end
83
+ end
84
+
85
+ rescue Pry::RescuableException
86
+ nil
87
+ end
88
+
89
+ def method_or_class_lookup
90
+ # we need this here because stupid Pry::Method.from_str() does a
91
+ # Pry::Method.from_binding when str is nil.
92
+ # Once we refactor Pry::Method.from_str() so it doesnt lookup
93
+ # from bindings, we can get rid of this check
94
+ return nil if str.to_s.empty?
95
+
96
+ obj = if str =~ /::(?:\S+)\Z/
97
+ Pry::WrappedModule.from_str(str,target) || Pry::Method.from_str(str, target)
98
+ else
99
+ Pry::Method.from_str(str,target) || Pry::WrappedModule.from_str(str, target)
100
+ end
101
+
102
+ lookup_super(obj, super_level)
103
+ end
104
+
105
+ private
106
+
107
+ def sourcable_object?(obj)
108
+ [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) }
109
+ end
110
+
111
+
112
+ # Returns true if `str` looks like a method, i.e Klass#method
113
+ # We need to consider this case because method lookups should fall
114
+ # through to the `method_or_class_lookup()` method but a
115
+ # defined?() on a "Klass#method` string will see the `#` as a
116
+ # comment and only evaluate the `Klass` part.
117
+ # @param [String] str
118
+ # @return [Boolean] Whether the string looks like an instance method.
119
+ def looks_like_an_instance_method?(str)
120
+ str =~ /\S#\S/
121
+ end
122
+
123
+ # We use this method to decide whether code is safe to eval. Method's are
124
+ # generally not, but everything else is.
125
+ # TODO: is just checking != "method" enough??
126
+ # TODO: see duplication of this method in Pry::WrappedModule
127
+ # @param [String] str The string to lookup
128
+ # @return [Boolean]
129
+ def safe_to_evaluate?(str)
130
+ return true if str.strip == "self"
131
+ kind = target.eval("defined?(#{str})")
132
+ kind =~ /variable|constant/
133
+ end
134
+
135
+ def target_self
136
+ target.eval('self')
137
+ end
138
+
139
+ # grab the nth (`super_level`) super of `obj
140
+ # @param [Object] obj
141
+ # @param [Fixnum] super_level How far up the super chain to ascend.
142
+ def lookup_super(obj, super_level)
143
+ return nil if !obj
144
+
145
+ sup = obj.super(super_level)
146
+ if !sup
147
+ raise Pry::CommandError, "No superclass found for #{obj.wrapped}"
148
+ else
149
+ sup
150
+ end
151
+ end
152
+ end
153
+ end
@@ -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,7 +25,11 @@ class Pry
20
25
  attr_writer :match
21
26
 
22
27
  def match(arg=nil)
23
- @match = arg if arg
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
24
33
  @match
25
34
  end
26
35
 
@@ -32,7 +41,7 @@ class Pry
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`
@@ -209,7 +261,6 @@ class Pry
209
261
  include Pry::Helpers::BaseHelpers
210
262
  include Pry::Helpers::CommandHelpers
211
263
 
212
-
213
264
  # Instantiate a command, in preparation for calling it.
214
265
  # @param [Hash] context The runtime context to use with this command.
215
266
  def initialize(context={})
@@ -256,7 +307,7 @@ class Pry
256
307
  collision_type ||= 'local-variable' if arg_string.match(%r{\A\s*[-+*/%&|^]*=})
257
308
 
258
309
  if collision_type
259
- output.puts "#{Pry::Helpers::Text.bold('WARNING:')} Calling Pry command '#{command_match}'," +
310
+ output.puts "#{text.bold('WARNING:')} Calling Pry command '#{command_match}'," +
260
311
  "which conflicts with a #{collision_type}.\n\n"
261
312
  end
262
313
  rescue Pry::RescuableException
@@ -325,7 +376,10 @@ class Pry
325
376
  # Note that if we find the '| do' or '| {' we delete this and the
326
377
  # elements following it from `arg_string`.
327
378
  def pass_block(arg_string)
328
- block_index = arg_string.rindex(/\| *(?:do|\{)/)
379
+ # Workaround for weird JRuby bug where rindex in this case can return nil
380
+ # even when there's a match.
381
+ arg_string.scan(/\| *(?:do|\{)/)
382
+ block_index = $~ && $~.offset(0)[0]
329
383
 
330
384
  return if !block_index
331
385
 
@@ -358,8 +412,8 @@ class Pry
358
412
  def call_safely(*args)
359
413
  unless dependencies_met?
360
414
  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(", "))}"
415
+ gems_not_installed = gems_needed.select { |g| !Rubygem.installed?(g) }
416
+ output.puts "\nThe command '#{command_name}' is #{text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}"
363
417
  output.puts "-"
364
418
  output.puts "Type `install-command #{command_name}` to install the required gems and activate this command."
365
419
  return void
@@ -380,6 +434,12 @@ class Pry
380
434
  @dependencies_met ||= command_dependencies_met?(command_options)
381
435
  end
382
436
 
437
+ # Generate completions for this command
438
+ #
439
+ # @param [String] search The line typed so far
440
+ # @return [Array<String>] Completion words
441
+ def complete(search); Bond::DefaultMission.completions; end
442
+
383
443
  private
384
444
 
385
445
  # Run the `#call` method and all the registered hooks.
@@ -437,7 +497,7 @@ class Pry
437
497
  end
438
498
  end
439
499
 
440
- # A super-class ofr Commands with structure.
500
+ # A super-class of Commands with structure.
441
501
  #
442
502
  # This class implements the bare-minimum functionality that a command should
443
503
  # have, namely a --help switch, and then delegates actual processing to its
@@ -449,13 +509,45 @@ class Pry
449
509
  # `setup` which will be called before `options`, for example to require any
450
510
  # gems your command needs to run, or to set up state.
451
511
  class ClassCommand < Command
512
+ class << self
513
+
514
+ # Ensure that subclasses inherit the options, description and
515
+ # match from a ClassCommand super class.
516
+ def inherited(klass)
517
+ klass.match match
518
+ klass.description description
519
+ klass.command_options options
520
+ end
521
+
522
+ def source
523
+ Pry::WrappedModule(self).source
524
+ end
525
+
526
+ def doc
527
+ new.help
528
+ end
529
+
530
+ def source_location
531
+ Pry::WrappedModule(self).source_location
532
+ end
533
+
534
+ def source_file
535
+ Pry::WrappedModule(self).source_file
536
+ end
537
+ alias_method :file, :source_file
538
+
539
+ def source_line
540
+ Pry::WrappedModule(self).source_line
541
+ end
542
+ alias_method :line, :source_line
543
+ end
452
544
 
453
545
  attr_accessor :opts
454
546
  attr_accessor :args
455
547
 
456
548
  # Set up `opts` and `args`, and then call `process`.
457
549
  #
458
- # This function will display help if necessary.
550
+ # This method will display help if necessary.
459
551
  #
460
552
  # @param [Array<String>] args The arguments passed
461
553
  # @return [Object] The return value of `process` or VOID_VALUE
@@ -478,32 +570,78 @@ class Pry
478
570
  slop.help
479
571
  end
480
572
 
481
- # Return an instance of Slop that can parse the options that this command accepts.
573
+ # Return an instance of Slop::Commands that can parse either subcommands
574
+ # or the options that this command accepts.
482
575
  def slop
483
- Slop.new do |opt|
576
+ Slop.parse do |opt|
484
577
  opt.banner(unindent(self.class.banner))
578
+ subcommands(opt)
485
579
  options(opt)
486
- opt.on(:h, :help, "Show this message.")
580
+ opt.on :h, :help, 'Show this message.'
487
581
  end
488
582
  end
489
583
 
490
- # A function called just before `options(opt)` as part of `call`.
584
+ # Generate shell completions
585
+ # @param [String] search The line typed so far
586
+ # @return [Array<String>] the words to complete
587
+ def complete(search)
588
+ slop.map do |opt|
589
+ [opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"]
590
+ end.flatten(1).compact + super
591
+ end
592
+
593
+ # A method called just before `options(opt)` as part of `call`.
491
594
  #
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.
595
+ # This method can be used to set up any context your command needs to run,
596
+ # for example requiring gems, or setting default values for options.
494
597
  #
495
598
  # @example
496
- # def setup;
599
+ # def setup
497
600
  # require 'gist'
498
601
  # @action = :method
499
602
  # end
500
603
  def setup; end
501
604
 
502
- # A function to setup Slop so it can parse the options your command expects.
605
+ # A method to setup Slop commands so it can parse the subcommands your
606
+ # command expects. If you need to set up default values, use `setup`
607
+ # instead.
608
+ #
609
+ # @example A minimal example
610
+ # def subcommands(cmd)
611
+ # cmd.command :download do |opt|
612
+ # description 'Downloads a content from a server'
613
+ #
614
+ # opt.on :verbose, 'Use verbose output'
615
+ #
616
+ # run do |options, arguments|
617
+ # ContentDownloader.download(options, arguments)
618
+ # end
619
+ # end
620
+ # end
621
+ #
622
+ # @example Define the invokation block anywhere you want
623
+ # def subcommands(cmd)
624
+ # cmd.command :download do |opt|
625
+ # description 'Downloads a content from a server'
626
+ #
627
+ # opt.on :verbose, 'Use verbose output'
628
+ # end
629
+ # end
630
+ #
631
+ # def process
632
+ # # Perform calculations...
633
+ # opts.fetch_command(:download).run do |options, arguments|
634
+ # ContentDownloader.download(options, arguments)
635
+ # end
636
+ # # More calculations...
637
+ # end
638
+ def subcommands(cmd); end
639
+
640
+ # A method to setup Slop so it can parse the options your command expects.
503
641
  #
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.
642
+ # @note Please don't do anything side-effecty in the main part of this
643
+ # method, as it may be called by Pry at any time for introspection reasons.
644
+ # If you need to set up default values, use `setup` instead.
507
645
  #
508
646
  # @example
509
647
  # def options(opt)