pry 0.12.2-java → 0.13.0-java
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 +5 -5
- data/CHANGELOG.md +110 -1
- data/LICENSE +1 -1
- data/README.md +331 -269
- data/bin/pry +5 -0
- data/lib/pry.rb +133 -119
- data/lib/pry/basic_object.rb +8 -4
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +40 -31
- data/lib/pry/code.rb +39 -27
- data/lib/pry/code/code_file.rb +28 -24
- data/lib/pry/code/code_range.rb +4 -2
- data/lib/pry/code/loc.rb +15 -8
- data/lib/pry/code_object.rb +40 -38
- data/lib/pry/color_printer.rb +47 -46
- data/lib/pry/command.rb +166 -369
- data/lib/pry/command_set.rb +76 -73
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -81
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat.rb +61 -54
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +71 -60
- data/lib/pry/commands/cat/file_formatter.rb +55 -49
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cd.rb +40 -35
- data/lib/pry/commands/change_inspector.rb +29 -22
- data/lib/pry/commands/change_prompt.rb +44 -39
- data/lib/pry/commands/clear_screen.rb +16 -10
- data/lib/pry/commands/code_collector.rb +148 -133
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +19 -30
- data/lib/pry/commands/edit.rb +184 -161
- data/lib/pry/commands/edit/exception_patcher.rb +21 -17
- data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
- data/lib/pry/commands/exit.rb +39 -35
- data/lib/pry/commands/exit_all.rb +24 -20
- data/lib/pry/commands/exit_program.rb +20 -16
- data/lib/pry/commands/find_method.rb +168 -160
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +151 -150
- data/lib/pry/commands/import_set.rb +20 -16
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +35 -28
- data/lib/pry/commands/ls.rb +124 -102
- data/lib/pry/commands/ls/constants.rb +59 -42
- data/lib/pry/commands/ls/formatter.rb +50 -46
- data/lib/pry/commands/ls/globals.rb +38 -34
- data/lib/pry/commands/ls/grep.rb +17 -13
- data/lib/pry/commands/ls/instance_vars.rb +29 -27
- data/lib/pry/commands/ls/interrogatable.rb +18 -12
- data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
- data/lib/pry/commands/ls/local_names.rb +26 -22
- data/lib/pry/commands/ls/local_vars.rb +38 -28
- data/lib/pry/commands/ls/ls_entity.rb +47 -51
- data/lib/pry/commands/ls/methods.rb +44 -43
- data/lib/pry/commands/ls/methods_helper.rb +46 -42
- data/lib/pry/commands/ls/self_methods.rb +23 -22
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +93 -82
- data/lib/pry/commands/pry_backtrace.rb +24 -17
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +27 -22
- data/lib/pry/commands/reload_code.rb +60 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +55 -45
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +51 -51
- data/lib/pry/commands/shell_mode.rb +21 -17
- data/lib/pry/commands/show_doc.rb +81 -68
- data/lib/pry/commands/show_info.rb +189 -171
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +109 -45
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +20 -16
- data/lib/pry/commands/watch_expression.rb +89 -86
- data/lib/pry/commands/watch_expression/expression.rb +32 -27
- data/lib/pry/commands/whereami.rb +156 -148
- data/lib/pry/commands/wtf.rb +75 -50
- data/lib/pry/config.rb +311 -25
- data/lib/pry/config/attributable.rb +22 -0
- data/lib/pry/config/lazy_value.rb +29 -0
- data/lib/pry/config/memoized_value.rb +34 -0
- data/lib/pry/config/value.rb +24 -0
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +9 -7
- data/lib/pry/editor.rb +48 -21
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +13 -16
- data/lib/pry/forwardable.rb +5 -1
- data/lib/pry/helpers.rb +2 -0
- data/lib/pry/helpers/base_helpers.rb +68 -197
- data/lib/pry/helpers/command_helpers.rb +50 -61
- data/lib/pry/helpers/documentation_helpers.rb +20 -13
- data/lib/pry/helpers/options_helpers.rb +14 -7
- data/lib/pry/helpers/platform.rb +7 -5
- data/lib/pry/helpers/table.rb +33 -26
- data/lib/pry/helpers/text.rb +17 -14
- data/lib/pry/history.rb +48 -56
- data/lib/pry/hooks.rb +21 -12
- data/lib/pry/indent.rb +54 -50
- data/lib/pry/input_completer.rb +248 -230
- data/lib/pry/input_lock.rb +8 -9
- data/lib/pry/inspector.rb +36 -24
- data/lib/pry/last_exception.rb +45 -45
- data/lib/pry/method.rb +141 -94
- data/lib/pry/method/disowned.rb +16 -4
- data/lib/pry/method/patcher.rb +12 -3
- data/lib/pry/method/weird_method_locator.rb +68 -44
- data/lib/pry/object_path.rb +33 -25
- data/lib/pry/output.rb +121 -35
- data/lib/pry/pager.rb +41 -42
- data/lib/pry/plugins.rb +25 -8
- data/lib/pry/prompt.rb +123 -54
- data/lib/pry/pry_class.rb +61 -98
- data/lib/pry/pry_instance.rb +217 -215
- data/lib/pry/repl.rb +18 -22
- data/lib/pry/repl_file_loader.rb +27 -21
- data/lib/pry/ring.rb +11 -6
- data/lib/pry/slop.rb +574 -563
- data/lib/pry/slop/commands.rb +164 -169
- data/lib/pry/slop/option.rb +172 -168
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable.rb +59 -61
- data/lib/pry/testable/evalable.rb +21 -12
- data/lib/pry/testable/mockable.rb +18 -10
- data/lib/pry/testable/pry_tester.rb +71 -56
- data/lib/pry/testable/utility.rb +29 -21
- data/lib/pry/testable/variables.rb +49 -43
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +27 -0
- data/lib/pry/wrapped_module.rb +51 -42
- data/lib/pry/wrapped_module/candidate.rb +21 -14
- metadata +31 -30
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/commands/disabled_commands.rb +0 -2
- data/lib/pry/commands/gem_cd.rb +0 -26
- data/lib/pry/commands/gem_install.rb +0 -32
- data/lib/pry/commands/gem_list.rb +0 -33
- data/lib/pry/commands/gem_open.rb +0 -29
- data/lib/pry/commands/gem_readme.rb +0 -25
- data/lib/pry/commands/gem_search.rb +0 -40
- data/lib/pry/commands/gem_stats.rb +0 -83
- data/lib/pry/commands/gist.rb +0 -102
- data/lib/pry/commands/install_command.rb +0 -54
- data/lib/pry/config/behavior.rb +0 -255
- data/lib/pry/config/convenience.rb +0 -28
- data/lib/pry/config/default.rb +0 -159
- data/lib/pry/config/memoization.rb +0 -48
- data/lib/pry/platform.rb +0 -91
- data/lib/pry/rubygem.rb +0 -84
- data/lib/pry/terminal.rb +0 -91
data/lib/pry/commands/stat.rb
CHANGED
@@ -1,40 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class Command
|
5
|
+
class Stat < Pry::ClassCommand
|
6
|
+
match 'stat'
|
7
|
+
group 'Introspection'
|
8
|
+
description 'View method information and set _file_ and _dir_ locals.'
|
9
|
+
command_options shellwords: false
|
7
10
|
|
8
|
-
|
9
|
-
|
11
|
+
banner <<-'BANNER'
|
12
|
+
Usage: stat [OPTIONS] [METH]
|
10
13
|
|
11
|
-
|
14
|
+
Show method information for method METH and set _file_ and _dir_ locals.
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
stat hello_method
|
17
|
+
BANNER
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
+
def options(opt)
|
20
|
+
method_options(opt)
|
21
|
+
end
|
22
|
+
|
23
|
+
def process
|
24
|
+
meth = method_object
|
25
|
+
aliases = meth.aliases
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
Method Signature: #{meth.signature}
|
34
|
-
Source Location: #{meth.source_location ? meth.source_location.join(":") : "Not found."}
|
35
|
-
EOS
|
27
|
+
output.puts(unindent(<<-OUTPUT))
|
28
|
+
Method Information:
|
29
|
+
--
|
30
|
+
Name: #{meth.name}
|
31
|
+
Alias#{'es' if aliases.length > 1}: #{aliases.any? ? aliases.join(', ') : 'None.'}
|
32
|
+
Owner: #{meth.owner || 'Unknown'}
|
33
|
+
Visibility: #{meth.visibility}
|
34
|
+
Type: #{meth.is_a?(::Method) ? 'Bound' : 'Unbound'}
|
35
|
+
Arity: #{meth.arity}
|
36
|
+
Method Signature: #{meth.signature}
|
37
|
+
Source Location: #{meth.source_location ? meth.source_location.join(':') : 'Not found.'}
|
38
|
+
OUTPUT
|
39
|
+
end
|
36
40
|
end
|
37
|
-
end
|
38
41
|
|
39
|
-
|
42
|
+
Pry::Commands.add_command(Pry::Command::Stat)
|
43
|
+
end
|
40
44
|
end
|
@@ -1,23 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
class Command
|
5
|
+
class SwitchTo < Pry::ClassCommand
|
6
|
+
match 'switch-to'
|
7
|
+
group 'Navigating Pry'
|
8
|
+
description 'Start a new subsession on a binding in the current stack.'
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
banner <<-'BANNER'
|
11
|
+
Start a new subsession on a binding in the current stack (numbered by nesting).
|
12
|
+
BANNER
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
def process(selection)
|
15
|
+
selection = selection.to_i
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
if selection < 0 || selection > pry_instance.binding_stack.size - 1
|
18
|
+
raise CommandError,
|
19
|
+
"Invalid binding index #{selection} - use `nesting` command " \
|
20
|
+
"to view valid indices."
|
21
|
+
else
|
22
|
+
Pry.start(pry_instance.binding_stack[selection])
|
23
|
+
end
|
18
24
|
end
|
19
25
|
end
|
20
|
-
end
|
21
26
|
|
22
|
-
|
27
|
+
Pry::Commands.add_command(Pry::Command::SwitchTo)
|
28
|
+
end
|
23
29
|
end
|
@@ -1,24 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
class Command
|
5
|
+
class ToggleColor < Pry::ClassCommand
|
6
|
+
match 'toggle-color'
|
7
|
+
group 'Misc'
|
8
|
+
description 'Toggle syntax highlighting.'
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
banner <<-'BANNER'
|
11
|
+
Usage: toggle-color
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
Toggle syntax highlighting.
|
14
|
+
BANNER
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
def process
|
17
|
+
pry_instance.color = color_toggle
|
18
|
+
output.puts "Syntax highlighting #{pry_instance.color ? 'on' : 'off'}"
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
def color_toggle
|
22
|
+
!pry_instance.color
|
23
|
+
end
|
21
24
|
|
22
|
-
|
25
|
+
Pry::Commands.add_command(self)
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
@@ -1,107 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def options(opt)
|
30
|
-
opt.on :d, :delete,
|
31
|
-
"Delete the watch expression with the given index. If no index is given; clear all watch expressions.",
|
32
|
-
optional_argument: true, as: Integer
|
33
|
-
opt.on :l, :list,
|
34
|
-
"Show all current watch expressions and their values. Calling watch with no expressions or options will also show the watch expressions."
|
35
|
-
end
|
4
|
+
class Command
|
5
|
+
class WatchExpression < Pry::ClassCommand
|
6
|
+
match 'watch'
|
7
|
+
group 'Context'
|
8
|
+
description 'Watch the value of an expression and print a notification ' \
|
9
|
+
'whenever it changes.'
|
10
|
+
command_options use_prefix: false
|
11
|
+
|
12
|
+
banner <<-'BANNER'
|
13
|
+
Usage: watch [EXPRESSION]
|
14
|
+
watch
|
15
|
+
watch --delete [INDEX]
|
16
|
+
|
17
|
+
watch [EXPRESSION] adds an expression to the list of those being watched.
|
18
|
+
It will be re-evaluated every time you hit enter in pry. If its value has
|
19
|
+
changed, the new value will be printed to the console.
|
20
|
+
|
21
|
+
This is useful if you are step-through debugging and want to see how
|
22
|
+
something changes over time. It's also useful if you're trying to write
|
23
|
+
a method inside pry and want to check that it gives the right answers
|
24
|
+
every time you redefine it.
|
25
|
+
|
26
|
+
watch on its own displays all the currently watched expressions and their
|
27
|
+
values, and watch --delete [INDEX] allows you to delete expressions from
|
28
|
+
the list being watched.
|
29
|
+
BANNER
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
list
|
43
|
-
|
44
|
-
|
45
|
-
|
31
|
+
def options(opt)
|
32
|
+
opt.on :d, :delete,
|
33
|
+
"Delete the watch expression with the given index. If no index " \
|
34
|
+
"is given; clear all watch expressions.",
|
35
|
+
optional_argument: true, as: Integer
|
36
|
+
opt.on :l, :list,
|
37
|
+
"Show all current watch expressions and their values. Calling " \
|
38
|
+
"watch with no expressions or options will also show the watch " \
|
39
|
+
"expressions."
|
46
40
|
end
|
47
|
-
end
|
48
41
|
|
49
|
-
|
42
|
+
def process
|
43
|
+
if opts.present?(:delete)
|
44
|
+
delete opts[:delete]
|
45
|
+
elsif opts.present?(:list) || args.empty?
|
46
|
+
list
|
47
|
+
else
|
48
|
+
add_hook
|
49
|
+
add_expression(args)
|
50
|
+
end
|
51
|
+
end
|
50
52
|
|
51
|
-
|
52
|
-
_pry_.config.watch_expressions ||= []
|
53
|
-
end
|
53
|
+
private
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
output.puts "Deleting watch expression ##{index}: #{expressions[index - 1]}"
|
58
|
-
expressions.delete_at(index - 1)
|
59
|
-
else
|
60
|
-
output.puts "Deleting all watched expressions"
|
61
|
-
expressions.clear
|
55
|
+
def expressions
|
56
|
+
state.watch_expressions ||= []
|
62
57
|
end
|
63
|
-
end
|
64
58
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
59
|
+
def delete(index)
|
60
|
+
if index
|
61
|
+
output.puts "Deleting watch expression ##{index}: #{expressions[index - 1]}"
|
62
|
+
expressions.delete_at(index - 1)
|
63
|
+
else
|
64
|
+
output.puts "Deleting all watched expressions"
|
65
|
+
expressions.clear
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def list
|
70
|
+
if expressions.empty?
|
71
|
+
output.puts "No watched expressions"
|
72
|
+
else
|
73
|
+
pry_instance.pager.open do |pager|
|
74
|
+
pager.puts "Listing all watched expressions:"
|
75
|
+
pager.puts ""
|
76
|
+
expressions.each_with_index do |expr, index|
|
77
|
+
pager.print with_line_numbers(expr.to_s, index + 1)
|
78
|
+
end
|
79
|
+
pager.puts ""
|
74
80
|
end
|
75
|
-
pager.puts ""
|
76
81
|
end
|
77
82
|
end
|
78
|
-
end
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
output.puts "#{blue "watch"}: #{expr}"
|
84
|
+
def eval_and_print_changed(output)
|
85
|
+
expressions.each do |expr|
|
86
|
+
expr.eval!
|
87
|
+
output.puts "#{blue 'watch'}: #{expr}" if expr.changed?
|
85
88
|
end
|
86
89
|
end
|
87
|
-
end
|
88
90
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
# TODO: fix arguments.
|
92
|
+
# https://github.com/pry/pry/commit/b031df2f2f5850ee6e9018f33d35f3485a9b0423
|
93
|
+
def add_expression(_arguments)
|
94
|
+
expressions << Expression.new(pry_instance, target, arg_string)
|
95
|
+
output.puts "Watching #{Code.new(arg_string).highlighted}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_hook
|
99
|
+
hook = [:after_eval, :watch_expression]
|
100
|
+
return if pry_instance.hooks.hook_exists?(*hook)
|
95
101
|
|
96
|
-
|
97
|
-
|
98
|
-
unless _pry_.hooks.hook_exists?(*hook)
|
99
|
-
_pry_.hooks.add_hook(*hook) do |_, _pry_|
|
100
|
-
eval_and_print_changed _pry_.output
|
102
|
+
pry_instance.hooks.add_hook(*hook) do |_, pry_instance|
|
103
|
+
eval_and_print_changed pry_instance.output
|
101
104
|
end
|
102
105
|
end
|
103
106
|
end
|
104
|
-
end
|
105
107
|
|
106
|
-
|
108
|
+
Pry::Commands.add_command(Pry::Command::WatchExpression)
|
109
|
+
end
|
107
110
|
end
|
@@ -1,37 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
class
|
4
|
-
|
4
|
+
class Command
|
5
|
+
class WatchExpression
|
6
|
+
class Expression
|
7
|
+
attr_reader :target, :source, :value, :previous_value, :pry_instance
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def initialize(pry_instance, target, source)
|
10
|
+
@pry_instance = pry_instance
|
11
|
+
@target = target
|
12
|
+
@source = Code.new(source).strip
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
def eval!
|
16
|
+
@previous_value = value
|
17
|
+
@value = Pry::ColorPrinter.pp(target_eval(target, source), ''.dup)
|
18
|
+
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
def to_s
|
21
|
+
"#{Code.new(source).highlighted.strip} => #{value}"
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
# Has the value of the expression changed?
|
25
|
+
#
|
26
|
+
# We use the pretty-printed string represenation to detect differences
|
27
|
+
# as this avoids problems with dup (causes too many differences) and ==
|
28
|
+
# (causes too few)
|
29
|
+
def changed?
|
30
|
+
(value != previous_value)
|
31
|
+
end
|
28
32
|
|
29
|
-
|
33
|
+
private
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
def target_eval(target, source)
|
36
|
+
target.eval(source)
|
37
|
+
rescue StandardError => e
|
38
|
+
e
|
39
|
+
end
|
35
40
|
end
|
36
41
|
end
|
37
42
|
end
|
@@ -1,197 +1,205 @@
|
|
1
|
-
|
2
|
-
class Command::Whereami < Pry::ClassCommand
|
3
|
-
def initialize(*)
|
4
|
-
super
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
end
|
3
|
+
require 'method_source'
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
class Pry
|
6
|
+
class Command
|
7
|
+
class Whereami < Pry::ClassCommand
|
8
|
+
def initialize(*)
|
9
|
+
super
|
12
10
|
|
13
|
-
|
11
|
+
@method_code = nil
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
class << self
|
15
|
+
attr_accessor :method_size_cutoff
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
Usage: whereami [-qn] [LINES]
|
18
|
+
@method_size_cutoff = 30
|
21
19
|
|
22
|
-
|
23
|
-
|
20
|
+
match 'whereami'
|
21
|
+
description 'Show code surrounding the current context.'
|
22
|
+
group 'Context'
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
banner <<-'BANNER'
|
25
|
+
Usage: whereami [-qn] [LINES]
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
you when you arrive at a `binding.pry`.
|
27
|
+
Describe the current location. If you use `binding.pry` inside a method then
|
28
|
+
whereami will print out the source for that method.
|
31
29
|
|
32
|
-
|
33
|
-
|
30
|
+
If a number is passed, then LINES lines before and after the current line will be
|
31
|
+
shown instead of the method itself.
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
The `-q` flag can be used to suppress error messages in the case that there's
|
34
|
+
no code to show. This is used by pry in the default before_session hook to show
|
35
|
+
you when you arrive at a `binding.pry`.
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
@line = target.eval('__LINE__')
|
42
|
-
@method = Pry::Method.from_binding(target)
|
43
|
-
end
|
37
|
+
The `-n` flag can be used to hide line numbers so that code can be copy/pasted
|
38
|
+
effectively.
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
opt.on :m, :"method", "Show the complete source for the current method."
|
49
|
-
opt.on :c, :"class", "Show the complete source for the current class or module."
|
50
|
-
opt.on :f, :"file", "Show the complete source for the current file."
|
51
|
-
end
|
40
|
+
When pry was started on an Object and there is no associated method, whereami
|
41
|
+
will instead output a brief description of the current object.
|
42
|
+
BANNER
|
52
43
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
default_code
|
64
|
-
end
|
65
|
-
end
|
44
|
+
def setup
|
45
|
+
if target.respond_to?(:source_location)
|
46
|
+
file, @line = target.source_location
|
47
|
+
@file = expand_path(file)
|
48
|
+
else
|
49
|
+
@file = expand_path(target.eval('__FILE__'))
|
50
|
+
@line = target.eval('__LINE__')
|
51
|
+
end
|
52
|
+
@method = Pry::Method.from_binding(target)
|
53
|
+
end
|
66
54
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
55
|
+
def options(opt)
|
56
|
+
opt.on :q, :quiet, "Don't display anything in case of an error"
|
57
|
+
opt.on :n, :"no-line-numbers", "Do not display line numbers"
|
58
|
+
opt.on :m, :method, "Show the complete source for the current method."
|
59
|
+
opt.on :c, :class, "Show the complete source for the current class or module."
|
60
|
+
opt.on :f, :file, "Show the complete source for the current file."
|
61
|
+
end
|
72
62
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
63
|
+
def code
|
64
|
+
@code ||= if opts.present?(:m)
|
65
|
+
method_code || raise(CommandError, "Cannot find method code.")
|
66
|
+
elsif opts.present?(:c)
|
67
|
+
class_code || raise(CommandError, "Cannot find class code.")
|
68
|
+
elsif opts.present?(:f)
|
69
|
+
Pry::Code.from_file(@file)
|
70
|
+
elsif args.any?
|
71
|
+
code_window
|
72
|
+
else
|
73
|
+
default_code
|
74
|
+
end
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
def code?
|
78
|
+
!!code
|
79
|
+
rescue MethodSource::SourceNotFoundError
|
80
|
+
false
|
81
|
+
end
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
83
|
+
def bad_option_combination?
|
84
|
+
[opts.present?(:m), opts.present?(:f),
|
85
|
+
opts.present?(:c), args.any?].count(true) > 1
|
85
86
|
end
|
86
87
|
|
87
|
-
|
88
|
-
|
89
|
-
elsif internal_binding?(target)
|
90
|
-
handle_internal_binding
|
91
|
-
return
|
88
|
+
def location
|
89
|
+
"#{@file}:#{@line} #{@method && @method.name_with_owner}"
|
92
90
|
end
|
93
91
|
|
94
|
-
|
92
|
+
def process
|
93
|
+
if bad_option_combination?
|
94
|
+
raise CommandError, "Only one of -m, -c, -f, and LINES may be specified."
|
95
|
+
end
|
95
96
|
|
96
|
-
|
97
|
-
code.with_line_numbers(use_line_numbers?).with_marker(marker).highlighted << "\n"
|
97
|
+
return if nothing_to_do?
|
98
98
|
|
99
|
-
|
100
|
-
|
99
|
+
if internal_binding?(target)
|
100
|
+
handle_internal_binding
|
101
|
+
return
|
102
|
+
end
|
101
103
|
|
102
|
-
|
104
|
+
set_file_and_dir_locals(@file)
|
103
105
|
|
104
|
-
|
105
|
-
|
106
|
-
|
106
|
+
pretty_code = code.with_line_numbers(use_line_numbers?)
|
107
|
+
.with_marker(marker)
|
108
|
+
.highlighted
|
109
|
+
pry_instance.pager.page(
|
110
|
+
"\n#{bold('From:')} #{location}:\n\n" + pretty_code + "\n"
|
111
|
+
)
|
112
|
+
end
|
107
113
|
|
108
|
-
|
109
|
-
!opts.present?(:n)
|
110
|
-
end
|
114
|
+
private
|
111
115
|
|
112
|
-
|
113
|
-
|
114
|
-
|
116
|
+
def nothing_to_do?
|
117
|
+
opts.quiet? && (internal_binding?(target) || !code?)
|
118
|
+
end
|
115
119
|
|
116
|
-
|
117
|
-
|
118
|
-
|
120
|
+
def use_line_numbers?
|
121
|
+
!opts.present?(:n)
|
122
|
+
end
|
119
123
|
|
120
|
-
|
121
|
-
|
122
|
-
output.puts "At the top level."
|
123
|
-
else
|
124
|
-
output.puts "Inside #{Pry.view_clip(target_self)}."
|
124
|
+
def marker
|
125
|
+
!opts.present?(:n) && @line
|
125
126
|
end
|
126
|
-
end
|
127
127
|
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
def top_level?
|
129
|
+
target_self == Pry.main
|
130
|
+
end
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
132
|
+
def handle_internal_binding
|
133
|
+
if top_level?
|
134
|
+
output.puts "At the top level."
|
135
|
+
else
|
136
|
+
output.puts "Inside #{Pry.view_clip(target_self)}."
|
137
|
+
end
|
137
138
|
end
|
138
|
-
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
140
|
+
def small_method?
|
141
|
+
@method.source_range.count < self.class.method_size_cutoff
|
142
|
+
end
|
143
143
|
|
144
|
-
|
145
|
-
|
144
|
+
def default_code
|
145
|
+
if method_code && small_method?
|
146
|
+
method_code
|
147
|
+
else
|
148
|
+
code_window
|
149
|
+
end
|
150
|
+
end
|
146
151
|
|
147
|
-
|
148
|
-
|
152
|
+
def code_window
|
153
|
+
Pry::Code.from_file(@file).around(@line, window_size)
|
149
154
|
end
|
150
|
-
end
|
151
155
|
|
152
|
-
|
153
|
-
|
154
|
-
# @return [Pry::WrappedModule]
|
155
|
-
def target_class
|
156
|
-
return Pry::WrappedModule(target_self) if target_self.is_a?(Module)
|
156
|
+
def method_code
|
157
|
+
return @method_code if @method_code
|
157
158
|
|
158
|
-
|
159
|
-
|
159
|
+
@method_code = Pry::Code.from_method(@method) if valid_method?
|
160
|
+
end
|
160
161
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
idx && Pry::Code.from_module(mod, idx)
|
167
|
-
end
|
168
|
-
end
|
162
|
+
# This either returns the `target_self`
|
163
|
+
# or it returns the class of `target_self` if `target_self` is not a class.
|
164
|
+
# @return [Pry::WrappedModule]
|
165
|
+
def target_class
|
166
|
+
return Pry::WrappedModule(target_self) if target_self.is_a?(Module)
|
169
167
|
|
170
|
-
|
171
|
-
|
172
|
-
@method.source_range.include?(@line)
|
173
|
-
end
|
168
|
+
Pry::WrappedModule(target_self.class)
|
169
|
+
end
|
174
170
|
|
175
|
-
|
176
|
-
|
171
|
+
def class_code
|
172
|
+
@class_code ||=
|
173
|
+
begin
|
174
|
+
mod = @method ? Pry::WrappedModule(@method.owner) : target_class
|
175
|
+
idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
|
176
|
+
idx && Pry::Code.from_module(mod, idx)
|
177
|
+
end
|
178
|
+
end
|
177
179
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
File.expand_path(f)
|
180
|
+
def valid_method?
|
181
|
+
@method && @method.source? && expand_path(@method.source_file) == @file &&
|
182
|
+
@method.source_range.include?(@line)
|
182
183
|
end
|
183
|
-
end
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
185
|
+
def expand_path(filename)
|
186
|
+
return unless filename
|
187
|
+
return filename if Pry.eval_path == filename
|
188
|
+
|
189
|
+
File.expand_path(filename)
|
190
|
+
end
|
191
|
+
|
192
|
+
def window_size
|
193
|
+
if args.empty?
|
194
|
+
pry_instance.config.default_window_size
|
195
|
+
else
|
196
|
+
args.first.to_i
|
197
|
+
end
|
190
198
|
end
|
191
199
|
end
|
192
|
-
end
|
193
200
|
|
194
|
-
|
195
|
-
|
196
|
-
|
201
|
+
Pry::Commands.add_command(Pry::Command::Whereami)
|
202
|
+
Pry::Commands.alias_command '@', 'whereami'
|
203
|
+
Pry::Commands.alias_command(/whereami[!?]+/, 'whereami')
|
204
|
+
end
|
197
205
|
end
|