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,418 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class NoCommandError < StandardError
5
+ def initialize(match, owner)
6
+ super "Command '#{match}' not found in command set #{owner}"
7
+ end
8
+ end
9
+
10
+ # This class is used to create sets of commands. Commands can be imported from
11
+ # different sets, aliased, removed, etc.
12
+ class CommandSet
13
+ include Enumerable
14
+ include Pry::Helpers::BaseHelpers
15
+ attr_reader :helper_module
16
+
17
+ # @param [Array<Commandset>] imported_sets
18
+ # Sets which will be imported automatically
19
+ # @yield Optional block run to define commands
20
+ def initialize(*imported_sets, &block)
21
+ @commands = {}
22
+ @helper_module = Module.new
23
+ import(*imported_sets)
24
+ instance_eval(&block) if block
25
+ end
26
+
27
+ # Defines a new Pry command.
28
+ # @param [String, Regexp] match The start of invocations of this command.
29
+ # @param [String] description A description of the command.
30
+ # @param [Hash] options The optional configuration parameters.
31
+ # @option options [Boolean] :keep_retval Whether or not to use return value
32
+ # of the block for return of `command` or just to return `nil`
33
+ # (the default).
34
+ # @option options [Boolean] :interpolate Whether string #{} based
35
+ # interpolation is applied to the command arguments before
36
+ # executing the command. Defaults to true.
37
+ # @option options [String] :listing The listing name of the
38
+ # command. That is the name by which the command is looked up by
39
+ # help and by show-source. Necessary for commands with regex matches.
40
+ # @option options [Boolean] :use_prefix Whether the command uses
41
+ # `Pry.config.command_prefix` prefix (if one is defined). Defaults
42
+ # to true.
43
+ # @option options [Boolean] :shellwords Whether the command's arguments
44
+ # should be split using Shellwords instead of just split on spaces.
45
+ # Defaults to true.
46
+ # @yield The action to perform. The parameters in the block
47
+ # determines the parameters the command will receive. All
48
+ # parameters passed into the block will be strings. Successive
49
+ # command parameters are separated by whitespace at the Pry prompt.
50
+ # @example
51
+ # MyCommands = Pry::CommandSet.new do
52
+ # command "greet", "Greet somebody" do |name|
53
+ # puts "Good afternoon #{name.capitalize}!"
54
+ # end
55
+ # end
56
+ #
57
+ # # From pry:
58
+ # # pry(main)> pry_instance.commands = MyCommands
59
+ # # pry(main)> greet john
60
+ # # Good afternoon John!
61
+ # # pry(main)> help greet
62
+ # # Greet somebody
63
+ # @example Regexp command
64
+ # MyCommands = Pry::CommandSet.new do
65
+ # command(
66
+ # /number-(\d+)/, "number-N regex command", :listing => "number"
67
+ # ) do |num, name|
68
+ # puts "hello #{name}, nice number: #{num}"
69
+ # end
70
+ # end
71
+ #
72
+ # # From pry:
73
+ # # pry(main)> pry_instance.commands = MyCommands
74
+ # # pry(main)> number-10 john
75
+ # # hello john, nice number: 10
76
+ # # pry(main)> help number
77
+ # # number-N regex command
78
+ def block_command(match, description = "No description.", options = {}, &block)
79
+ if description.is_a?(Hash)
80
+ options = description
81
+ description = "No description."
82
+ end
83
+ options = Pry::Command.default_options(match).merge!(options)
84
+
85
+ @commands[match] = Pry::BlockCommand.subclass(
86
+ match, description, options, helper_module, &block
87
+ )
88
+ end
89
+ alias command block_command
90
+
91
+ # Defines a new Pry command class.
92
+ #
93
+ # @param [String, Regexp] match The start of invocations of this command.
94
+ # @param [String] description A description of the command.
95
+ # @param [Hash] options The optional configuration parameters, see {#command}
96
+ # @yield The class body's definition.
97
+ #
98
+ # @example
99
+ # Pry::Commands.create_command "echo", "echo's the input", :shellwords => false do
100
+ # def options(opt)
101
+ # opt.banner "Usage: echo [-u | -d] <string to echo>"
102
+ # opt.on :u, :upcase, "ensure the output is all upper-case"
103
+ # opt.on :d, :downcase, "ensure the output is all lower-case"
104
+ # end
105
+ #
106
+ # def process
107
+ # if opts.present?(:u) && opts.present?(:d)
108
+ # raise Pry::CommandError, "-u and -d makes no sense"
109
+ # end
110
+ # result = args.join(" ")
111
+ # result.downcase! if opts.present?(:downcase)
112
+ # result.upcase! if opts.present?(:upcase)
113
+ # output.puts result
114
+ # end
115
+ # end
116
+ #
117
+ def create_command(match, description = "No description.", options = {}, &block)
118
+ if description.is_a?(Hash)
119
+ options = description
120
+ description = "No description."
121
+ end
122
+ options = Pry::Command.default_options(match).merge!(options)
123
+
124
+ @commands[match] = Pry::ClassCommand.subclass(
125
+ match, description, options, helper_module, &block
126
+ )
127
+ @commands[match].class_eval(&block)
128
+ @commands[match]
129
+ end
130
+
131
+ def each(&block)
132
+ @commands.each(&block)
133
+ end
134
+
135
+ # Removes some commands from the set
136
+ # @param [Array<String>] searches the matches or listings of the commands
137
+ # to remove
138
+ def delete(*searches)
139
+ searches.each do |search|
140
+ cmd = find_command_by_match_or_listing(search)
141
+ @commands.delete cmd.match
142
+ end
143
+ end
144
+
145
+ # Imports all the commands from one or more sets.
146
+ # @param [Array<CommandSet>] sets Command sets, all of the commands of which
147
+ # will be imported.
148
+ # @return [Pry::CommandSet] Returns the receiver (a command set).
149
+ def import(*sets)
150
+ sets.each do |set|
151
+ @commands.merge! set.to_hash
152
+ helper_module.send :include, set.helper_module
153
+ end
154
+ self
155
+ end
156
+
157
+ # Imports some commands from a set
158
+ # @param [CommandSet] set Set to import commands from
159
+ # @param [Array<String>] matches Commands to import
160
+ # @return [Pry::CommandSet] Returns the receiver (a command set).
161
+ def import_from(set, *matches)
162
+ helper_module.send :include, set.helper_module
163
+ matches.each do |match|
164
+ cmd = set.find_command_by_match_or_listing(match)
165
+ @commands[cmd.match] = cmd
166
+ end
167
+ self
168
+ end
169
+
170
+ # @param [String, Regexp] match_or_listing The match or listing of a command.
171
+ # of the command to retrieve.
172
+ # @return [Command] The command object matched.
173
+ def find_command_by_match_or_listing(match_or_listing)
174
+ cmd = (@commands[match_or_listing] ||
175
+ Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands))
176
+ cmd || raise(ArgumentError, "cannot find a command: '#{match_or_listing}'")
177
+ end
178
+
179
+ # Aliases a command
180
+ # @param [String, Regex] match The match of the alias (can be a regex).
181
+ # @param [String] action The action to be performed (typically
182
+ # another command).
183
+ # @param [Hash] options The optional configuration parameters,
184
+ # accepts the same as the `command` method, but also allows the
185
+ # command description to be passed this way too as `:desc`
186
+ # @example Creating an alias for `ls -M`
187
+ # Pry.config.commands.alias_command "lM", "ls -M"
188
+ # @example Pass explicit description (overriding default).
189
+ # Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie"
190
+ def alias_command(match, action, options = {})
191
+ (cmd = find_command(action)) || raise("command: '#{action}' not found")
192
+ original_options = cmd.options.dup
193
+
194
+ options = original_options.merge!(
195
+ desc: "Alias for `#{action}`",
196
+ listing: match.is_a?(String) ? match : match.inspect
197
+ ).merge!(options)
198
+
199
+ # ensure default description is used if desc is nil
200
+ desc = options.delete(:desc).to_s
201
+
202
+ c = block_command match, desc, options do |*args|
203
+ run action, *args
204
+ end
205
+
206
+ # TODO: untested. What's this about?
207
+ c.class_eval do
208
+ define_method(:complete) do |input|
209
+ cmd.new(context).complete(input)
210
+ end
211
+ end
212
+
213
+ c.group "Aliases"
214
+
215
+ c
216
+ end
217
+
218
+ # Rename a command. Accepts either match or listing for the search.
219
+ #
220
+ # @param [String, Regexp] new_match The new match for the command.
221
+ # @param [String, Regexp] search The command's current match or listing.
222
+ # @param [Hash] options The optional configuration parameters,
223
+ # accepts the same as the `command` method, but also allows the
224
+ # command description to be passed this way too.
225
+ # @example Renaming the `ls` command and changing its description.
226
+ # Pry.config.commands.rename "dir", "ls", :description => "DOS friendly ls"
227
+ def rename_command(new_match, search, options = {})
228
+ cmd = find_command_by_match_or_listing(search)
229
+
230
+ options = {
231
+ listing: new_match,
232
+ description: cmd.description
233
+ }.merge!(options)
234
+
235
+ @commands[new_match] = cmd.dup
236
+ @commands[new_match].match = new_match
237
+ @commands[new_match].description = options.delete(:description)
238
+ @commands[new_match].options.merge!(options)
239
+ @commands.delete(cmd.match)
240
+ end
241
+
242
+ # Sets or gets the description for a command (replacing the old
243
+ # description). Returns current description if no description
244
+ # parameter provided.
245
+ # @param [String, Regexp] search The command match.
246
+ # @param [String?] description (nil) The command description.
247
+ # @example Setting
248
+ # MyCommands = Pry::CommandSet.new do
249
+ # desc "help", "help description"
250
+ # end
251
+ # @example Getting
252
+ # Pry.config.commands.desc "amend-line"
253
+ def desc(search, description = nil)
254
+ cmd = find_command_by_match_or_listing(search)
255
+ return cmd.description unless description
256
+
257
+ cmd.description = description
258
+ end
259
+
260
+ # @return [Array]
261
+ # The list of commands provided by the command set.
262
+ def list_commands
263
+ @commands.keys
264
+ end
265
+ alias keys list_commands
266
+
267
+ def to_hash
268
+ @commands.dup
269
+ end
270
+ alias to_h to_hash
271
+
272
+ # Find a command that matches the given line
273
+ # @param [String] pattern The line that might be a command invocation
274
+ # @return [Pry::Command, nil]
275
+ def [](pattern)
276
+ commands = @commands.values.select do |command|
277
+ command.matches?(pattern)
278
+ end
279
+ commands.max_by { |command| command.match_score(pattern) }
280
+ end
281
+ alias find_command []
282
+
283
+ #
284
+ # Re-assign the command found at _pattern_ with _command_.
285
+ #
286
+ # @param [Regexp, String] pattern
287
+ # The command to add or replace(found at _pattern_).
288
+ #
289
+ # @param [Pry::Command] command
290
+ # The command to add.
291
+ #
292
+ # @return [Pry::Command]
293
+ # Returns the new command (matched with "pattern".)
294
+ #
295
+ # @example
296
+ # Pry.config.commands["help"] = MyHelpCommand
297
+ #
298
+ def []=(pattern, command)
299
+ if command.equal?(nil)
300
+ @commands.delete(pattern)
301
+ return
302
+ end
303
+
304
+ unless command.is_a?(Class) && command < Pry::Command
305
+ raise TypeError, "command is not a subclass of Pry::Command"
306
+ end
307
+
308
+ bind_command_to_pattern = pattern != command.match
309
+ if bind_command_to_pattern
310
+ command_copy = command.dup
311
+ command_copy.match = pattern
312
+ @commands[pattern] = command_copy
313
+ else
314
+ @commands[pattern] = command
315
+ end
316
+ end
317
+
318
+ #
319
+ # Add a command to set.
320
+ #
321
+ # @param [Command] command
322
+ # a subclass of Pry::Command.
323
+ #
324
+ def add_command(command)
325
+ self[command.match] = command
326
+ end
327
+
328
+ # Find the command that the user might be trying to refer to.
329
+ # @param [String] search The user's search.
330
+ # @return [Pry::Command?]
331
+ def find_command_for_help(search)
332
+ find_command(search) ||
333
+ (begin
334
+ find_command_by_match_or_listing(search)
335
+ rescue ArgumentError
336
+ nil
337
+ end)
338
+ end
339
+
340
+ # Is the given line a command invocation?
341
+ # @param [String] val
342
+ # @return [Boolean]
343
+ def valid_command?(val)
344
+ !!find_command(val)
345
+ end
346
+
347
+ # Process the given line to see whether it needs executing as a command.
348
+ # @param [String] val The line to execute
349
+ # @param [Hash] context The context to execute the commands with
350
+ # @return [CommandSet::Result]
351
+ def process_line(val, context = {})
352
+ if (command = find_command(val))
353
+ context = context.merge(command_set: self)
354
+ retval = command.new(context).process_line(val)
355
+ Result.new(true, retval)
356
+ else
357
+ Result.new(false)
358
+ end
359
+ end
360
+
361
+ # Generate completions for the user's search.
362
+ # @param [String] search The line to search for
363
+ # @param [Hash] context The context to create the command with
364
+ # @return [Array<String>]
365
+ def complete(search, context = {})
366
+ if (command = find_command(search))
367
+ command.new(context).complete(search)
368
+ else
369
+ keys = @commands.keys.select do |key|
370
+ key.is_a?(String) && key.start_with?(search)
371
+ end
372
+ keys.map { |key| key + " " }
373
+ end
374
+ end
375
+
376
+ private
377
+
378
+ # Defines helpers methods for this command sets.
379
+ # Those helpers are only defined in this command set.
380
+ #
381
+ # @yield A block defining helper methods
382
+ # @example
383
+ # helpers do
384
+ # def hello
385
+ # puts "Hello!"
386
+ # end
387
+ #
388
+ # include OtherModule
389
+ # end
390
+ def helpers(&block)
391
+ helper_module.class_eval(&block)
392
+ end
393
+ end
394
+
395
+ # Wraps the return result of process_commands, indicates if the
396
+ # result IS a command and what kind of command (e.g void)
397
+ class Result
398
+ attr_reader :retval
399
+
400
+ def initialize(is_command, retval = nil)
401
+ @is_command = is_command
402
+ @retval = retval
403
+ end
404
+
405
+ # Is the result a command?
406
+ # @return [Boolean]
407
+ def command?
408
+ @is_command
409
+ end
410
+
411
+ # Is the result a command and if it is, is it a void command?
412
+ # (one that does not return a value)
413
+ # @return [Boolean]
414
+ def void_command?
415
+ retval == Command::VOID_VALUE
416
+ end
417
+ end
418
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # CommandState is a data structure to hold per-command state.
5
+ #
6
+ # Pry commands can store arbitrary state here. This state persists between
7
+ # subsequent command invocations. All state saved here is unique to the
8
+ # command.
9
+ #
10
+ # @since v0.13.0
11
+ # @api private
12
+ class CommandState
13
+ def self.default
14
+ @default ||= new
15
+ end
16
+
17
+ def initialize
18
+ @command_state = {}
19
+ end
20
+
21
+ def state_for(command_class)
22
+ @command_state[command_class] ||= command_struct(command_class)
23
+ end
24
+
25
+ def reset(command_class)
26
+ @command_state[command_class] = command_struct(command_class)
27
+ end
28
+
29
+ private
30
+
31
+ def command_struct(command_class)
32
+ Struct.new(:command, *command_class.command_options[:state])
33
+ .new(command: command_class)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class AmendLine < Pry::ClassCommand
6
+ match(/amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/)
7
+ group 'Editing'
8
+ description 'Amend a line of input in multi-line mode.'
9
+ command_options interpolate: false, listing: 'amend-line'
10
+
11
+ banner <<-'BANNER'
12
+ Amend a line of input in multi-line mode. `amend-line N`, where the N represents
13
+ line to replace. Can also specify a range of lines using `amend-line N..M`
14
+ syntax. Passing "!" as replacement content deletes the line(s) instead.
15
+
16
+ amend-line 1 puts 'new' # replace line 1
17
+ amend-line 1..4 ! # delete lines 1..4
18
+ amend-line 3 >puts 'bye' # insert before line 3
19
+ amend-line puts 'appended' # no line number modifies immediately preceding line
20
+ BANNER
21
+
22
+ def process
23
+ raise CommandError, "No input to amend." if eval_string.empty?
24
+
25
+ eval_string.replace(amend_input)
26
+ run "fix-indent"
27
+ run "show-input"
28
+ end
29
+
30
+ private
31
+
32
+ # @return [String] A new string with the amendments applied to it.
33
+ def amend_input
34
+ input_array = eval_string.each_line.to_a
35
+
36
+ if arg_string == "!"
37
+ delete_from_array(input_array, line_range)
38
+ elsif arg_string.start_with?(">")
39
+ insert_into_array(input_array, line_range)
40
+ else
41
+ replace_in_array(input_array, line_range)
42
+ end
43
+
44
+ input_array.join
45
+ end
46
+
47
+ def delete_from_array(array, range)
48
+ array.slice!(range)
49
+ end
50
+
51
+ def insert_into_array(array, range)
52
+ insert_slot = Array(range).first
53
+ array.insert(insert_slot, arg_string[1..-1] << "\n")
54
+ end
55
+
56
+ def replace_in_array(array, range)
57
+ array[range] = arg_string + "\n"
58
+ end
59
+
60
+ # @return [Fixnum] The number of lines currently in `eval_string` (the
61
+ # input buffer)
62
+ def line_count
63
+ eval_string.lines.count
64
+ end
65
+
66
+ # Returns the (one-indexed) start and end lines given by the user.
67
+ # The lines in this range will be affected by the `amend-line`.
68
+ # Returns `nil` if no lines were specified by the user.
69
+ # @return [Array<Fixnum>, nil]
70
+ def start_and_end_line_number
71
+ start_line_number, end_line_number = args
72
+ end_line_number ||= start_line_number.to_i
73
+
74
+ [start_line_number.to_i, end_line_number.to_i] if start_line_number
75
+ end
76
+
77
+ # Takes two numbers that are 1-indexed, and returns a range (or
78
+ # number) that is 0-indexed. 1-indexed means the first element is
79
+ # identified by 1 rather than by 0 (as is the case for Ruby arrays).
80
+ # @param [Fixnum] start_line_number One-indexed number.
81
+ # @param [Fixnum] end_line_number One-indexed number.
82
+ # @return [Range] The zero-indexed range.
83
+ def zero_indexed_range_from_one_indexed_numbers(start_line_number, end_line_number)
84
+ # FIXME: one_index_number is a horrible name for this method
85
+ one_index_number(start_line_number)..one_index_number(end_line_number)
86
+ end
87
+
88
+ # The lines (or line) that will be modified by the `amend-line`.
89
+ # @return [Range, Fixnum] The lines or line.
90
+ def line_range
91
+ start_line_number, end_line_number = start_and_end_line_number
92
+ if start_line_number
93
+ zero_indexed_range_from_one_indexed_numbers(start_line_number,
94
+ end_line_number)
95
+ else
96
+ line_count - 1
97
+ end
98
+ end
99
+ end
100
+
101
+ Pry::Commands.add_command(Pry::Command::AmendLine)
102
+ end
103
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class Bang < Pry::ClassCommand
6
+ match(/^\s*!\s*$/)
7
+ group 'Editing'
8
+ description 'Clear the input buffer.'
9
+ command_options use_prefix: false, listing: '!'
10
+
11
+ banner <<-'BANNER'
12
+ Clear the input buffer. Useful if the parsing process goes wrong and you get
13
+ stuck in the read loop.
14
+ BANNER
15
+
16
+ def process
17
+ output.puts 'Input buffer cleared!'
18
+ eval_string.replace('')
19
+ end
20
+ end
21
+
22
+ Pry::Commands.add_command(Pry::Command::Bang)
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class BangPry < Pry::ClassCommand
6
+ match '!pry'
7
+ group 'Navigating Pry'
8
+ description 'Start a Pry session on current self.'
9
+
10
+ banner <<-'BANNER'
11
+ Start a Pry session on current self. Also works mid multi-line expression.
12
+ BANNER
13
+
14
+ def process
15
+ target.pry
16
+ end
17
+ end
18
+
19
+ Pry::Commands.add_command(Pry::Command::BangPry)
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ class Command
5
+ class Cat
6
+ class AbstractFormatter
7
+ include Pry::Helpers::CommandHelpers
8
+ include Pry::Helpers::BaseHelpers
9
+
10
+ private
11
+
12
+ def decorate(content)
13
+ content.code_type = code_type
14
+ content.between(*between_lines)
15
+ .with_line_numbers(use_line_numbers?).highlighted
16
+ end
17
+
18
+ def code_type
19
+ opts[:type] || :ruby
20
+ end
21
+
22
+ def use_line_numbers?
23
+ opts.present?(:'line-numbers') || opts.present?(:ex)
24
+ end
25
+
26
+ def between_lines
27
+ [opts[:start] || 1, opts[:end] || -1]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end