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,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class FindMethod < Pry::ClassCommand
6
+ extend Pry::Helpers::BaseHelpers
7
+
8
+ match 'find-method'
9
+ group 'Context'
10
+ description 'Recursively search for a method within a Class/Module or ' \
11
+ 'the current namespace.'
12
+ command_options shellwords: false
13
+
14
+ banner <<-'BANNER'
15
+ Usage: find-method [-n|-c] METHOD [NAMESPACE]
16
+
17
+ Recursively search for a method within a Class/Module or the current namespace.
18
+ Use the `-n` switch (the default) to search for methods whose name matches the
19
+ given regex. Use the `-c` switch to search for methods that contain the given
20
+ code.
21
+
22
+ # Find all methods whose name match /re/ inside
23
+ # the Pry namespace. Matches Pry#repl, etc.
24
+ find-method re Pry
25
+
26
+ # Find all methods that contain the code:
27
+ # output.puts inside the Pry namespace.
28
+ find-method -c 'output.puts' Pry
29
+ BANNER
30
+
31
+ def options(opt)
32
+ opt.on :n, :name, "Search for a method by name"
33
+ opt.on :c, :content, "Search for a method based on content in Regex form"
34
+ end
35
+
36
+ def process
37
+ return if args.empty?
38
+
39
+ klass = search_class
40
+
41
+ matches = opts.content? ? content_search(klass) : name_search(klass)
42
+ show_search_results(matches)
43
+ end
44
+
45
+ private
46
+
47
+ # @return [Regexp] The pattern to search for.
48
+ def pattern
49
+ @pattern ||= ::Regexp.new args[0]
50
+ end
51
+
52
+ # Output the result of the search.
53
+ #
54
+ # @param [Array] matches
55
+ def show_search_results(matches)
56
+ if matches.empty?
57
+ output.puts bold("No Methods Matched")
58
+ else
59
+ print_matches(matches)
60
+ end
61
+ end
62
+
63
+ # The class to search for methods.
64
+ # We only search classes, so if the search object is an
65
+ # instance, return its class. If no search object is given
66
+ # search `target_self`.
67
+ def search_class
68
+ klass = if args[1]
69
+ target.eval(args[1])
70
+ else
71
+ target_self
72
+ end
73
+
74
+ klass.is_a?(Module) ? klass : klass.class
75
+ end
76
+
77
+ # pretty-print a list of matching methods.
78
+ #
79
+ # @param [Array<Method>] matches
80
+ def print_matches(matches)
81
+ grouped = matches.group_by(&:owner)
82
+ order = grouped.keys.sort_by { |x| x.name || x.to_s }
83
+
84
+ order.each do |klass|
85
+ print_matches_for_class(klass, grouped)
86
+ end
87
+ end
88
+
89
+ # Print matched methods for a class
90
+ def print_matches_for_class(klass, grouped)
91
+ output.puts bold(klass.name)
92
+ grouped[klass].each do |method|
93
+ header = method.name_with_owner
94
+ output.puts header + additional_info(header, method)
95
+ end
96
+ end
97
+
98
+ # Return the matched lines of method source if `-c` is given or ""
99
+ # if `-c` was not given
100
+ def additional_info(header, method)
101
+ if opts.content?
102
+ ': ' + colorize_code(matched_method_lines(header, method))
103
+ else
104
+ ""
105
+ end
106
+ end
107
+
108
+ def matched_method_lines(header, method)
109
+ method.source.split(/\n/).select { |x| x =~ pattern }.join(
110
+ "\n#{' ' * header.length}"
111
+ )
112
+ end
113
+
114
+ # Run the given block against every constant in the provided namespace.
115
+ #
116
+ # @param [Module] klass The namespace in which to start the search.
117
+ # @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
118
+ # @yieldparam klass Each class/module in the namespace.
119
+ #
120
+ def recurse_namespace(klass, done = {}, &block)
121
+ return if !klass.is_a?(Module) || done[klass]
122
+
123
+ done[klass] = true
124
+
125
+ yield klass
126
+
127
+ klass.constants.each do |name|
128
+ next if klass.autoload?(name)
129
+
130
+ begin
131
+ const = Pry::Method.singleton_class_of(klass.const_get(name))
132
+ rescue RescuableException # rubocop:disable Lint/HandleExceptions
133
+ # constant loading is an inexact science at the best of times,
134
+ # this often happens when a constant was .autoload? but someone
135
+ # tried to load it. It's now not .autoload? but will still raise
136
+ # a NameError when you access it.
137
+ else
138
+ recurse_namespace(const, done, &block)
139
+ end
140
+ end
141
+ end
142
+
143
+ # Gather all the methods in a namespace that pass the given block.
144
+ #
145
+ # @param [Module] namespace The namespace in which to search.
146
+ # @yieldparam [Method] method The method to test
147
+ # @yieldreturn [Boolean]
148
+ # @return [Array<Method>]
149
+ #
150
+ def search_all_methods(namespace)
151
+ done = Hash.new { |h, k| h[k] = {} }
152
+ matches = []
153
+
154
+ recurse_namespace(namespace) do |klass|
155
+ methods = Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)
156
+ methods.each do |method|
157
+ next if done[method.owner][method.name]
158
+
159
+ done[method.owner][method.name] = true
160
+
161
+ matches << method if yield method
162
+ end
163
+ end
164
+
165
+ matches
166
+ end
167
+
168
+ # Search for all methods with a name that matches the given regex
169
+ # within a namespace.
170
+ #
171
+ # @param [Module] namespace The namespace to search
172
+ # @return [Array<Method>]
173
+ #
174
+ def name_search(namespace)
175
+ search_all_methods(namespace) do |meth|
176
+ meth.name =~ pattern
177
+ end
178
+ end
179
+
180
+ # Search for all methods who's implementation matches the given regex
181
+ # within a namespace.
182
+ #
183
+ # @param [Module] namespace The namespace to search
184
+ # @return [Array<Method>]
185
+ #
186
+ def content_search(namespace)
187
+ search_all_methods(namespace) do |meth|
188
+ begin
189
+ meth.source =~ pattern
190
+ rescue RescuableException
191
+ false
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ Pry::Commands.add_command(Pry::Command::FindMethod)
198
+ end
199
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class FixIndent < Pry::ClassCommand
6
+ match 'fix-indent'
7
+ group 'Input and Output'
8
+
9
+ description "Correct the indentation for contents of the input buffer"
10
+
11
+ banner <<-USAGE
12
+ Usage: fix-indent
13
+ USAGE
14
+
15
+ def process
16
+ indented_str = Pry::Indent.indent(eval_string)
17
+ pry_instance.eval_string = indented_str
18
+ end
19
+ end
20
+
21
+ Pry::Commands.add_command(Pry::Command::FixIndent)
22
+ end
23
+ end
@@ -0,0 +1,171 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class Help < Pry::ClassCommand
6
+ match 'help'
7
+ group 'Help'
8
+ description 'Show a list of commands or information about a specific command.'
9
+
10
+ banner <<-'BANNER'
11
+ Usage: help [COMMAND]
12
+
13
+ With no arguments, help lists all the available commands along with their
14
+ descriptions. When given a command name as an argument, shows the help
15
+ for that command.
16
+ BANNER
17
+
18
+ # We only want to show commands that have descriptions, so that the
19
+ # easter eggs don't show up.
20
+ def visible_commands
21
+ visible = {}
22
+ commands.each do |key, command|
23
+ visible[key] = command if command.description && !command.description.empty?
24
+ end
25
+ visible
26
+ end
27
+
28
+ # Get a hash of available commands grouped by the "group" name.
29
+ def command_groups
30
+ visible_commands.values.group_by(&:group)
31
+ end
32
+
33
+ def process
34
+ if args.empty?
35
+ display_index(command_groups)
36
+ else
37
+ display_search(args.first)
38
+ end
39
+ end
40
+
41
+ # Display the index view, with headings and short descriptions per command.
42
+ #
43
+ # @param [Hash<String, Array<Commands>>] groups
44
+ def display_index(groups)
45
+ help_text = []
46
+
47
+ sorted_group_names(groups).each do |group_name|
48
+ commands = sorted_commands(groups[group_name])
49
+
50
+ help_text << help_text_for_commands(group_name, commands) if commands.any?
51
+ end
52
+
53
+ pry_instance.pager.page help_text.join("\n\n")
54
+ end
55
+
56
+ # Given a group name and an array of commands,
57
+ # return the help string for those commands.
58
+ #
59
+ # @param [String] name The group name.
60
+ # @param [Array<Pry::Command>] commands
61
+ # @return [String] The generated help string.
62
+ def help_text_for_commands(name, commands)
63
+ "#{bold(name.capitalize)}\n" + commands.map do |command|
64
+ " #{command.options[:listing].to_s.ljust(18)} " \
65
+ "#{command.description.capitalize}"
66
+ end.join("\n")
67
+ end
68
+
69
+ # @param [Hash] groups
70
+ # @return [Array<String>] An array of sorted group names.
71
+ def sorted_group_names(groups)
72
+ groups.keys.sort_by(&method(:group_sort_key))
73
+ end
74
+
75
+ # Sort an array of commands by their `listing` name.
76
+ #
77
+ # @param [Array<Pry::Command>] commands The commands to sort
78
+ # @return [Array<Pry::Command>] commands sorted by listing name.
79
+ def sorted_commands(commands)
80
+ commands.sort_by { |command| command.options[:listing].to_s }
81
+ end
82
+
83
+ # Display help for an individual command or group.
84
+ #
85
+ # @param [String] search The string to search for.
86
+ def display_search(search)
87
+ if (command = command_set.find_command_for_help(search))
88
+ display_command(command)
89
+ else
90
+ display_filtered_search_results(search)
91
+ end
92
+ end
93
+
94
+ # Display help for a searched item, filtered first by group
95
+ # and if that fails, filtered by command name.
96
+ #
97
+ # @param [String] search The string to search for.
98
+ def display_filtered_search_results(search)
99
+ groups = search_hash(search, command_groups)
100
+
101
+ if !groups.empty?
102
+ display_index(groups)
103
+ else
104
+ display_filtered_commands(search)
105
+ end
106
+ end
107
+
108
+ # Display help for a searched item, filtered by group
109
+ #
110
+ # @param [String] search The string to search for.
111
+ def display_filtered_commands(search)
112
+ filtered = search_hash(search, visible_commands)
113
+ raise CommandError, "No help found for '#{args.first}'" if filtered.empty?
114
+
115
+ if filtered.size == 1
116
+ display_command(filtered.values.first)
117
+ else
118
+ display_index("'#{search}' commands" => filtered.values)
119
+ end
120
+ end
121
+
122
+ # Display help for an individual command.
123
+ #
124
+ # @param [Pry::Command] command
125
+ def display_command(command)
126
+ pry_instance.pager.page command.new.help
127
+ end
128
+
129
+ # Find a subset of a hash that matches the user's search term.
130
+ #
131
+ # If there's an exact match a Hash of one element will be returned,
132
+ # otherwise a sub-Hash with every key that matches the search will
133
+ # be returned.
134
+ #
135
+ # @param [String] search the search term
136
+ # @param [Hash] hash the hash to search
137
+ def search_hash(search, hash)
138
+ matching = {}
139
+
140
+ hash.each_pair do |key, value|
141
+ next unless key.is_a?(String)
142
+ return { key => value } if normalize(key) == normalize(search)
143
+ next unless normalize(key).start_with?(normalize(search))
144
+
145
+ matching[key] = value
146
+ end
147
+
148
+ matching
149
+ end
150
+
151
+ # Clean search terms to make it easier to search group names
152
+ #
153
+ # @param [String] key
154
+ # @return [String]
155
+ def normalize(key)
156
+ key.downcase.gsub(/pry\W+/, '')
157
+ end
158
+
159
+ def group_sort_key(group_name)
160
+ [
161
+ %w[
162
+ Help Context Editing Introspection Input_and_output Navigating_pry
163
+ Gems Basic Commands
164
+ ].index(group_name.tr(' ', '_')) || 99, group_name
165
+ ]
166
+ end
167
+ end
168
+
169
+ Pry::Commands.add_command(Pry::Command::Help)
170
+ end
171
+ end
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class Hist < Pry::ClassCommand
6
+ match 'hist'
7
+ group 'Editing'
8
+ description 'Show and replay Readline history.'
9
+
10
+ banner <<-'BANNER'
11
+ Usage: hist [--head|--tail]
12
+ hist --all
13
+ hist --head N
14
+ hist --tail N
15
+ hist --show START..END
16
+ hist --grep PATTERN
17
+ hist --clear
18
+ hist --replay START..END
19
+ hist --save [START..END] FILE
20
+ Aliases: history
21
+
22
+ Show and replay Readline history.
23
+ BANNER
24
+
25
+ def options(opt)
26
+ opt.on :a, :all, "Display all history"
27
+ opt.on :H, :head, "Display the first N items",
28
+ optional_argument: true, as: Integer
29
+ opt.on :T, :tail, "Display the last N items",
30
+ optional_argument: true, as: Integer
31
+ opt.on :s, :show, "Show the given range of lines",
32
+ optional_argument: true, as: Range
33
+ opt.on :G, :grep, "Show lines matching the given pattern",
34
+ argument: true, as: String
35
+ opt.on :c, :clear, "Clear the current session's history"
36
+ opt.on :r, :replay, "Replay a line or range of lines",
37
+ argument: true, as: Range
38
+ opt.on :save, "Save history to a file", argument: true, as: Range
39
+ opt.on :e, :'exclude-pry', "Exclude Pry commands from the history"
40
+ opt.on :n, :'no-numbers', "Omit line numbers"
41
+ end
42
+
43
+ def process
44
+ @history = find_history
45
+
46
+ @history = @history.between(opts[:show]) if opts.present?(:show)
47
+
48
+ @history = @history.grep(opts[:grep]) if opts.present?(:grep)
49
+
50
+ @history =
51
+ if opts.present?(:head)
52
+ @history.take_lines(1, opts[:head] || 10)
53
+ elsif opts.present?(:tail)
54
+ @history.take_lines(-(opts[:tail] || 10), opts[:tail] || 10)
55
+ else
56
+ @history
57
+ end
58
+
59
+ if opts.present?(:'exclude-pry')
60
+ @history = @history.reject do |loc|
61
+ command_set.valid_command?(loc.line)
62
+ end
63
+ end
64
+
65
+ if opts.present?(:save)
66
+ process_save
67
+ elsif opts.present?(:clear)
68
+ process_clear
69
+ elsif opts.present?(:replay)
70
+ process_replay
71
+ else
72
+ process_display
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def process_display
79
+ @history = @history.with_line_numbers unless opts.present?(:'no-numbers')
80
+
81
+ pry_instance.pager.open do |pager|
82
+ @history.print_to_output(pager, true)
83
+ end
84
+ end
85
+
86
+ def process_save
87
+ case opts[:save]
88
+ when Range
89
+ @history = @history.between(opts[:save])
90
+
91
+ raise CommandError, "Must provide a file name." unless args.first
92
+
93
+ file_name = File.expand_path(args.first)
94
+ when String
95
+ file_name = File.expand_path(opts[:save])
96
+ end
97
+
98
+ output.puts "Saving history in #{file_name}..."
99
+
100
+ File.open(file_name, 'w') { |f| f.write(@history.raw) }
101
+
102
+ output.puts "History saved."
103
+ end
104
+
105
+ def process_clear
106
+ Pry.history.clear
107
+ output.puts "History cleared."
108
+ end
109
+
110
+ def process_replay
111
+ @history = @history.between(opts[:r])
112
+ replay_sequence = @history.raw
113
+
114
+ # If we met follow-up "hist" call, check for the "--replay" option
115
+ # presence. If "hist" command is called with other options, proceed
116
+ # further.
117
+ check_for_juxtaposed_replay(replay_sequence)
118
+
119
+ replay_sequence.lines.each do |line|
120
+ pry_instance.eval line, generated: true
121
+ end
122
+ end
123
+
124
+ # Checks +replay_sequence+ for the presence of neighboring replay calls.
125
+ # @example
126
+ # [1] pry(main)> hist --show 46894
127
+ # 46894: hist --replay 46675..46677
128
+ # [2] pry(main)> hist --show 46675..46677
129
+ # 46675: 1+1
130
+ # 46676: a = 100
131
+ # 46677: hist --tail
132
+ # [3] pry(main)> hist --replay 46894
133
+ # Error: Replay index 46894 points out to another replay call:
134
+ # `hist -r 46675..46677`
135
+ # [4] pry(main)>
136
+ #
137
+ # @raise [Pry::CommandError] If +replay_sequence+ contains another
138
+ # "hist --replay" call
139
+ # @param [String] replay_sequence The sequence of commands to be replayed
140
+ # (per saltum)
141
+ # @return [Boolean] `false` if +replay_sequence+ does not contain another
142
+ # "hist --replay" call
143
+ def check_for_juxtaposed_replay(replay_sequence)
144
+ if replay_sequence =~ /\Ahist(?:ory)?\b/
145
+ # Create *fresh* instance of Options for parsing of "hist" command.
146
+ slop_instance = slop
147
+ slop_instance.parse(replay_sequence.split(' ')[1..-1])
148
+
149
+ if slop_instance.present?(:r)
150
+ replay_sequence = replay_sequence.split("\n").join('; ')
151
+ index = opts[:r]
152
+ index = index.min if index.min == index.max || index.max.nil?
153
+
154
+ raise CommandError,
155
+ "Replay index #{index} points out to another replay call: " \
156
+ "`#{replay_sequence}`"
157
+ end
158
+ else
159
+ false
160
+ end
161
+ end
162
+
163
+ # Finds history depending on the given switch.
164
+ #
165
+ # @return [Pry::Code] if it finds `--all` (or `-a`) switch, returns all
166
+ # entries in history. Without the switch returns only the entries from the
167
+ # current Pry session.
168
+ def find_history
169
+ h = if opts.present?(:all)
170
+ Pry.history.to_a
171
+ else
172
+ Pry.history.to_a.last(Pry.history.session_line_count)
173
+ end
174
+
175
+ Pry::Code(Pry.history.filter(h[0..-2]))
176
+ end
177
+ end
178
+
179
+ Pry::Commands.add_command(Pry::Command::Hist)
180
+ Pry::Commands.alias_command 'history', 'hist'
181
+ end
182
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ImportSet < Pry::ClassCommand
6
+ match 'import-set'
7
+ group 'Commands'
8
+ # TODO: Provide a better description with examples and a general conception
9
+ # of this command.
10
+ description 'Import a Pry command set.'
11
+
12
+ banner <<-'BANNER'
13
+ Import a Pry command set.
14
+ BANNER
15
+
16
+ # TODO: resolve unused parameter.
17
+ def process(_command_set_name)
18
+ raise CommandError, "Provide a command set name" if command_set.nil?
19
+
20
+ set = target.eval(arg_string)
21
+ pry_instance.commands.import set
22
+ end
23
+ end
24
+
25
+ Pry::Commands.add_command(Pry::Command::ImportSet)
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class JumpTo < Pry::ClassCommand
6
+ match 'jump-to'
7
+ group 'Navigating Pry'
8
+ description 'Jump to a binding further up the stack.'
9
+
10
+ banner <<-'BANNER'
11
+ Jump to a binding further up the stack, popping all bindings below.
12
+ BANNER
13
+
14
+ def process(break_level)
15
+ break_level = break_level.to_i
16
+ nesting_level = pry_instance.binding_stack.size - 1
17
+ max_nest_level = nesting_level - 1
18
+
19
+ case break_level
20
+ when nesting_level
21
+ output.puts "Already at nesting level #{nesting_level}"
22
+ when 0..max_nest_level
23
+ pry_instance.binding_stack = pry_instance.binding_stack[0..break_level]
24
+ else
25
+ output.puts "Invalid nest level. Must be between 0 and " \
26
+ "#{max_nest_level}. Got #{break_level}."
27
+ end
28
+ end
29
+ end
30
+
31
+ Pry::Commands.add_command(Pry::Command::JumpTo)
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class ListInspectors < Pry::ClassCommand
6
+ match 'list-inspectors'
7
+ group 'Input and Output'
8
+ description 'List the inspector procs available for use.'
9
+ banner <<-BANNER
10
+ Usage: list-inspectors
11
+
12
+ List the inspector procs available to print return values. You can use
13
+ change-inspector to switch between them.
14
+ BANNER
15
+
16
+ def process
17
+ output.puts heading("Available inspectors") + "\n"
18
+ inspector_map.each do |name, inspector|
19
+ output.write "Name: #{bold(name)}"
20
+ output.puts selected_inspector?(inspector) ? selected_text : ""
21
+ output.puts inspector[:description]
22
+ output.puts
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def inspector_map
29
+ Pry::Inspector::MAP
30
+ end
31
+
32
+ def selected_text
33
+ red " (selected) "
34
+ end
35
+
36
+ def selected_inspector?(inspector)
37
+ pry_instance.print == inspector[:value]
38
+ end
39
+ Pry::Commands.add_command(self)
40
+ end
41
+ end
42
+ end