pry 0.10.0.pre2-universal-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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +702 -0
- data/LICENSE +25 -0
- data/README.md +406 -0
- data/bin/pry +16 -0
- data/lib/pry.rb +161 -0
- data/lib/pry/cli.rb +220 -0
- data/lib/pry/code.rb +346 -0
- data/lib/pry/code/code_file.rb +103 -0
- data/lib/pry/code/code_range.rb +71 -0
- data/lib/pry/code/loc.rb +92 -0
- data/lib/pry/code_object.rb +172 -0
- data/lib/pry/color_printer.rb +55 -0
- data/lib/pry/command.rb +692 -0
- data/lib/pry/command_set.rb +443 -0
- data/lib/pry/commands.rb +6 -0
- 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 +62 -0
- data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
- data/lib/pry/commands/cat/exception_formatter.rb +77 -0
- data/lib/pry/commands/cat/file_formatter.rb +67 -0
- data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
- data/lib/pry/commands/cd.rb +41 -0
- data/lib/pry/commands/change_inspector.rb +27 -0
- data/lib/pry/commands/change_prompt.rb +26 -0
- data/lib/pry/commands/code_collector.rb +165 -0
- data/lib/pry/commands/disable_pry.rb +27 -0
- data/lib/pry/commands/disabled_commands.rb +2 -0
- data/lib/pry/commands/easter_eggs.rb +112 -0
- data/lib/pry/commands/edit.rb +195 -0
- data/lib/pry/commands/edit/exception_patcher.rb +25 -0
- data/lib/pry/commands/edit/file_and_line_locator.rb +36 -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 +23 -0
- data/lib/pry/commands/find_method.rb +193 -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 +32 -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 +101 -0
- data/lib/pry/commands/help.rb +164 -0
- data/lib/pry/commands/hist.rb +180 -0
- data/lib/pry/commands/import_set.rb +22 -0
- data/lib/pry/commands/install_command.rb +53 -0
- data/lib/pry/commands/jump_to.rb +29 -0
- data/lib/pry/commands/list_inspectors.rb +35 -0
- data/lib/pry/commands/list_prompts.rb +35 -0
- data/lib/pry/commands/ls.rb +114 -0
- data/lib/pry/commands/ls/constants.rb +47 -0
- data/lib/pry/commands/ls/formatter.rb +49 -0
- data/lib/pry/commands/ls/globals.rb +48 -0
- data/lib/pry/commands/ls/grep.rb +21 -0
- data/lib/pry/commands/ls/instance_vars.rb +39 -0
- data/lib/pry/commands/ls/interrogatable.rb +18 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
- data/lib/pry/commands/ls/local_names.rb +35 -0
- data/lib/pry/commands/ls/local_vars.rb +39 -0
- data/lib/pry/commands/ls/ls_entity.rb +70 -0
- data/lib/pry/commands/ls/methods.rb +57 -0
- data/lib/pry/commands/ls/methods_helper.rb +46 -0
- data/lib/pry/commands/ls/self_methods.rb +32 -0
- data/lib/pry/commands/nesting.rb +25 -0
- data/lib/pry/commands/play.rb +103 -0
- data/lib/pry/commands/pry_backtrace.rb +25 -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 +62 -0
- data/lib/pry/commands/reset.rb +18 -0
- data/lib/pry/commands/ri.rb +60 -0
- data/lib/pry/commands/save_file.rb +61 -0
- data/lib/pry/commands/shell_command.rb +48 -0
- data/lib/pry/commands/shell_mode.rb +25 -0
- data/lib/pry/commands/show_doc.rb +83 -0
- data/lib/pry/commands/show_info.rb +195 -0
- data/lib/pry/commands/show_input.rb +17 -0
- data/lib/pry/commands/show_source.rb +50 -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 +24 -0
- data/lib/pry/commands/watch_expression.rb +105 -0
- data/lib/pry/commands/watch_expression/expression.rb +38 -0
- data/lib/pry/commands/whereami.rb +190 -0
- data/lib/pry/commands/wtf.rb +57 -0
- data/lib/pry/config.rb +24 -0
- data/lib/pry/config/behavior.rb +139 -0
- data/lib/pry/config/convenience.rb +26 -0
- data/lib/pry/config/default.rb +165 -0
- data/lib/pry/core_extensions.rb +131 -0
- data/lib/pry/editor.rb +133 -0
- data/lib/pry/exceptions.rb +77 -0
- data/lib/pry/helpers.rb +5 -0
- data/lib/pry/helpers/base_helpers.rb +113 -0
- data/lib/pry/helpers/command_helpers.rb +156 -0
- data/lib/pry/helpers/documentation_helpers.rb +75 -0
- data/lib/pry/helpers/options_helpers.rb +27 -0
- data/lib/pry/helpers/table.rb +109 -0
- data/lib/pry/helpers/text.rb +107 -0
- data/lib/pry/history.rb +125 -0
- data/lib/pry/history_array.rb +121 -0
- data/lib/pry/hooks.rb +230 -0
- data/lib/pry/indent.rb +406 -0
- data/lib/pry/input_completer.rb +242 -0
- data/lib/pry/input_lock.rb +132 -0
- data/lib/pry/inspector.rb +27 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method.rb +546 -0
- data/lib/pry/method/disowned.rb +53 -0
- data/lib/pry/method/patcher.rb +125 -0
- data/lib/pry/method/weird_method_locator.rb +186 -0
- data/lib/pry/module_candidate.rb +136 -0
- data/lib/pry/object_path.rb +82 -0
- data/lib/pry/output.rb +50 -0
- data/lib/pry/pager.rb +234 -0
- data/lib/pry/plugins.rb +103 -0
- data/lib/pry/prompt.rb +26 -0
- data/lib/pry/pry_class.rb +375 -0
- data/lib/pry/pry_instance.rb +654 -0
- data/lib/pry/rbx_path.rb +22 -0
- data/lib/pry/repl.rb +202 -0
- data/lib/pry/repl_file_loader.rb +74 -0
- data/lib/pry/rubygem.rb +82 -0
- data/lib/pry/terminal.rb +79 -0
- data/lib/pry/test/helper.rb +170 -0
- data/lib/pry/version.rb +3 -0
- data/lib/pry/wrapped_module.rb +373 -0
- metadata +248 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
class Pry
|
2
|
+
class CodeFile
|
3
|
+
DEFAULT_EXT = '.rb'
|
4
|
+
|
5
|
+
# List of all supported languages.
|
6
|
+
# @return [Hash]
|
7
|
+
EXTENSIONS = {
|
8
|
+
%w(.py) => :python,
|
9
|
+
%w(.js) => :javascript,
|
10
|
+
%w(.css) => :css,
|
11
|
+
%w(.xml) => :xml,
|
12
|
+
%w(.php) => :php,
|
13
|
+
%w(.html) => :html,
|
14
|
+
%w(.diff) => :diff,
|
15
|
+
%w(.java) => :java,
|
16
|
+
%w(.json) => :json,
|
17
|
+
%w(.c .h) => :c,
|
18
|
+
%w(.rhtml) => :rhtml,
|
19
|
+
%w(.yaml .yml) => :yaml,
|
20
|
+
%w(.cpp .hpp .cc .h cxx) => :cpp,
|
21
|
+
%w(.rb .ru .irbrc .gemspec .pryrc) => :ruby,
|
22
|
+
}
|
23
|
+
|
24
|
+
# @return [Symbol] The type of code stored in this wrapper.
|
25
|
+
attr_reader :code_type
|
26
|
+
|
27
|
+
# @param [String] filename The name of a file with code to be detected
|
28
|
+
# @param [Symbol] code_type The type of code the `filename` contains
|
29
|
+
def initialize(filename, code_type = type_from_filename(filename))
|
30
|
+
@filename = filename
|
31
|
+
@code_type = code_type
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String] The code contained in the current `@filename`.
|
35
|
+
def code
|
36
|
+
if @filename == Pry.eval_path
|
37
|
+
Pry.line_buffer.drop(1)
|
38
|
+
elsif Pry::Method::Patcher.code_for(@filename)
|
39
|
+
Pry::Method::Patcher.code_for(@filename)
|
40
|
+
elsif RbxPath.is_core_path?(@filename)
|
41
|
+
File.read(RbxPath.convert_path_to_full(@filename))
|
42
|
+
else
|
43
|
+
path = abs_path
|
44
|
+
@code_type = type_from_filename(path)
|
45
|
+
File.read(path)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# @raise [MethodSource::SourceNotFoundError] if the `filename` is not
|
52
|
+
# readable for some reason.
|
53
|
+
# @return [String] absolute path for the given `filename`.
|
54
|
+
def abs_path
|
55
|
+
code_path.detect { |path| readable?(path) } or
|
56
|
+
raise MethodSource::SourceNotFoundError,
|
57
|
+
"Cannot open #{ @filename.inspect } for reading."
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param [String] path
|
61
|
+
# @return [Boolean] if the path, with or without the default ext,
|
62
|
+
# is a readable file then `true`, otherwise `false`.
|
63
|
+
def readable?(path)
|
64
|
+
File.readable?(path) && !File.directory?(path) or
|
65
|
+
File.readable?(path << DEFAULT_EXT)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Array] All the paths that contain code that Pry can use for its
|
69
|
+
# API's. Skips directories.
|
70
|
+
def code_path
|
71
|
+
[from_pwd, from_pry_init_pwd, *from_load_path]
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param [String] filename
|
75
|
+
# @param [Symbol] default (:unknown) the file type to assume if none could be
|
76
|
+
# detected.
|
77
|
+
# @return [Symbol, nil] The CodeRay type of a file from its extension, or
|
78
|
+
# `nil` if `:unknown`.
|
79
|
+
def type_from_filename(filename, default = :unknown)
|
80
|
+
_, @code_type = EXTENSIONS.find do |k, _|
|
81
|
+
k.any? { |ext| ext == File.extname(filename) }
|
82
|
+
end
|
83
|
+
|
84
|
+
code_type || default
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [String]
|
88
|
+
def from_pwd
|
89
|
+
File.expand_path(@filename, Dir.pwd)
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [String]
|
93
|
+
def from_pry_init_pwd
|
94
|
+
File.expand_path(@filename, Pry::INITIAL_PWD)
|
95
|
+
end
|
96
|
+
|
97
|
+
# @return [String]
|
98
|
+
def from_load_path
|
99
|
+
$LOAD_PATH.map { |path| File.expand_path(@filename, path) }
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,71 @@
|
|
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
|
+
def start_line; @start_line; end
|
26
|
+
def end_line; @end_line; end
|
27
|
+
|
28
|
+
# If `end_line` is equal to `nil`, then calculate it from the first
|
29
|
+
# parameter, `start_line`. Otherwise, leave it as it is.
|
30
|
+
# @return [void]
|
31
|
+
def force_set_end_line
|
32
|
+
if start_line.is_a?(Range)
|
33
|
+
set_end_line_from_range
|
34
|
+
else
|
35
|
+
@end_line ||= start_line
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Finds indices of `start_line` and `end_line` in the given Array of
|
40
|
+
# +lines+.
|
41
|
+
#
|
42
|
+
# @param [Array<LOC>] lines
|
43
|
+
# @return [Array<Integer>]
|
44
|
+
def indices(lines)
|
45
|
+
[find_start_index(lines), find_end_index(lines)]
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Integer]
|
49
|
+
def find_start_index(lines)
|
50
|
+
return start_line if start_line < 0
|
51
|
+
lines.index { |loc| loc.lineno >= start_line } || lines.length
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Integer]
|
55
|
+
def find_end_index(lines)
|
56
|
+
return end_line if end_line < 0
|
57
|
+
(lines.index { |loc| loc.lineno > end_line } || 0) - 1
|
58
|
+
end
|
59
|
+
|
60
|
+
# For example, if the range is 4..10, then `start_line` would be equal to
|
61
|
+
# 4 and `end_line` to 10.
|
62
|
+
# @return [void]
|
63
|
+
def set_end_line_from_range
|
64
|
+
@end_line = start_line.last
|
65
|
+
@end_line -= 1 if start_line.exclude_end?
|
66
|
+
@start_line = start_line.first
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
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, color = false)
|
63
|
+
padded = lineno.to_s.rjust(max_width)
|
64
|
+
colorized_lineno = color ? Pry::Helpers::BaseHelpers.colorize_code(padded) : 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,172 @@
|
|
1
|
+
class Pry
|
2
|
+
|
3
|
+
# This class is responsible for taking a string (identifying a
|
4
|
+
# command/class/method/etc) and returning the relevant type of object.
|
5
|
+
# For example, if the user looks up "show-source" then a
|
6
|
+
# `Pry::Command` will be returned. Alternatively, if the user passes in "Pry#repl" then
|
7
|
+
# a `Pry::Method` object will be returned.
|
8
|
+
#
|
9
|
+
# The `CodeObject.lookup` method is responsible for 1. figuring out what kind of
|
10
|
+
# object the user wants (applying precedence rules in doing so -- i.e methods
|
11
|
+
# get precedence over commands with the same name) and 2. Returning
|
12
|
+
# the appropriate object. If the user fails to provide a string
|
13
|
+
# identifer for the object (i.e they pass in `nil` or "") then the
|
14
|
+
# object looked up will be the 'current method' or 'current class'
|
15
|
+
# associated with the Binding.
|
16
|
+
#
|
17
|
+
# TODO: This class is a clusterfuck. We need a much more robust
|
18
|
+
# concept of what a "Code Object" really is. Currently
|
19
|
+
# commands/classes/candidates/methods and so on just share a very
|
20
|
+
# ill-defined interface.
|
21
|
+
class CodeObject
|
22
|
+
module Helpers
|
23
|
+
# we need this helper as some Pry::Method objects can wrap Procs
|
24
|
+
# @return [Boolean]
|
25
|
+
def real_method_object?
|
26
|
+
is_a?(::Method) || is_a?(::UnboundMethod)
|
27
|
+
end
|
28
|
+
|
29
|
+
def c_method?
|
30
|
+
real_method_object? && source_type == :c
|
31
|
+
end
|
32
|
+
|
33
|
+
def module_with_yard_docs?
|
34
|
+
is_a?(WrappedModule) && yard_docs?
|
35
|
+
end
|
36
|
+
|
37
|
+
def command?
|
38
|
+
is_a?(Module) && self <= Pry::Command
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
include Pry::Helpers::CommandHelpers
|
43
|
+
|
44
|
+
class << self
|
45
|
+
def lookup(str, _pry_, options={})
|
46
|
+
co = new(str, _pry_, options)
|
47
|
+
|
48
|
+
co.default_lookup || co.method_or_class_lookup ||
|
49
|
+
co.command_lookup || co.empty_lookup
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_accessor :str
|
54
|
+
attr_accessor :target
|
55
|
+
attr_accessor :_pry_
|
56
|
+
attr_accessor :super_level
|
57
|
+
|
58
|
+
def initialize(str, _pry_, options={})
|
59
|
+
options = {
|
60
|
+
:super => 0,
|
61
|
+
}.merge!(options)
|
62
|
+
|
63
|
+
@str = str
|
64
|
+
@_pry_ = _pry_
|
65
|
+
@target = _pry_.current_context
|
66
|
+
@super_level = options[:super]
|
67
|
+
end
|
68
|
+
|
69
|
+
def command_lookup
|
70
|
+
# TODO: just make it so find_command_by_match_or_listing doesn't
|
71
|
+
# raise?
|
72
|
+
_pry_.commands.find_command_by_match_or_listing(str) rescue nil
|
73
|
+
end
|
74
|
+
|
75
|
+
# when no paramter is given (i.e CodeObject.lookup(nil)), then we
|
76
|
+
# lookup the 'current object' from the binding.
|
77
|
+
def empty_lookup
|
78
|
+
return nil if str && !str.empty?
|
79
|
+
|
80
|
+
obj = if internal_binding?(target)
|
81
|
+
mod = target_self.is_a?(Module) ? target_self : target_self.class
|
82
|
+
Pry::WrappedModule(mod)
|
83
|
+
else
|
84
|
+
Pry::Method.from_binding(target)
|
85
|
+
end
|
86
|
+
|
87
|
+
# respect the super level (i.e user might have specified a
|
88
|
+
# --super flag to show-source)
|
89
|
+
lookup_super(obj, super_level)
|
90
|
+
end
|
91
|
+
|
92
|
+
# lookup variables and constants and `self` that are not modules
|
93
|
+
def default_lookup
|
94
|
+
|
95
|
+
# we skip instance methods as we want those to fall through to method_or_class_lookup()
|
96
|
+
if safe_to_evaluate?(str) && !looks_like_an_instance_method?(str)
|
97
|
+
obj = target.eval(str)
|
98
|
+
|
99
|
+
# restrict to only objects we KNOW for sure support the full API
|
100
|
+
# Do NOT support just any object that responds to source_location
|
101
|
+
if sourcable_object?(obj)
|
102
|
+
Pry::Method(obj)
|
103
|
+
elsif !obj.is_a?(Module)
|
104
|
+
Pry::WrappedModule(obj.class)
|
105
|
+
else
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
rescue Pry::RescuableException
|
111
|
+
nil
|
112
|
+
end
|
113
|
+
|
114
|
+
def method_or_class_lookup
|
115
|
+
obj = case str
|
116
|
+
when /\S+\(\)\z/
|
117
|
+
Pry::Method.from_str(str.sub(/\(\)\z/, ''),target) || Pry::WrappedModule.from_str(str, target)
|
118
|
+
else
|
119
|
+
Pry::WrappedModule.from_str(str,target) || Pry::Method.from_str(str, target)
|
120
|
+
end
|
121
|
+
|
122
|
+
lookup_super(obj, super_level)
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def sourcable_object?(obj)
|
128
|
+
[::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) }
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns true if `str` looks like a method, i.e Klass#method
|
132
|
+
# We need to consider this case because method lookups should fall
|
133
|
+
# through to the `method_or_class_lookup()` method but a
|
134
|
+
# defined?() on a "Klass#method` string will see the `#` as a
|
135
|
+
# comment and only evaluate the `Klass` part.
|
136
|
+
# @param [String] str
|
137
|
+
# @return [Boolean] Whether the string looks like an instance method.
|
138
|
+
def looks_like_an_instance_method?(str)
|
139
|
+
str =~ /\S#\S/
|
140
|
+
end
|
141
|
+
|
142
|
+
# We use this method to decide whether code is safe to eval. Method's are
|
143
|
+
# generally not, but everything else is.
|
144
|
+
# TODO: is just checking != "method" enough??
|
145
|
+
# TODO: see duplication of this method in Pry::WrappedModule
|
146
|
+
# @param [String] str The string to lookup
|
147
|
+
# @return [Boolean]
|
148
|
+
def safe_to_evaluate?(str)
|
149
|
+
return true if str.strip == "self"
|
150
|
+
kind = target.eval("defined?(#{str})")
|
151
|
+
kind =~ /variable|constant/
|
152
|
+
end
|
153
|
+
|
154
|
+
def target_self
|
155
|
+
target.eval('self')
|
156
|
+
end
|
157
|
+
|
158
|
+
# grab the nth (`super_level`) super of `obj
|
159
|
+
# @param [Object] obj
|
160
|
+
# @param [Fixnum] super_level How far up the super chain to ascend.
|
161
|
+
def lookup_super(obj, super_level)
|
162
|
+
return nil if !obj
|
163
|
+
|
164
|
+
sup = obj.super(super_level)
|
165
|
+
if !sup
|
166
|
+
raise Pry::CommandError, "No superclass found for #{obj.wrapped}"
|
167
|
+
else
|
168
|
+
sup
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# PP subclass for streaming inspect output in color.
|
2
|
+
class Pry
|
3
|
+
class ColorPrinter < ::PP
|
4
|
+
OBJ_COLOR = begin
|
5
|
+
code = CodeRay::Encoders::Terminal::TOKEN_COLORS[:keyword]
|
6
|
+
if code.start_with? "\e"
|
7
|
+
code
|
8
|
+
else
|
9
|
+
"\e[0m\e[0;#{code}m"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
CodeRay::Encoders::Terminal::TOKEN_COLORS[:comment][:self] = "\e[1;34m"
|
14
|
+
|
15
|
+
def self.pp(obj, out = $>, width = 79)
|
16
|
+
q = ColorPrinter.new(out, width)
|
17
|
+
q.guard_inspect_key { q.pp obj }
|
18
|
+
q.flush
|
19
|
+
out << "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
def text(str, width = str.length)
|
23
|
+
# Don't recolorize output with color [Issue #751]
|
24
|
+
if str.include?("\e[")
|
25
|
+
super "#{str}\e[0m", width
|
26
|
+
elsif str.start_with?('#<') || str == '=' || str == '>'
|
27
|
+
super highlight_object_literal(str), width
|
28
|
+
else
|
29
|
+
super CodeRay.scan(str, :ruby).term, width
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def pp(obj)
|
34
|
+
super
|
35
|
+
rescue => e
|
36
|
+
raise if e.is_a? Pry::Pager::StopPaging
|
37
|
+
|
38
|
+
# Read the class name off of the singleton class to provide a default
|
39
|
+
# inspect.
|
40
|
+
singleton = class << obj; self; end
|
41
|
+
ancestors = Pry::Method.safe_send(singleton, :ancestors)
|
42
|
+
klass = ancestors.reject { |k| k == singleton }.first
|
43
|
+
obj_id = obj.__id__.to_s(16) rescue 0
|
44
|
+
str = "#<#{klass}:0x#{obj_id}>"
|
45
|
+
|
46
|
+
text highlight_object_literal(str)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def highlight_object_literal(object_literal)
|
52
|
+
"#{OBJ_COLOR}#{object_literal}\e[0m"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|