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.
- data/.travis.yml +3 -1
- data/CHANGELOG +63 -2
- data/CONTRIBUTORS +43 -25
- data/Gemfile +7 -0
- data/Guardfile +62 -0
- data/README.markdown +4 -4
- data/Rakefile +34 -35
- data/lib/pry.rb +107 -54
- data/lib/pry/cli.rb +34 -11
- data/lib/pry/code.rb +165 -182
- data/lib/pry/code/code_range.rb +70 -0
- data/lib/pry/code/loc.rb +92 -0
- data/lib/pry/code_object.rb +153 -0
- data/lib/pry/command.rb +160 -22
- data/lib/pry/command_set.rb +37 -26
- data/lib/pry/commands.rb +4 -27
- data/lib/pry/commands/amend_line.rb +99 -0
- data/lib/pry/commands/bang.rb +20 -0
- data/lib/pry/commands/bang_pry.rb +17 -0
- data/lib/pry/commands/cat.rb +53 -0
- data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
- data/lib/pry/commands/cat/exception_formatter.rb +78 -0
- data/lib/pry/commands/cat/file_formatter.rb +84 -0
- data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
- data/lib/pry/commands/cd.rb +30 -0
- data/lib/pry/commands/code_collector.rb +165 -0
- data/lib/pry/commands/deprecated_commands.rb +2 -0
- data/lib/pry/commands/disable_pry.rb +27 -0
- data/lib/pry/commands/easter_eggs.rb +112 -0
- data/lib/pry/commands/edit.rb +206 -0
- data/lib/pry/commands/edit/exception_patcher.rb +25 -0
- data/lib/pry/commands/edit/file_and_line_locator.rb +38 -0
- data/lib/pry/commands/edit/method_patcher.rb +122 -0
- data/lib/pry/commands/exit.rb +42 -0
- data/lib/pry/commands/exit_all.rb +29 -0
- data/lib/pry/commands/exit_program.rb +24 -0
- data/lib/pry/commands/find_method.rb +199 -0
- data/lib/pry/commands/fix_indent.rb +19 -0
- data/lib/pry/commands/gem_cd.rb +26 -0
- data/lib/pry/commands/gem_install.rb +29 -0
- data/lib/pry/commands/gem_list.rb +33 -0
- data/lib/pry/commands/gem_open.rb +29 -0
- data/lib/pry/commands/gist.rb +95 -0
- data/lib/pry/commands/help.rb +164 -0
- data/lib/pry/commands/hist.rb +161 -0
- data/lib/pry/commands/import_set.rb +22 -0
- data/lib/pry/commands/install_command.rb +51 -0
- data/lib/pry/commands/jump_to.rb +29 -0
- data/lib/pry/commands/ls.rb +339 -0
- data/lib/pry/commands/nesting.rb +25 -0
- data/lib/pry/commands/play.rb +69 -0
- data/lib/pry/commands/pry_backtrace.rb +26 -0
- data/lib/pry/commands/pry_version.rb +17 -0
- data/lib/pry/commands/raise_up.rb +32 -0
- data/lib/pry/commands/reload_code.rb +39 -0
- data/lib/pry/commands/reset.rb +18 -0
- data/lib/pry/commands/ri.rb +56 -0
- data/lib/pry/commands/save_file.rb +61 -0
- data/lib/pry/commands/shell_command.rb +43 -0
- data/lib/pry/commands/shell_mode.rb +27 -0
- data/lib/pry/commands/show_doc.rb +78 -0
- data/lib/pry/commands/show_info.rb +139 -0
- data/lib/pry/commands/show_input.rb +17 -0
- data/lib/pry/commands/show_source.rb +37 -0
- data/lib/pry/commands/simple_prompt.rb +22 -0
- data/lib/pry/commands/stat.rb +40 -0
- data/lib/pry/commands/switch_to.rb +23 -0
- data/lib/pry/commands/toggle_color.rb +20 -0
- data/lib/pry/commands/whereami.rb +114 -0
- data/lib/pry/commands/wtf.rb +57 -0
- data/lib/pry/completion.rb +120 -46
- data/lib/pry/config.rb +11 -0
- data/lib/pry/core_extensions.rb +30 -19
- data/lib/pry/editor.rb +129 -0
- data/lib/pry/helpers.rb +1 -0
- data/lib/pry/helpers/base_helpers.rb +89 -119
- data/lib/pry/helpers/command_helpers.rb +7 -122
- data/lib/pry/helpers/table.rb +100 -0
- data/lib/pry/helpers/text.rb +4 -4
- data/lib/pry/history_array.rb +5 -0
- data/lib/pry/hooks.rb +1 -3
- data/lib/pry/indent.rb +104 -30
- data/lib/pry/method.rb +66 -22
- data/lib/pry/module_candidate.rb +26 -15
- data/lib/pry/pager.rb +70 -0
- data/lib/pry/plugins.rb +1 -2
- data/lib/pry/pry_class.rb +63 -22
- data/lib/pry/pry_instance.rb +58 -37
- data/lib/pry/rubygem.rb +74 -0
- data/lib/pry/terminal_info.rb +43 -0
- data/lib/pry/test/helper.rb +185 -0
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +58 -24
- data/pry.gemspec +21 -37
- data/{test/test_cli.rb → spec/cli_spec.rb} +0 -0
- data/spec/code_object_spec.rb +277 -0
- data/{test/test_code.rb → spec/code_spec.rb} +19 -1
- data/{test/test_command_helpers.rb → spec/command_helpers_spec.rb} +0 -0
- data/{test/test_command_integration.rb → spec/command_integration_spec.rb} +38 -46
- data/{test/test_command_set.rb → spec/command_set_spec.rb} +18 -1
- data/{test/test_command.rb → spec/command_spec.rb} +250 -149
- data/spec/commands/amend_line_spec.rb +247 -0
- data/spec/commands/bang_spec.rb +19 -0
- data/spec/commands/cat_spec.rb +164 -0
- data/spec/commands/cd_spec.rb +250 -0
- data/spec/commands/disable_pry_spec.rb +25 -0
- data/spec/commands/edit_spec.rb +727 -0
- data/spec/commands/exit_all_spec.rb +34 -0
- data/spec/commands/exit_program_spec.rb +19 -0
- data/spec/commands/exit_spec.rb +34 -0
- data/{test/test_default_commands/test_find_method.rb → spec/commands/find_method_spec.rb} +27 -7
- data/spec/commands/gem_list_spec.rb +26 -0
- data/spec/commands/gist_spec.rb +75 -0
- data/{test/test_default_commands/test_help.rb → spec/commands/help_spec.rb} +8 -9
- data/spec/commands/hist_spec.rb +181 -0
- data/spec/commands/jump_to_spec.rb +15 -0
- data/spec/commands/ls_spec.rb +177 -0
- data/spec/commands/play_spec.rb +140 -0
- data/spec/commands/raise_up_spec.rb +56 -0
- data/spec/commands/save_file_spec.rb +177 -0
- data/spec/commands/show_doc_spec.rb +378 -0
- data/spec/commands/show_input_spec.rb +17 -0
- data/spec/commands/show_source_spec.rb +597 -0
- data/spec/commands/whereami_spec.rb +154 -0
- data/spec/completion_spec.rb +233 -0
- data/spec/control_d_handler_spec.rb +58 -0
- data/spec/editor_spec.rb +79 -0
- data/{test/test_exception_whitelist.rb → spec/exception_whitelist_spec.rb} +0 -0
- data/{test → spec/fixtures}/candidate_helper1.rb +0 -0
- data/{test → spec/fixtures}/candidate_helper2.rb +0 -0
- data/{test/test_default_commands → spec/fixtures}/example.erb +0 -0
- data/spec/fixtures/example_nesting.rb +33 -0
- data/spec/fixtures/show_source_doc_examples.rb +15 -0
- data/{test → spec/fixtures}/testrc +0 -0
- data/{test → spec/fixtures}/testrcbad +0 -0
- data/spec/helper.rb +34 -0
- data/spec/helpers/bacon.rb +86 -0
- data/spec/helpers/mock_pry.rb +43 -0
- data/spec/helpers/table_spec.rb +83 -0
- data/{test/test_history_array.rb → spec/history_array_spec.rb} +21 -19
- data/{test/test_hooks.rb → spec/hooks_spec.rb} +0 -0
- data/{test/test_indent.rb → spec/indent_spec.rb} +24 -0
- data/{test/test_input_stack.rb → spec/input_stack_spec.rb} +4 -0
- data/{test/test_method.rb → spec/method_spec.rb} +65 -1
- data/{test/test_prompt.rb → spec/prompt_spec.rb} +0 -0
- data/{test/test_pry_defaults.rb → spec/pry_defaults_spec.rb} +14 -14
- data/{test/test_pry_history.rb → spec/pry_history_spec.rb} +15 -0
- data/spec/pry_output_spec.rb +95 -0
- data/{test/test_pry.rb → spec/pry_spec.rb} +74 -32
- data/{test/test_sticky_locals.rb → spec/sticky_locals_spec.rb} +27 -25
- data/{test/test_syntax_checking.rb → spec/syntax_checking_spec.rb} +17 -1
- data/{test/test_wrapped_module.rb → spec/wrapped_module_spec.rb} +92 -5
- metadata +239 -115
- data/examples/example_basic.rb +0 -15
- data/examples/example_command_override.rb +0 -32
- data/examples/example_commands.rb +0 -36
- data/examples/example_hooks.rb +0 -9
- data/examples/example_image_edit.rb +0 -67
- data/examples/example_input.rb +0 -7
- data/examples/example_input2.rb +0 -29
- data/examples/example_output.rb +0 -11
- data/examples/example_print.rb +0 -6
- data/examples/example_prompt.rb +0 -9
- data/examples/helper.rb +0 -6
- data/lib/pry/default_commands/cd.rb +0 -81
- data/lib/pry/default_commands/commands.rb +0 -62
- data/lib/pry/default_commands/context.rb +0 -98
- data/lib/pry/default_commands/easter_eggs.rb +0 -95
- data/lib/pry/default_commands/editing.rb +0 -420
- data/lib/pry/default_commands/find_method.rb +0 -169
- data/lib/pry/default_commands/gems.rb +0 -84
- data/lib/pry/default_commands/gist.rb +0 -187
- data/lib/pry/default_commands/help.rb +0 -127
- data/lib/pry/default_commands/hist.rb +0 -120
- data/lib/pry/default_commands/input_and_output.rb +0 -306
- data/lib/pry/default_commands/introspection.rb +0 -410
- data/lib/pry/default_commands/ls.rb +0 -272
- data/lib/pry/default_commands/misc.rb +0 -38
- data/lib/pry/default_commands/navigating_pry.rb +0 -110
- data/lib/pry/default_commands/whereami.rb +0 -92
- data/lib/pry/extended_commands/experimental.rb +0 -7
- data/test/helper.rb +0 -223
- data/test/test_completion.rb +0 -62
- data/test/test_control_d_handler.rb +0 -45
- data/test/test_default_commands/test_cd.rb +0 -321
- data/test/test_default_commands/test_context.rb +0 -288
- data/test/test_default_commands/test_documentation.rb +0 -315
- data/test/test_default_commands/test_gems.rb +0 -18
- data/test/test_default_commands/test_input.rb +0 -428
- data/test/test_default_commands/test_introspection.rb +0 -511
- data/test/test_default_commands/test_ls.rb +0 -151
- data/test/test_default_commands/test_shell.rb +0 -343
- data/test/test_default_commands/test_show_source.rb +0 -432
- 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
|
data/lib/pry/code/loc.rb
ADDED
@@ -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
|
data/lib/pry/command.rb
CHANGED
@@ -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
|
-
|
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)
|
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;
|
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 "#{
|
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
|
-
|
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| !
|
362
|
-
output.puts "\nThe command '#{command_name}' is #{
|
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
|
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
|
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
|
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.
|
576
|
+
Slop.parse do |opt|
|
484
577
|
opt.banner(unindent(self.class.banner))
|
578
|
+
subcommands(opt)
|
485
579
|
options(opt)
|
486
|
-
opt.on
|
580
|
+
opt.on :h, :help, 'Show this message.'
|
487
581
|
end
|
488
582
|
end
|
489
583
|
|
490
|
-
#
|
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
|
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
|
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
|
-
#
|
505
|
-
# as it may be called by Pry at any time for introspection reasons.
|
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)
|