pry 0.10.3 → 0.14.2

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 (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +439 -16
  3. data/LICENSE +1 -1
  4. data/README.md +362 -302
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +84 -97
  10. data/lib/pry/code/code_file.rb +37 -26
  11. data/lib/pry/code/code_range.rb +7 -5
  12. data/lib/pry/code/loc.rb +26 -13
  13. data/lib/pry/code.rb +42 -31
  14. data/lib/pry/code_object.rb +53 -28
  15. data/lib/pry/color_printer.rb +46 -35
  16. data/lib/pry/command.rb +197 -369
  17. data/lib/pry/command_set.rb +89 -114
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -72
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -46
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +62 -54
  27. data/lib/pry/commands/cd.rb +40 -35
  28. data/lib/pry/commands/change_inspector.rb +29 -22
  29. data/lib/pry/commands/change_prompt.rb +48 -23
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  36. data/lib/pry/commands/edit.rb +185 -157
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -16
  40. data/lib/pry/commands/find_method.rb +168 -162
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +151 -149
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +35 -28
  47. data/lib/pry/commands/ls/constants.rb +59 -31
  48. data/lib/pry/commands/ls/formatter.rb +42 -36
  49. data/lib/pry/commands/ls/globals.rb +38 -36
  50. data/lib/pry/commands/ls/grep.rb +17 -15
  51. data/lib/pry/commands/ls/instance_vars.rb +29 -28
  52. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  53. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  54. data/lib/pry/commands/ls/local_names.rb +26 -24
  55. data/lib/pry/commands/ls/local_vars.rb +38 -30
  56. data/lib/pry/commands/ls/ls_entity.rb +47 -52
  57. data/lib/pry/commands/ls/methods.rb +49 -51
  58. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  59. data/lib/pry/commands/ls/self_methods.rb +23 -21
  60. data/lib/pry/commands/ls.rb +124 -103
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +92 -82
  63. data/lib/pry/commands/pry_backtrace.rb +22 -17
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +60 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -42
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +56 -29
  71. data/lib/pry/commands/shell_mode.rb +22 -18
  72. data/lib/pry/commands/show_doc.rb +80 -70
  73. data/lib/pry/commands/show_info.rb +194 -155
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +110 -42
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +20 -16
  79. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  80. data/lib/pry/commands/watch_expression.rb +89 -84
  81. data/lib/pry/commands/whereami.rb +156 -141
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +310 -20
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +22 -9
  90. data/lib/pry/editor.rb +56 -34
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +13 -18
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +20 -62
  96. data/lib/pry/helpers/command_helpers.rb +52 -62
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -12
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +55 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -85
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +81 -55
  104. data/lib/pry/hooks.rb +60 -110
  105. data/lib/pry/indent.rb +74 -68
  106. data/lib/pry/input_completer.rb +199 -158
  107. data/lib/pry/input_lock.rb +7 -10
  108. data/lib/pry/inspector.rb +36 -24
  109. data/lib/pry/last_exception.rb +45 -45
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/method/patcher.rb +14 -8
  112. data/lib/pry/method/weird_method_locator.rb +79 -45
  113. data/lib/pry/method.rb +178 -124
  114. data/lib/pry/object_path.rb +37 -28
  115. data/lib/pry/output.rb +102 -16
  116. data/lib/pry/pager.rb +187 -174
  117. data/lib/pry/prompt.rb +213 -25
  118. data/lib/pry/pry_class.rb +119 -98
  119. data/lib/pry/pry_instance.rb +261 -224
  120. data/lib/pry/repl.rb +83 -29
  121. data/lib/pry/repl_file_loader.rb +27 -22
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
  138. data/lib/pry/wrapped_module.rb +68 -63
  139. data/lib/pry.rb +133 -149
  140. metadata +58 -69
  141. data/lib/pry/commands/disabled_commands.rb +0 -2
  142. data/lib/pry/commands/gem_cd.rb +0 -26
  143. data/lib/pry/commands/gem_install.rb +0 -32
  144. data/lib/pry/commands/gem_list.rb +0 -33
  145. data/lib/pry/commands/gem_open.rb +0 -29
  146. data/lib/pry/commands/gist.rb +0 -101
  147. data/lib/pry/commands/install_command.rb +0 -53
  148. data/lib/pry/commands/list_prompts.rb +0 -35
  149. data/lib/pry/commands/simple_prompt.rb +0 -22
  150. data/lib/pry/commands.rb +0 -6
  151. data/lib/pry/config/behavior.rb +0 -139
  152. data/lib/pry/config/convenience.rb +0 -25
  153. data/lib/pry/config/default.rb +0 -161
  154. data/lib/pry/history_array.rb +0 -121
  155. data/lib/pry/plugins.rb +0 -103
  156. data/lib/pry/rbx_path.rb +0 -22
  157. data/lib/pry/rubygem.rb +0 -82
  158. data/lib/pry/terminal.rb +0 -79
  159. data/lib/pry/test/helper.rb +0 -170
@@ -1,50 +1,118 @@
1
- require 'pry/commands/show_info'
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Pry
4
- class Command::ShowSource < Command::ShowInfo
5
- match 'show-source'
6
- group 'Introspection'
7
- description 'Show the source for a method or class.'
8
-
9
- banner <<-'BANNER'
10
- Usage: show-source [OPTIONS] [METH|CLASS]
11
- Aliases: $, show-method
12
-
13
- Show the source for a method or class. Tries instance methods first and then
14
- methods by default.
15
-
16
- show-source hi_method
17
- show-source hi_method
18
- show-source Pry#rep # source for Pry#rep method
19
- show-source Pry # for Pry class
20
- show-source Pry -a # for all Pry class definitions (all monkey patches)
21
- show-source Pry.foo -e # for class of the return value of expression `Pry.foo`
22
- show-source Pry --super # for superclass of Pry (Object class)
23
-
24
- https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method
25
- BANNER
26
-
27
- def options(opt)
28
- opt.on :e, :eval, "evaluate the command's argument as a ruby expression and show the class its return value"
29
- super(opt)
30
- end
4
+ class Command
5
+ class ShowSource < Command::ShowInfo
6
+ include Pry::Helpers::DocumentationHelpers
7
+
8
+ match 'show-source'
9
+ group 'Introspection'
10
+ description 'Show the source for a method or class.'
11
+
12
+ banner <<-'BANNER'
13
+ Usage: show-source [OPTIONS] [METH|CLASS]
14
+ Aliases: $, show-method
15
+
16
+ Show the source for a method or class. Tries instance methods first and then
17
+ methods by default.
31
18
 
32
- def process
33
- if opts.present?(:e)
34
- obj = target.eval(args.first)
35
- self.args = Array.new(1) { Module === obj ? obj.name : obj.class.name }
19
+ show-source hi_method
20
+ show-source hi_method
21
+ show-source Pry#rep # source for Pry#rep method
22
+ show-source Pry # for Pry class
23
+ show-source Pry -a # for all Pry class definitions (all monkey patches)
24
+ show-source Pry.foo -e # for class of the return value of expression `Pry.foo`
25
+ show-source Pry --super # for superclass of Pry (Object class)
26
+ show-source Pry -d # include documentation
27
+
28
+ https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method
29
+ BANNER
30
+
31
+ def options(opt)
32
+ opt.on :e, :eval, "evaluate the command's argument as a ruby " \
33
+ "expression and show the class its return value"
34
+ opt.on :d, :doc, 'include documentation in the output'
35
+ super(opt)
36
+ end
37
+
38
+ def process
39
+ if opts.present?(:e)
40
+ obj = target.eval(args.first)
41
+ self.args = Array.new(1) { obj.is_a?(Module) ? obj.name : obj.class.name }
42
+ end
43
+
44
+ super
45
+ end
46
+
47
+ # The source for code_object prepared for display.
48
+ def content_for(code_object)
49
+ content = ''
50
+ if opts.present?(:d)
51
+ code = Code.new(
52
+ render_doc_markup_for(code_object), start_line_for(code_object), :text
53
+ )
54
+ content += code.with_line_numbers(use_line_numbers?).to_s
55
+ content += "\n"
56
+ end
57
+
58
+ code = Code.new(
59
+ code_object.source || [], start_line_for(code_object)
60
+ )
61
+ content += code.with_line_numbers(use_line_numbers?).highlighted
62
+ content
36
63
  end
37
- super
38
- end
39
64
 
40
- # The source for code_object prepared for display.
41
- def content_for(code_object)
42
- Code.new(code_object.source, start_line_for(code_object)).
43
- with_line_numbers(use_line_numbers?).highlighted
65
+ # process the markup (if necessary) and apply colors
66
+ def render_doc_markup_for(code_object)
67
+ docs = docs_for(code_object)
68
+
69
+ if code_object.command?
70
+ # command '--help' shouldn't use markup highlighting
71
+ docs
72
+ else
73
+ if docs.empty?
74
+ raise CommandError, "No docs found for: #{obj_name || 'current context'}"
75
+ end
76
+
77
+ process_comment_markup(docs)
78
+ end
79
+ end
80
+
81
+ # Return docs for the code_object, adjusting for whether the code_object
82
+ # has yard docs available, in which case it returns those.
83
+ # (note we only have to check yard docs for modules since they can
84
+ # have multiple docs, but methods can only be doc'd once so we
85
+ # dont need to check them)
86
+ def docs_for(code_object)
87
+ if code_object.module_with_yard_docs?
88
+ # yard docs
89
+ code_object.yard_doc
90
+ else
91
+ # normal docs (i.e comments above method/module/command)
92
+ code_object.doc
93
+ end
94
+ end
95
+
96
+ # Which sections to include in the 'header', can toggle: :owner,
97
+ # :signature and visibility.
98
+ def header_options
99
+ super.merge signature: true
100
+ end
101
+
102
+ # figure out start line of docs by back-calculating based on
103
+ # number of lines in the comment and the start line of the code_object
104
+ # @return [Fixnum] start line of docs
105
+ def start_line_for(code_object)
106
+ return 1 if code_object.command? || opts.present?(:'base-one')
107
+ return 1 unless code_object.source_line
108
+
109
+ code_object.source_line - code_object.doc.lines.count
110
+ end
44
111
  end
45
- end
46
112
 
47
- Pry::Commands.add_command(Pry::Command::ShowSource)
48
- Pry::Commands.alias_command 'show-method', 'show-source'
49
- Pry::Commands.alias_command '$', 'show-source'
113
+ Pry::Commands.add_command(Pry::Command::ShowSource)
114
+ Pry::Commands.alias_command 'show-method', 'show-source'
115
+ Pry::Commands.alias_command '$', 'show-source'
116
+ Pry::Commands.alias_command '?', 'show-source -d'
117
+ end
50
118
  end
@@ -1,40 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::Stat < Pry::ClassCommand
3
- match 'stat'
4
- group 'Introspection'
5
- description 'View method information and set _file_ and _dir_ locals.'
6
- command_options :shellwords => false
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
- banner <<-'BANNER'
9
- Usage: stat [OPTIONS] [METH]
11
+ banner <<-'BANNER'
12
+ Usage: stat [OPTIONS] [METH]
10
13
 
11
- Show method information for method METH and set _file_ and _dir_ locals.
14
+ Show method information for method METH and set _file_ and _dir_ locals.
12
15
 
13
- stat hello_method
14
- BANNER
16
+ stat hello_method
17
+ BANNER
15
18
 
16
- def options(opt)
17
- method_options(opt)
18
- end
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
- def process
21
- meth = method_object
22
- aliases = meth.aliases
23
-
24
- output.puts unindent <<-EOS
25
- Method Information:
26
- --
27
- Name: #{meth.name}
28
- Alias#{ "es" if aliases.length > 1 }: #{ aliases.any? ? aliases.join(", ") : "None." }
29
- Owner: #{meth.owner ? meth.owner : "Unknown"}
30
- Visibility: #{meth.visibility}
31
- Type: #{meth.is_a?(::Method) ? "Bound" : "Unbound"}
32
- Arity: #{meth.arity}
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
- Pry::Commands.add_command(Pry::Command::Stat)
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::SwitchTo < Pry::ClassCommand
3
- match 'switch-to'
4
- group 'Navigating Pry'
5
- description 'Start a new subsession on a binding in the current stack.'
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
- banner <<-'BANNER'
8
- Start a new subsession on a binding in the current stack (numbered by nesting).
9
- BANNER
10
+ banner <<-'BANNER'
11
+ Start a new subsession on a binding in the current stack (numbered by nesting).
12
+ BANNER
10
13
 
11
- def process(selection)
12
- selection = selection.to_i
14
+ def process(selection)
15
+ selection = selection.to_i
13
16
 
14
- if selection < 0 || selection > _pry_.binding_stack.size - 1
15
- raise CommandError, "Invalid binding index #{selection} - use `nesting` command to view valid indices."
16
- else
17
- Pry.start(_pry_.binding_stack[selection])
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
- Pry::Commands.add_command(Pry::Command::SwitchTo)
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::ToggleColor < Pry::ClassCommand
3
- match 'toggle-color'
4
- group 'Misc'
5
- description 'Toggle syntax highlighting.'
4
+ class Command
5
+ class ToggleColor < Pry::ClassCommand
6
+ match 'toggle-color'
7
+ group 'Misc'
8
+ description 'Toggle syntax highlighting.'
6
9
 
7
- banner <<-'BANNER'
8
- Usage: toggle-color
10
+ banner <<-'BANNER'
11
+ Usage: toggle-color
9
12
 
10
- Toggle syntax highlighting.
11
- BANNER
13
+ Toggle syntax highlighting.
14
+ BANNER
12
15
 
13
- def process
14
- _pry_.color = color_toggle
15
- output.puts "Syntax highlighting #{_pry_.color ? "on" : "off"}"
16
- end
16
+ def process
17
+ pry_instance.color = color_toggle
18
+ output.puts "Syntax highlighting #{pry_instance.color ? 'on' : 'off'}"
19
+ end
17
20
 
18
- def color_toggle
19
- !_pry_.color
20
- end
21
+ def color_toggle
22
+ !pry_instance.color
23
+ end
21
24
 
22
- Pry::Commands.add_command(self)
25
+ Pry::Commands.add_command(self)
26
+ end
23
27
  end
24
28
  end
@@ -1,37 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::WatchExpression
3
- class Expression
4
- attr_reader :target, :source, :value, :previous_value, :_pry_
4
+ class Command
5
+ class WatchExpression
6
+ class Expression
7
+ attr_reader :target, :source, :value, :previous_value, :pry_instance
5
8
 
6
- def initialize(_pry_, target, source)
7
- @_pry_ = _pry_
8
- @target = target
9
- @source = Code.new(source).strip
10
- end
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
- def eval!
13
- @previous_value = @value
14
- @value = Pry::ColorPrinter.pp(target_eval(target, source), "")
15
- end
15
+ def eval!
16
+ @previous_value = value
17
+ @value = Pry::ColorPrinter.pp(target_eval(target, source), ''.dup)
18
+ end
16
19
 
17
- def to_s
18
- "#{Code.new(source).highlighted.strip} => #{value}"
19
- end
20
+ def to_s
21
+ "#{Code.new(source).highlighted.strip} => #{value}"
22
+ end
20
23
 
21
- # Has the value of the expression changed?
22
- #
23
- # We use the pretty-printed string represenation to detect differences
24
- # as this avoids problems with dup (causes too many differences) and == (causes too few)
25
- def changed?
26
- (value != previous_value)
27
- end
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
- private
33
+ private
30
34
 
31
- def target_eval(target, source)
32
- target.eval(source)
33
- rescue => e
34
- e
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,105 +1,110 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
- class Command::WatchExpression < Pry::ClassCommand
3
- require 'pry/commands/watch_expression/expression.rb'
4
-
5
- match 'watch'
6
- group 'Context'
7
- description 'Watch the value of an expression and print a notification whenever it changes.'
8
- command_options :use_prefix => false
9
-
10
- banner <<-'BANNER'
11
- Usage: watch [EXPRESSION]
12
- watch
13
- watch --delete [INDEX]
14
-
15
- watch [EXPRESSION] adds an expression to the list of those being watched.
16
- It will be re-evaluated every time you hit enter in pry. If its value has
17
- changed, the new value will be printed to the console.
18
-
19
- This is useful if you are step-through debugging and want to see how
20
- something changes over time. It's also useful if you're trying to write
21
- a method inside pry and want to check that it gives the right answers
22
- every time you redefine it.
23
-
24
- watch on its own displays all the currently watched expressions and their
25
- values, and watch --delete [INDEX] allows you to delete expressions from
26
- the list being watched.
27
- BANNER
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
- def process
38
- case
39
- when opts.present?(:delete)
40
- delete opts[:delete]
41
- when opts.present?(:list) || args.empty?
42
- list
43
- else
44
- add_hook
45
- add_expression(args)
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
- private
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
- def expressions
52
- _pry_.config.watch_expressions ||= []
53
- end
53
+ private
54
54
 
55
- def delete(index)
56
- if index
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
- def list
66
- if expressions.empty?
67
- output.puts "No watched expressions"
68
- else
69
- _pry_.pager.open do |pager|
70
- pager.puts "Listing all watched expressions:"
71
- pager.puts ""
72
- expressions.each_with_index do |expr, index|
73
- pager.print text.with_line_numbers(expr.to_s, index+1)
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
- def eval_and_print_changed(output)
81
- expressions.each do |expr|
82
- expr.eval!
83
- if expr.changed?
84
- output.puts "#{text.blue "watch"}: #{expr.to_s}"
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
- def add_expression(arguments)
90
- expressions << Expression.new(_pry_, target, arg_string)
91
- output.puts "Watching #{Code.new(arg_string).highlighted}"
92
- end
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 = %i[after_eval watch_expression]
100
+ return if pry_instance.hooks.hook_exists?(*hook)
93
101
 
94
- def add_hook
95
- hook = [:after_eval, :watch_expression]
96
- unless _pry_.hooks.hook_exists?(*hook)
97
- _pry_.hooks.add_hook(*hook) do |_, _pry_|
98
- eval_and_print_changed _pry_.output
102
+ pry_instance.hooks.add_hook(*hook) do |_, pry_instance|
103
+ eval_and_print_changed pry_instance.output
99
104
  end
100
105
  end
101
106
  end
102
- end
103
107
 
104
- Pry::Commands.add_command(Pry::Command::WatchExpression)
108
+ Pry::Commands.add_command(Pry::Command::WatchExpression)
109
+ end
105
110
  end