super-smart-mod 0.0.1

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 (143) hide show
  1. checksums.yaml +7 -0
  2. data/pry-0.16.0/CHANGELOG.md +1211 -0
  3. data/pry-0.16.0/LICENSE +25 -0
  4. data/pry-0.16.0/README.md +469 -0
  5. data/pry-0.16.0/bin/pry +13 -0
  6. data/pry-0.16.0/lib/pry/basic_object.rb +10 -0
  7. data/pry-0.16.0/lib/pry/block_command.rb +22 -0
  8. data/pry-0.16.0/lib/pry/class_command.rb +194 -0
  9. data/pry-0.16.0/lib/pry/cli.rb +211 -0
  10. data/pry-0.16.0/lib/pry/code/code_file.rb +114 -0
  11. data/pry-0.16.0/lib/pry/code/code_range.rb +73 -0
  12. data/pry-0.16.0/lib/pry/code/loc.rb +105 -0
  13. data/pry-0.16.0/lib/pry/code.rb +357 -0
  14. data/pry-0.16.0/lib/pry/code_object.rb +197 -0
  15. data/pry-0.16.0/lib/pry/color_printer.rb +66 -0
  16. data/pry-0.16.0/lib/pry/command.rb +520 -0
  17. data/pry-0.16.0/lib/pry/command_set.rb +418 -0
  18. data/pry-0.16.0/lib/pry/command_state.rb +36 -0
  19. data/pry-0.16.0/lib/pry/commands/amend_line.rb +103 -0
  20. data/pry-0.16.0/lib/pry/commands/bang.rb +24 -0
  21. data/pry-0.16.0/lib/pry/commands/bang_pry.rb +21 -0
  22. data/pry-0.16.0/lib/pry/commands/cat/abstract_formatter.rb +32 -0
  23. data/pry-0.16.0/lib/pry/commands/cat/exception_formatter.rb +90 -0
  24. data/pry-0.16.0/lib/pry/commands/cat/file_formatter.rb +77 -0
  25. data/pry-0.16.0/lib/pry/commands/cat/input_expression_formatter.rb +48 -0
  26. data/pry-0.16.0/lib/pry/commands/cat.rb +70 -0
  27. data/pry-0.16.0/lib/pry/commands/cd.rb +48 -0
  28. data/pry-0.16.0/lib/pry/commands/change_inspector.rb +34 -0
  29. data/pry-0.16.0/lib/pry/commands/change_prompt.rb +51 -0
  30. data/pry-0.16.0/lib/pry/commands/clear_screen.rb +20 -0
  31. data/pry-0.16.0/lib/pry/commands/code_collector.rb +182 -0
  32. data/pry-0.16.0/lib/pry/commands/disable_pry.rb +31 -0
  33. data/pry-0.16.0/lib/pry/commands/easter_eggs.rb +101 -0
  34. data/pry-0.16.0/lib/pry/commands/edit/exception_patcher.rb +29 -0
  35. data/pry-0.16.0/lib/pry/commands/edit/file_and_line_locator.rb +47 -0
  36. data/pry-0.16.0/lib/pry/commands/edit.rb +225 -0
  37. data/pry-0.16.0/lib/pry/commands/exit.rb +47 -0
  38. data/pry-0.16.0/lib/pry/commands/exit_all.rb +33 -0
  39. data/pry-0.16.0/lib/pry/commands/exit_program.rb +27 -0
  40. data/pry-0.16.0/lib/pry/commands/find_method.rb +199 -0
  41. data/pry-0.16.0/lib/pry/commands/fix_indent.rb +23 -0
  42. data/pry-0.16.0/lib/pry/commands/help.rb +171 -0
  43. data/pry-0.16.0/lib/pry/commands/hist.rb +182 -0
  44. data/pry-0.16.0/lib/pry/commands/import_set.rb +27 -0
  45. data/pry-0.16.0/lib/pry/commands/jump_to.rb +33 -0
  46. data/pry-0.16.0/lib/pry/commands/list_inspectors.rb +42 -0
  47. data/pry-0.16.0/lib/pry/commands/ls/config.rb +54 -0
  48. data/pry-0.16.0/lib/pry/commands/ls/constants.rb +75 -0
  49. data/pry-0.16.0/lib/pry/commands/ls/formatter.rb +55 -0
  50. data/pry-0.16.0/lib/pry/commands/ls/globals.rb +50 -0
  51. data/pry-0.16.0/lib/pry/commands/ls/grep.rb +23 -0
  52. data/pry-0.16.0/lib/pry/commands/ls/instance_vars.rb +40 -0
  53. data/pry-0.16.0/lib/pry/commands/ls/interrogatable.rb +24 -0
  54. data/pry-0.16.0/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  55. data/pry-0.16.0/lib/pry/commands/ls/local_names.rb +37 -0
  56. data/pry-0.16.0/lib/pry/commands/ls/local_vars.rb +47 -0
  57. data/pry-0.16.0/lib/pry/commands/ls/ls_entity.rb +65 -0
  58. data/pry-0.16.0/lib/pry/commands/ls/methods.rb +55 -0
  59. data/pry-0.16.0/lib/pry/commands/ls/methods_helper.rb +50 -0
  60. data/pry-0.16.0/lib/pry/commands/ls/self_methods.rb +34 -0
  61. data/pry-0.16.0/lib/pry/commands/ls.rb +114 -0
  62. data/pry-0.16.0/lib/pry/commands/nesting.rb +29 -0
  63. data/pry-0.16.0/lib/pry/commands/play.rb +113 -0
  64. data/pry-0.16.0/lib/pry/commands/pry_backtrace.rb +30 -0
  65. data/pry-0.16.0/lib/pry/commands/pry_version.rb +21 -0
  66. data/pry-0.16.0/lib/pry/commands/raise_up.rb +38 -0
  67. data/pry-0.16.0/lib/pry/commands/reload_code.rb +74 -0
  68. data/pry-0.16.0/lib/pry/commands/reset.rb +22 -0
  69. data/pry-0.16.0/lib/pry/commands/ri.rb +75 -0
  70. data/pry-0.16.0/lib/pry/commands/save_file.rb +63 -0
  71. data/pry-0.16.0/lib/pry/commands/shell_command.rb +75 -0
  72. data/pry-0.16.0/lib/pry/commands/shell_mode.rb +30 -0
  73. data/pry-0.16.0/lib/pry/commands/show_doc.rb +84 -0
  74. data/pry-0.16.0/lib/pry/commands/show_info.rb +234 -0
  75. data/pry-0.16.0/lib/pry/commands/show_input.rb +22 -0
  76. data/pry-0.16.0/lib/pry/commands/show_source.rb +57 -0
  77. data/pry-0.16.0/lib/pry/commands/stat.rb +44 -0
  78. data/pry-0.16.0/lib/pry/commands/switch_to.rb +29 -0
  79. data/pry-0.16.0/lib/pry/commands/toggle_color.rb +28 -0
  80. data/pry-0.16.0/lib/pry/commands/watch_expression/expression.rb +43 -0
  81. data/pry-0.16.0/lib/pry/commands/watch_expression.rb +108 -0
  82. data/pry-0.16.0/lib/pry/commands/whereami.rb +205 -0
  83. data/pry-0.16.0/lib/pry/commands/wtf.rb +95 -0
  84. data/pry-0.16.0/lib/pry/config/attributable.rb +22 -0
  85. data/pry-0.16.0/lib/pry/config/lazy_value.rb +29 -0
  86. data/pry-0.16.0/lib/pry/config/memoized_value.rb +34 -0
  87. data/pry-0.16.0/lib/pry/config/value.rb +24 -0
  88. data/pry-0.16.0/lib/pry/config.rb +321 -0
  89. data/pry-0.16.0/lib/pry/control_d_handler.rb +28 -0
  90. data/pry-0.16.0/lib/pry/core_extensions.rb +144 -0
  91. data/pry-0.16.0/lib/pry/editor.rb +157 -0
  92. data/pry-0.16.0/lib/pry/env.rb +18 -0
  93. data/pry-0.16.0/lib/pry/exception_handler.rb +48 -0
  94. data/pry-0.16.0/lib/pry/exceptions.rb +73 -0
  95. data/pry-0.16.0/lib/pry/forwardable.rb +27 -0
  96. data/pry-0.16.0/lib/pry/helpers/base_helpers.rb +71 -0
  97. data/pry-0.16.0/lib/pry/helpers/command_helpers.rb +146 -0
  98. data/pry-0.16.0/lib/pry/helpers/documentation_helpers.rb +84 -0
  99. data/pry-0.16.0/lib/pry/helpers/options_helpers.rb +34 -0
  100. data/pry-0.16.0/lib/pry/helpers/platform.rb +55 -0
  101. data/pry-0.16.0/lib/pry/helpers/table.rb +121 -0
  102. data/pry-0.16.0/lib/pry/helpers/text.rb +118 -0
  103. data/pry-0.16.0/lib/pry/helpers.rb +8 -0
  104. data/pry-0.16.0/lib/pry/history.rb +153 -0
  105. data/pry-0.16.0/lib/pry/hooks.rb +180 -0
  106. data/pry-0.16.0/lib/pry/indent.rb +414 -0
  107. data/pry-0.16.0/lib/pry/input/simple_stdio.rb +13 -0
  108. data/pry-0.16.0/lib/pry/input_completer.rb +283 -0
  109. data/pry-0.16.0/lib/pry/input_lock.rb +129 -0
  110. data/pry-0.16.0/lib/pry/inspector.rb +39 -0
  111. data/pry-0.16.0/lib/pry/last_exception.rb +61 -0
  112. data/pry-0.16.0/lib/pry/method/disowned.rb +67 -0
  113. data/pry-0.16.0/lib/pry/method/patcher.rb +131 -0
  114. data/pry-0.16.0/lib/pry/method/weird_method_locator.rb +222 -0
  115. data/pry-0.16.0/lib/pry/method.rb +599 -0
  116. data/pry-0.16.0/lib/pry/object_path.rb +91 -0
  117. data/pry-0.16.0/lib/pry/output.rb +136 -0
  118. data/pry-0.16.0/lib/pry/pager.rb +249 -0
  119. data/pry-0.16.0/lib/pry/prompt.rb +214 -0
  120. data/pry-0.16.0/lib/pry/pry_class.rb +371 -0
  121. data/pry-0.16.0/lib/pry/pry_instance.rb +663 -0
  122. data/pry-0.16.0/lib/pry/repl.rb +326 -0
  123. data/pry-0.16.0/lib/pry/repl_file_loader.rb +79 -0
  124. data/pry-0.16.0/lib/pry/ring.rb +89 -0
  125. data/pry-0.16.0/lib/pry/slop/LICENSE +20 -0
  126. data/pry-0.16.0/lib/pry/slop/commands.rb +190 -0
  127. data/pry-0.16.0/lib/pry/slop/option.rb +210 -0
  128. data/pry-0.16.0/lib/pry/slop.rb +672 -0
  129. data/pry-0.16.0/lib/pry/syntax_highlighter.rb +26 -0
  130. data/pry-0.16.0/lib/pry/system_command_handler.rb +17 -0
  131. data/pry-0.16.0/lib/pry/testable/evalable.rb +24 -0
  132. data/pry-0.16.0/lib/pry/testable/mockable.rb +22 -0
  133. data/pry-0.16.0/lib/pry/testable/pry_tester.rb +88 -0
  134. data/pry-0.16.0/lib/pry/testable/utility.rb +34 -0
  135. data/pry-0.16.0/lib/pry/testable/variables.rb +52 -0
  136. data/pry-0.16.0/lib/pry/testable.rb +68 -0
  137. data/pry-0.16.0/lib/pry/version.rb +5 -0
  138. data/pry-0.16.0/lib/pry/warning.rb +20 -0
  139. data/pry-0.16.0/lib/pry/wrapped_module/candidate.rb +145 -0
  140. data/pry-0.16.0/lib/pry/wrapped_module.rb +382 -0
  141. data/pry-0.16.0/lib/pry.rb +148 -0
  142. data/super-smart-mod.gemspec +12 -0
  143. metadata +182 -0
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ShowDoc < Command::ShowInfo
6
+ include Pry::Helpers::DocumentationHelpers
7
+
8
+ match 'show-doc'
9
+ group 'Introspection'
10
+ description 'Show the documentation for a method or class.'
11
+
12
+ banner <<-BANNER
13
+ Usage: show-doc [OPTIONS] [METH]
14
+ Aliases: ?
15
+
16
+ Show the documentation for a method or class. Tries instance methods first and
17
+ then methods by default.
18
+
19
+ show-doc hi_method # docs for hi_method
20
+ show-doc Pry # for Pry class
21
+ show-doc Pry -a # for all definitions of Pry class (all monkey patches)
22
+ BANNER
23
+
24
+ # The docs for code_object prepared for display.
25
+ def content_for(code_object)
26
+ Code.new(
27
+ render_doc_markup_for(code_object),
28
+ start_line_for(code_object),
29
+ :text
30
+ ).with_line_numbers(use_line_numbers?).to_s
31
+ end
32
+
33
+ # process the markup (if necessary) and apply colors
34
+ def render_doc_markup_for(code_object)
35
+ docs = docs_for(code_object)
36
+
37
+ if code_object.command?
38
+ # command '--help' shouldn't use markup highlighting
39
+ docs
40
+ else
41
+ if docs.empty?
42
+ raise CommandError, "No docs found for: #{obj_name || 'current context'}"
43
+ end
44
+
45
+ process_comment_markup(docs)
46
+ end
47
+ end
48
+
49
+ # Return docs for the code_object, adjusting for whether the code_object
50
+ # has yard docs available, in which case it returns those.
51
+ # (note we only have to check yard docs for modules since they can
52
+ # have multiple docs, but methods can only be doc'd once so we
53
+ # dont need to check them)
54
+ def docs_for(code_object)
55
+ if code_object.module_with_yard_docs?
56
+ # yard docs
57
+ code_object.yard_doc
58
+ else
59
+ # normal docs (i.e comments above method/module/command)
60
+ code_object.doc
61
+ end
62
+ end
63
+
64
+ # Which sections to include in the 'header', can toggle: :owner,
65
+ # :signature and visibility.
66
+ def header_options
67
+ super.merge signature: true
68
+ end
69
+
70
+ # figure out start line of docs by back-calculating based on
71
+ # number of lines in the comment and the start line of the code_object
72
+ # @return [Fixnum] start line of docs
73
+ def start_line_for(code_object)
74
+ return 1 if code_object.command? || opts.present?(:'base-one')
75
+ return 1 unless code_object.source_line
76
+
77
+ code_object.source_line - code_object.doc.lines.count
78
+ end
79
+ end
80
+
81
+ Pry::Commands.add_command(Pry::Command::ShowDoc)
82
+ Pry::Commands.alias_command '?', 'show-doc'
83
+ end
84
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ShowInfo < Pry::ClassCommand
6
+ extend Pry::Helpers::BaseHelpers
7
+
8
+ command_options shellwords: false, interpolate: false
9
+
10
+ def initialize(*)
11
+ super
12
+
13
+ @used_super = nil
14
+ end
15
+
16
+ def options(opt)
17
+ opt.on :s, :super, "Select the 'super' method. Can be repeated to " \
18
+ "traverse the ancestors", as: :count
19
+ opt.on :l, "line-numbers", "Show line numbers"
20
+ opt.on :b, "base-one", "Show line numbers but start numbering at 1 " \
21
+ "(useful for `amend-line` and `play` commands)"
22
+ opt.on :a, :all, "Show all definitions and monkeypatches of the " \
23
+ "module/class"
24
+ end
25
+
26
+ def process
27
+ code_object = Pry::CodeObject.lookup(obj_name, pry_instance, super: opts[:super])
28
+ raise CommandError, no_definition_message unless code_object
29
+
30
+ @original_code_object = code_object
31
+
32
+ if !obj_name && code_object.c_module? && !opts[:all]
33
+ result = "You're inside an object, whose class is defined by means of " \
34
+ "the C Ruby API.\nPry cannot display the information for this " \
35
+ "class."
36
+ if code_object.candidates.any?
37
+ result += "\nHowever, you can view monkey-patches applied to this " \
38
+ "class.\n.Just execute the same command with the '--all' " \
39
+ "switch."
40
+ end
41
+ elsif show_all_modules?(code_object)
42
+ # show all monkey patches for a module
43
+
44
+ result = content_and_headers_for_all_module_candidates(code_object)
45
+ else
46
+ # show a specific code object
47
+ co = code_object_with_accessible_source(code_object)
48
+ result = content_and_header_for_code_object(co)
49
+ end
50
+
51
+ set_file_and_dir_locals(code_object.source_file)
52
+ pry_instance.pager.page result
53
+ end
54
+
55
+ # This method checks whether the `code_object` is a WrappedModule, if it
56
+ # is, then it returns the first candidate (monkeypatch) with accessible
57
+ # source (or docs). If `code_object` is not a WrappedModule (i.e a method
58
+ # or a command) then the `code_object` itself is just returned.
59
+ #
60
+ # @return [Pry::WrappedModule, Pry::Method, Pry::Command]
61
+ def code_object_with_accessible_source(code_object)
62
+ return code_object unless code_object.is_a?(WrappedModule)
63
+
64
+ candidate = code_object.candidates.find(&:source)
65
+ return candidate if candidate
66
+
67
+ raise CommandError, no_definition_message unless valid_superclass?(code_object)
68
+
69
+ @used_super = true
70
+ code_object_with_accessible_source(code_object.super)
71
+ end
72
+
73
+ def valid_superclass?(code_object)
74
+ code_object.super && code_object.super.wrapped != Object
75
+ end
76
+
77
+ def content_and_header_for_code_object(code_object)
78
+ header(code_object) + content_for(code_object)
79
+ end
80
+
81
+ def content_and_headers_for_all_module_candidates(mod)
82
+ result = "Found #{mod.number_of_candidates} candidates for " \
83
+ "`#{mod.name}` definition:\n"
84
+ mod.number_of_candidates.times do |v|
85
+ candidate = mod.candidate(v)
86
+ begin
87
+ result += "\nCandidate #{v + 1}/#{mod.number_of_candidates}: " \
88
+ "#{candidate.source_file}:#{candidate.source_line}\n"
89
+ content = content_for(candidate)
90
+
91
+ result += "Number of lines: #{content.lines.count}\n\n" + content
92
+ rescue Pry::RescuableException
93
+ result += "\nNo content found.\n"
94
+ next
95
+ end
96
+ end
97
+ result
98
+ end
99
+
100
+ def no_definition_message
101
+ "Couldn't locate a definition for #{obj_name}"
102
+ end
103
+
104
+ # Generate a header (meta-data information) for all the code
105
+ # object types: methods, modules, commands, procs...
106
+ def header(code_object)
107
+ file_name, line_num = file_and_line_for(code_object)
108
+ content = content_for(code_object)
109
+
110
+ h = "\n#{bold('From:')} #{file_name}"
111
+ h += code_object_header(code_object, line_num)
112
+ h += "\n#{bold('Number of lines:')} " + "#{content.lines.count}\n\n"
113
+ if @used_super
114
+ h += bold('** Warning:')
115
+ h += " Cannot find code for #{@original_code_object.nonblank_name}. " \
116
+ "Showing superclass #{code_object.nonblank_name} instead. **\n\n"
117
+ end
118
+
119
+ if content.lines.none?
120
+ h += bold('** Warning:')
121
+ h += " Cannot find code for '#{code_object.name}' (source_location is nil)"
122
+ end
123
+
124
+ h
125
+ end
126
+
127
+ def code_object_header(code_object, line_num)
128
+ if code_object.real_method_object?
129
+ method_header(code_object, line_num)
130
+
131
+ # It sucks we have to test for both Pry::WrappedModule and
132
+ # WrappedModule::Candidate, probably indicates a deep refactor needs
133
+ # to happen in those classes.
134
+ elsif code_object.is_a?(Pry::WrappedModule) ||
135
+ code_object.is_a?(Pry::WrappedModule::Candidate)
136
+ module_header(code_object, line_num)
137
+ else
138
+ ""
139
+ end
140
+ end
141
+
142
+ def method_header(code_object, line_num)
143
+ h = ""
144
+ h += (code_object.c_method? ? ' (C Method):' : ":#{line_num}:")
145
+ h += method_sections(code_object)[:owner]
146
+ h += method_sections(code_object)[:visibility]
147
+ h += method_sections(code_object)[:signature]
148
+ h
149
+ end
150
+
151
+ def module_header(code_object, line_num)
152
+ h = ""
153
+ h += ":#{line_num}\n"
154
+ h += bold(code_object.module? ? "Module" : "Class")
155
+ h += " #{bold('name:')} #{code_object.nonblank_name}"
156
+
157
+ if code_object.number_of_candidates > 1
158
+ h += bold("\nNumber of monkeypatches: ")
159
+ h += code_object.number_of_candidates.to_s
160
+ h += ". Use the `-a` option to display all available monkeypatches"
161
+ end
162
+ h
163
+ end
164
+
165
+ def method_sections(code_object)
166
+ {
167
+ owner: "\n#{bold('Owner:')} #{code_object.owner || 'N/A'}\n",
168
+ visibility: "#{bold('Visibility:')} #{code_object.visibility}",
169
+ signature: "\n#{bold('Signature:')} #{code_object.signature}"
170
+ }.merge(header_options) { |_key, old, new| (new && old).to_s }
171
+ end
172
+
173
+ def header_options
174
+ {
175
+ owner: true,
176
+ visibility: true,
177
+ signature: nil
178
+ }
179
+ end
180
+
181
+ def show_all_modules?(code_object)
182
+ code_object.is_a?(Pry::WrappedModule) && opts.present?(:all)
183
+ end
184
+
185
+ def obj_name
186
+ @obj_name ||= args.empty? ? nil : args.join(' ')
187
+ end
188
+
189
+ def use_line_numbers?
190
+ opts.present?(:b) || opts.present?(:l)
191
+ end
192
+
193
+ def start_line_for(code_object)
194
+ if opts.present?(:'base-one')
195
+ 1
196
+ else
197
+ code_object.source_line || 1
198
+ end
199
+ end
200
+
201
+ # takes into account possible yard docs, and returns yard_file / yard_line
202
+ # Also adjusts for start line of comments (using start_line_for), which it
203
+ # has to infer by subtracting number of lines of comment from start line
204
+ # of code_object
205
+ def file_and_line_for(code_object)
206
+ if code_object.module_with_yard_docs?
207
+ [code_object.yard_file, code_object.yard_line]
208
+ else
209
+ [code_object.source_file, start_line_for(code_object)]
210
+ end
211
+ end
212
+
213
+ def complete(input)
214
+ if input =~ /([^ ]*)#([a-z0-9_]*)\z/
215
+ prefix = Regexp.last_match(1)
216
+ search = Regexp.last_match(2)
217
+ methods =
218
+ begin
219
+ # rubocop:disable Security/Eval
220
+ Pry::Method.all_from_class(binding.eval(prefix))
221
+ # rubocop:enable Security/Eval
222
+ rescue RescuableException
223
+ return super
224
+ end
225
+ methods.map do |method|
226
+ [prefix, method.name].join('#') if method.name.start_with?(search)
227
+ end.compact
228
+ else
229
+ super
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ShowInput < Pry::ClassCommand
6
+ match 'show-input'
7
+ group 'Editing'
8
+ description 'Show the contents of the input buffer for the current ' \
9
+ 'multi-line expression.'
10
+
11
+ banner <<-'BANNER'
12
+ Show the contents of the input buffer for the current multi-line expression.
13
+ BANNER
14
+
15
+ def process
16
+ output.puts Code.new(eval_string).with_line_numbers
17
+ end
18
+ end
19
+
20
+ Pry::Commands.add_command(Pry::Command::ShowInput)
21
+ end
22
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ShowSource < Command::ShowInfo
6
+ match 'show-source'
7
+ group 'Introspection'
8
+ description 'Show the source for a method or class.'
9
+
10
+ banner <<-'BANNER'
11
+ Usage: show-source [OPTIONS] [METH|CLASS]
12
+ Aliases: $, show-method
13
+
14
+ Show the source for a method or class. Tries instance methods first and then
15
+ methods by default.
16
+
17
+ show-source hi_method
18
+ show-source hi_method
19
+ show-source Pry#rep # source for Pry#rep method
20
+ show-source Pry # for Pry class
21
+ show-source Pry -a # for all Pry class definitions (all monkey patches)
22
+ show-source Pry.foo -e # for class of the return value of expression `Pry.foo`
23
+ show-source Pry --super # for superclass of Pry (Object class)
24
+
25
+ https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method
26
+ BANNER
27
+
28
+ def options(opt)
29
+ opt.on :e, :eval, "evaluate the command's argument as a ruby " \
30
+ "expression and show the class its return value"
31
+ super(opt)
32
+ end
33
+
34
+ def process
35
+ if opts.present?(:e)
36
+ obj = target.eval(args.first)
37
+ self.args = Array.new(1) { obj.is_a?(Module) ? obj.name : obj.class.name }
38
+ end
39
+
40
+ super
41
+ end
42
+
43
+ # The source for code_object prepared for display.
44
+ def content_for(code_object)
45
+ code = Code.new(
46
+ code_object.source || [],
47
+ start_line_for(code_object)
48
+ )
49
+ code.with_line_numbers(use_line_numbers?).highlighted
50
+ end
51
+ end
52
+
53
+ Pry::Commands.add_command(Pry::Command::ShowSource)
54
+ Pry::Commands.alias_command 'show-method', 'show-source'
55
+ Pry::Commands.alias_command '$', 'show-source'
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
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
10
+
11
+ banner <<-'BANNER'
12
+ Usage: stat [OPTIONS] [METH]
13
+
14
+ Show method information for method METH and set _file_ and _dir_ locals.
15
+
16
+ stat hello_method
17
+ BANNER
18
+
19
+ def options(opt)
20
+ method_options(opt)
21
+ end
22
+
23
+ def process
24
+ meth = method_object
25
+ aliases = meth.aliases
26
+
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
40
+ end
41
+
42
+ Pry::Commands.add_command(Pry::Command::Stat)
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
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.'
9
+
10
+ banner <<-'BANNER'
11
+ Start a new subsession on a binding in the current stack (numbered by nesting).
12
+ BANNER
13
+
14
+ def process(selection)
15
+ selection = selection.to_i
16
+
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
24
+ end
25
+ end
26
+
27
+ Pry::Commands.add_command(Pry::Command::SwitchTo)
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ToggleColor < Pry::ClassCommand
6
+ match 'toggle-color'
7
+ group 'Misc'
8
+ description 'Toggle syntax highlighting.'
9
+
10
+ banner <<-'BANNER'
11
+ Usage: toggle-color
12
+
13
+ Toggle syntax highlighting.
14
+ BANNER
15
+
16
+ def process
17
+ pry_instance.color = color_toggle
18
+ output.puts "Syntax highlighting #{pry_instance.color ? 'on' : 'off'}"
19
+ end
20
+
21
+ def color_toggle
22
+ !pry_instance.color
23
+ end
24
+
25
+ Pry::Commands.add_command(self)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class WatchExpression
6
+ class Expression
7
+ attr_reader :target, :source, :value, :previous_value, :pry_instance
8
+
9
+ def initialize(pry_instance, target, source)
10
+ @pry_instance = pry_instance
11
+ @target = target
12
+ @source = Code.new(source).strip
13
+ end
14
+
15
+ def eval!
16
+ @previous_value = value
17
+ @value = Pry::ColorPrinter.pp(target_eval(target, source), ''.dup)
18
+ end
19
+
20
+ def to_s
21
+ "#{Code.new(source).highlighted.strip} => #{value}"
22
+ end
23
+
24
+ # Has the value of the expression changed?
25
+ #
26
+ # We use the pretty-printed string representation 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
32
+
33
+ private
34
+
35
+ def target_eval(target, source)
36
+ target.eval(source)
37
+ rescue StandardError => e
38
+ e
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
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, state: %i[watch_expressions]
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
30
+
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."
40
+ end
41
+
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
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def expressions
56
+ state.watch_expressions ||= []
57
+ end
58
+
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 ""
80
+ end
81
+ end
82
+ end
83
+
84
+ def eval_and_print_changed(output)
85
+ expressions.each do |expr|
86
+ expr.eval!
87
+ output.puts "#{blue 'watch'}: #{expr}" if expr.changed?
88
+ end
89
+ end
90
+
91
+ def add_expression
92
+ expressions << Expression.new(pry_instance, target, arg_string)
93
+ output.puts "Watching #{Code.new(arg_string).highlighted}"
94
+ end
95
+
96
+ def add_hook
97
+ hook = %i[after_eval watch_expression]
98
+ return if pry_instance.hooks.hook_exists?(*hook)
99
+
100
+ pry_instance.hooks.add_hook(*hook) do |_, pry_instance|
101
+ eval_and_print_changed pry_instance.output
102
+ end
103
+ end
104
+ end
105
+
106
+ Pry::Commands.add_command(Pry::Command::WatchExpression)
107
+ end
108
+ end