pry 0.10.4 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -16
  3. data/LICENSE +1 -1
  4. data/README.md +352 -306
  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 +81 -74
  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 +48 -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 +24 -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 +81 -70
  73. data/lib/pry/commands/show_info.rb +193 -160
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +109 -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 +155 -146
  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 +317 -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 +53 -33
  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 +20 -12
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +60 -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 +72 -66
  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 +177 -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 -177
  117. data/lib/pry/plugins.rb +49 -13
  118. data/lib/pry/prompt.rb +213 -25
  119. data/lib/pry/pry_class.rb +106 -93
  120. data/lib/pry/pry_instance.rb +261 -224
  121. data/lib/pry/repl.rb +82 -27
  122. data/lib/pry/repl_file_loader.rb +27 -22
  123. data/lib/pry/ring.rb +89 -0
  124. data/lib/pry/slop/LICENSE +20 -0
  125. data/lib/pry/slop/commands.rb +190 -0
  126. data/lib/pry/slop/option.rb +210 -0
  127. data/lib/pry/slop.rb +672 -0
  128. data/lib/pry/syntax_highlighter.rb +26 -0
  129. data/lib/pry/system_command_handler.rb +17 -0
  130. data/lib/pry/testable/evalable.rb +24 -0
  131. data/lib/pry/testable/mockable.rb +22 -0
  132. data/lib/pry/testable/pry_tester.rb +88 -0
  133. data/lib/pry/testable/utility.rb +34 -0
  134. data/lib/pry/testable/variables.rb +52 -0
  135. data/lib/pry/testable.rb +68 -0
  136. data/lib/pry/version.rb +3 -1
  137. data/lib/pry/warning.rb +27 -0
  138. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +28 -27
  139. data/lib/pry/wrapped_module.rb +66 -57
  140. data/lib/pry.rb +134 -149
  141. metadata +49 -59
  142. data/lib/pry/commands/disabled_commands.rb +0 -2
  143. data/lib/pry/commands/gem_cd.rb +0 -26
  144. data/lib/pry/commands/gem_install.rb +0 -32
  145. data/lib/pry/commands/gem_list.rb +0 -33
  146. data/lib/pry/commands/gem_open.rb +0 -29
  147. data/lib/pry/commands/gist.rb +0 -101
  148. data/lib/pry/commands/install_command.rb +0 -53
  149. data/lib/pry/commands/list_prompts.rb +0 -35
  150. data/lib/pry/commands/simple_prompt.rb +0 -22
  151. data/lib/pry/commands.rb +0 -6
  152. data/lib/pry/config/behavior.rb +0 -139
  153. data/lib/pry/config/convenience.rb +0 -25
  154. data/lib/pry/config/default.rb +0 -161
  155. data/lib/pry/history_array.rb +0 -121
  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,117 @@
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
+ end
50
117
  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 = [: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