pry 0.10.3 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +439 -16
- data/LICENSE +1 -1
- data/README.md +362 -302
- data/bin/pry +4 -7
- data/lib/pry/basic_object.rb +10 -0
- data/lib/pry/block_command.rb +22 -0
- data/lib/pry/class_command.rb +194 -0
- data/lib/pry/cli.rb +84 -97
- data/lib/pry/code/code_file.rb +37 -26
- data/lib/pry/code/code_range.rb +7 -5
- data/lib/pry/code/loc.rb +26 -13
- data/lib/pry/code.rb +42 -31
- data/lib/pry/code_object.rb +53 -28
- data/lib/pry/color_printer.rb +46 -35
- data/lib/pry/command.rb +197 -369
- data/lib/pry/command_set.rb +89 -114
- data/lib/pry/command_state.rb +31 -0
- data/lib/pry/commands/amend_line.rb +86 -82
- data/lib/pry/commands/bang.rb +18 -14
- data/lib/pry/commands/bang_pry.rb +15 -11
- data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
- data/lib/pry/commands/cat/exception_formatter.rb +85 -72
- data/lib/pry/commands/cat/file_formatter.rb +56 -46
- data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
- data/lib/pry/commands/cat.rb +62 -54
- data/lib/pry/commands/cd.rb +40 -35
- data/lib/pry/commands/change_inspector.rb +29 -22
- data/lib/pry/commands/change_prompt.rb +48 -23
- data/lib/pry/commands/clear_screen.rb +20 -0
- data/lib/pry/commands/code_collector.rb +148 -131
- data/lib/pry/commands/disable_pry.rb +23 -19
- data/lib/pry/commands/easter_eggs.rb +23 -34
- data/lib/pry/commands/edit/exception_patcher.rb +21 -17
- data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
- data/lib/pry/commands/edit.rb +185 -157
- data/lib/pry/commands/exit.rb +40 -35
- data/lib/pry/commands/exit_all.rb +24 -20
- data/lib/pry/commands/exit_program.rb +20 -16
- data/lib/pry/commands/find_method.rb +168 -162
- data/lib/pry/commands/fix_indent.rb +16 -12
- data/lib/pry/commands/help.rb +140 -133
- data/lib/pry/commands/hist.rb +151 -149
- data/lib/pry/commands/import_set.rb +20 -15
- data/lib/pry/commands/jump_to.rb +25 -21
- data/lib/pry/commands/list_inspectors.rb +35 -28
- data/lib/pry/commands/ls/constants.rb +59 -31
- data/lib/pry/commands/ls/formatter.rb +42 -36
- data/lib/pry/commands/ls/globals.rb +38 -36
- data/lib/pry/commands/ls/grep.rb +17 -15
- data/lib/pry/commands/ls/instance_vars.rb +29 -28
- data/lib/pry/commands/ls/interrogatable.rb +18 -12
- data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
- data/lib/pry/commands/ls/local_names.rb +26 -24
- data/lib/pry/commands/ls/local_vars.rb +38 -30
- data/lib/pry/commands/ls/ls_entity.rb +47 -52
- data/lib/pry/commands/ls/methods.rb +49 -51
- data/lib/pry/commands/ls/methods_helper.rb +46 -42
- data/lib/pry/commands/ls/self_methods.rb +23 -21
- data/lib/pry/commands/ls.rb +124 -103
- data/lib/pry/commands/nesting.rb +21 -17
- data/lib/pry/commands/play.rb +92 -82
- data/lib/pry/commands/pry_backtrace.rb +22 -17
- data/lib/pry/commands/pry_version.rb +15 -11
- data/lib/pry/commands/raise_up.rb +33 -27
- data/lib/pry/commands/reload_code.rb +60 -48
- data/lib/pry/commands/reset.rb +16 -12
- data/lib/pry/commands/ri.rb +57 -42
- data/lib/pry/commands/save_file.rb +45 -43
- data/lib/pry/commands/shell_command.rb +56 -29
- data/lib/pry/commands/shell_mode.rb +22 -18
- data/lib/pry/commands/show_doc.rb +80 -70
- data/lib/pry/commands/show_info.rb +194 -155
- data/lib/pry/commands/show_input.rb +16 -11
- data/lib/pry/commands/show_source.rb +110 -42
- data/lib/pry/commands/stat.rb +35 -31
- data/lib/pry/commands/switch_to.rb +21 -15
- data/lib/pry/commands/toggle_color.rb +20 -16
- data/lib/pry/commands/watch_expression/expression.rb +32 -27
- data/lib/pry/commands/watch_expression.rb +89 -84
- data/lib/pry/commands/whereami.rb +156 -141
- data/lib/pry/commands/wtf.rb +78 -40
- data/lib/pry/config/attributable.rb +22 -0
- data/lib/pry/config/lazy_value.rb +29 -0
- data/lib/pry/config/memoized_value.rb +34 -0
- data/lib/pry/config/value.rb +24 -0
- data/lib/pry/config.rb +310 -20
- data/lib/pry/control_d_handler.rb +28 -0
- data/lib/pry/core_extensions.rb +22 -9
- data/lib/pry/editor.rb +56 -34
- data/lib/pry/env.rb +18 -0
- data/lib/pry/exception_handler.rb +43 -0
- data/lib/pry/exceptions.rb +13 -18
- data/lib/pry/forwardable.rb +27 -0
- data/lib/pry/helpers/base_helpers.rb +20 -62
- data/lib/pry/helpers/command_helpers.rb +52 -62
- data/lib/pry/helpers/documentation_helpers.rb +21 -12
- data/lib/pry/helpers/options_helpers.rb +15 -8
- data/lib/pry/helpers/platform.rb +55 -0
- data/lib/pry/helpers/table.rb +44 -32
- data/lib/pry/helpers/text.rb +96 -85
- data/lib/pry/helpers.rb +3 -0
- data/lib/pry/history.rb +81 -55
- data/lib/pry/hooks.rb +60 -110
- data/lib/pry/indent.rb +74 -68
- data/lib/pry/input_completer.rb +199 -158
- data/lib/pry/input_lock.rb +7 -10
- data/lib/pry/inspector.rb +36 -24
- data/lib/pry/last_exception.rb +45 -45
- data/lib/pry/method/disowned.rb +19 -5
- data/lib/pry/method/patcher.rb +14 -8
- data/lib/pry/method/weird_method_locator.rb +79 -45
- data/lib/pry/method.rb +178 -124
- data/lib/pry/object_path.rb +37 -28
- data/lib/pry/output.rb +102 -16
- data/lib/pry/pager.rb +187 -174
- data/lib/pry/prompt.rb +213 -25
- data/lib/pry/pry_class.rb +119 -98
- data/lib/pry/pry_instance.rb +261 -224
- data/lib/pry/repl.rb +83 -29
- data/lib/pry/repl_file_loader.rb +27 -22
- data/lib/pry/ring.rb +89 -0
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +190 -0
- data/lib/pry/slop/option.rb +210 -0
- data/lib/pry/slop.rb +672 -0
- data/lib/pry/syntax_highlighter.rb +26 -0
- data/lib/pry/system_command_handler.rb +17 -0
- data/lib/pry/testable/evalable.rb +24 -0
- data/lib/pry/testable/mockable.rb +22 -0
- data/lib/pry/testable/pry_tester.rb +88 -0
- data/lib/pry/testable/utility.rb +34 -0
- data/lib/pry/testable/variables.rb +52 -0
- data/lib/pry/testable.rb +68 -0
- data/lib/pry/version.rb +3 -1
- data/lib/pry/warning.rb +20 -0
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
- data/lib/pry/wrapped_module.rb +68 -63
- data/lib/pry.rb +133 -149
- metadata +58 -69
- data/lib/pry/commands/disabled_commands.rb +0 -2
- data/lib/pry/commands/gem_cd.rb +0 -26
- data/lib/pry/commands/gem_install.rb +0 -32
- data/lib/pry/commands/gem_list.rb +0 -33
- data/lib/pry/commands/gem_open.rb +0 -29
- data/lib/pry/commands/gist.rb +0 -101
- data/lib/pry/commands/install_command.rb +0 -53
- data/lib/pry/commands/list_prompts.rb +0 -35
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/commands.rb +0 -6
- data/lib/pry/config/behavior.rb +0 -139
- data/lib/pry/config/convenience.rb +0 -25
- data/lib/pry/config/default.rb +0 -161
- data/lib/pry/history_array.rb +0 -121
- data/lib/pry/plugins.rb +0 -103
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/rubygem.rb +0 -82
- data/lib/pry/terminal.rb +0 -79
- data/lib/pry/test/helper.rb +0 -170
data/lib/pry/command_set.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
4
|
class NoCommandError < StandardError
|
3
5
|
def initialize(match, owner)
|
@@ -29,16 +31,12 @@ class Pry
|
|
29
31
|
# @option options [Boolean] :keep_retval Whether or not to use return value
|
30
32
|
# of the block for return of `command` or just to return `nil`
|
31
33
|
# (the default).
|
32
|
-
# @option options [Array<String>] :requires_gem Whether the command has
|
33
|
-
# any gem dependencies, if it does and dependencies not met then
|
34
|
-
# command is disabled and a stub proc giving instructions to
|
35
|
-
# install command is provided.
|
36
34
|
# @option options [Boolean] :interpolate Whether string #{} based
|
37
35
|
# interpolation is applied to the command arguments before
|
38
36
|
# executing the command. Defaults to true.
|
39
37
|
# @option options [String] :listing The listing name of the
|
40
38
|
# command. That is the name by which the command is looked up by
|
41
|
-
# help and by show-
|
39
|
+
# help and by show-source. Necessary for commands with regex matches.
|
42
40
|
# @option options [Boolean] :use_prefix Whether the command uses
|
43
41
|
# `Pry.config.command_prefix` prefix (if one is defined). Defaults
|
44
42
|
# to true.
|
@@ -57,31 +55,38 @@ class Pry
|
|
57
55
|
# end
|
58
56
|
#
|
59
57
|
# # From pry:
|
60
|
-
# # pry(main)>
|
58
|
+
# # pry(main)> pry_instance.commands = MyCommands
|
61
59
|
# # pry(main)> greet john
|
62
60
|
# # Good afternoon John!
|
63
61
|
# # pry(main)> help greet
|
64
62
|
# # Greet somebody
|
65
63
|
# @example Regexp command
|
66
64
|
# MyCommands = Pry::CommandSet.new do
|
67
|
-
# command
|
65
|
+
# command(
|
66
|
+
# /number-(\d+)/, "number-N regex command", :listing => "number"
|
67
|
+
# ) do |num, name|
|
68
68
|
# puts "hello #{name}, nice number: #{num}"
|
69
69
|
# end
|
70
70
|
# end
|
71
71
|
#
|
72
72
|
# # From pry:
|
73
|
-
# # pry(main)>
|
73
|
+
# # pry(main)> pry_instance.commands = MyCommands
|
74
74
|
# # pry(main)> number-10 john
|
75
75
|
# # hello john, nice number: 10
|
76
76
|
# # pry(main)> help number
|
77
77
|
# # number-N regex command
|
78
|
-
def block_command(match, description="No description.", options={}, &block)
|
79
|
-
|
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
|
80
83
|
options = Pry::Command.default_options(match).merge!(options)
|
81
84
|
|
82
|
-
@commands[match] = Pry::BlockCommand.subclass(
|
85
|
+
@commands[match] = Pry::BlockCommand.subclass(
|
86
|
+
match, description, options, helper_module, &block
|
87
|
+
)
|
83
88
|
end
|
84
|
-
|
89
|
+
alias command block_command
|
85
90
|
|
86
91
|
# Defines a new Pry command class.
|
87
92
|
#
|
@@ -99,7 +104,9 @@ class Pry
|
|
99
104
|
# end
|
100
105
|
#
|
101
106
|
# def process
|
102
|
-
#
|
107
|
+
# if opts.present?(:u) && opts.present?(:d)
|
108
|
+
# raise Pry::CommandError, "-u and -d makes no sense"
|
109
|
+
# end
|
103
110
|
# result = args.join(" ")
|
104
111
|
# result.downcase! if opts.present?(:downcase)
|
105
112
|
# result.upcase! if opts.present?(:upcase)
|
@@ -107,49 +114,27 @@ class Pry
|
|
107
114
|
# end
|
108
115
|
# end
|
109
116
|
#
|
110
|
-
def create_command(match, description="No description.", options={}, &block)
|
111
|
-
|
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
|
112
122
|
options = Pry::Command.default_options(match).merge!(options)
|
113
123
|
|
114
|
-
@commands[match] = Pry::ClassCommand.subclass(
|
124
|
+
@commands[match] = Pry::ClassCommand.subclass(
|
125
|
+
match, description, options, helper_module, &block
|
126
|
+
)
|
115
127
|
@commands[match].class_eval(&block)
|
116
128
|
@commands[match]
|
117
129
|
end
|
118
130
|
|
119
|
-
# Execute a block of code before a command is invoked. The block also
|
120
|
-
# gets access to parameters that will be passed to the command and
|
121
|
-
# is evaluated in the same context.
|
122
|
-
# @param [String, Regexp] search The match or listing of the command.
|
123
|
-
# @yield The block to be run before the command.
|
124
|
-
# @example Display parameter before invoking command
|
125
|
-
# Pry.config.commands.before_command("whereami") do |n|
|
126
|
-
# output.puts "parameter passed was #{n}"
|
127
|
-
# end
|
128
|
-
def before_command(search, &block)
|
129
|
-
cmd = find_command_by_match_or_listing(search)
|
130
|
-
cmd.hooks[:before].unshift block
|
131
|
-
end
|
132
|
-
|
133
|
-
# Execute a block of code after a command is invoked. The block also
|
134
|
-
# gets access to parameters that will be passed to the command and
|
135
|
-
# is evaluated in the same context.
|
136
|
-
# @param [String, Regexp] search The match or listing of the command.
|
137
|
-
# @yield The block to be run after the command.
|
138
|
-
# @example Display text 'command complete' after invoking command
|
139
|
-
# Pry.config.commands.after_command("whereami") do |n|
|
140
|
-
# output.puts "command complete!"
|
141
|
-
# end
|
142
|
-
def after_command(search, &block)
|
143
|
-
cmd = find_command_by_match_or_listing(search)
|
144
|
-
cmd.hooks[:after] << block
|
145
|
-
end
|
146
|
-
|
147
131
|
def each(&block)
|
148
132
|
@commands.each(&block)
|
149
133
|
end
|
150
134
|
|
151
135
|
# Removes some commands from the set
|
152
|
-
# @param [Array<String>] searches the matches or listings of the commands
|
136
|
+
# @param [Array<String>] searches the matches or listings of the commands
|
137
|
+
# to remove
|
153
138
|
def delete(*searches)
|
154
139
|
searches.each do |search|
|
155
140
|
cmd = find_command_by_match_or_listing(search)
|
@@ -188,7 +173,7 @@ class Pry
|
|
188
173
|
def find_command_by_match_or_listing(match_or_listing)
|
189
174
|
cmd = (@commands[match_or_listing] ||
|
190
175
|
Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands))
|
191
|
-
cmd
|
176
|
+
cmd || raise(ArgumentError, "cannot find a command: '#{match_or_listing}'")
|
192
177
|
end
|
193
178
|
|
194
179
|
# Aliases a command
|
@@ -202,14 +187,14 @@ class Pry
|
|
202
187
|
# Pry.config.commands.alias_command "lM", "ls -M"
|
203
188
|
# @example Pass explicit description (overriding default).
|
204
189
|
# Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie"
|
205
|
-
def alias_command(match, action,
|
206
|
-
cmd = find_command(action)
|
190
|
+
def alias_command(match, action, options = {})
|
191
|
+
(cmd = find_command(action)) || raise("command: '#{action}' not found")
|
207
192
|
original_options = cmd.options.dup
|
208
193
|
|
209
|
-
options = original_options.merge!(
|
210
|
-
|
211
|
-
|
212
|
-
|
194
|
+
options = original_options.merge!(
|
195
|
+
desc: "Alias for `#{action}`",
|
196
|
+
listing: match.is_a?(String) ? match : match.inspect
|
197
|
+
).merge!(options)
|
213
198
|
|
214
199
|
# ensure default description is used if desc is nil
|
215
200
|
desc = options.delete(:desc).to_s
|
@@ -218,6 +203,7 @@ class Pry
|
|
218
203
|
run action, *args
|
219
204
|
end
|
220
205
|
|
206
|
+
# TODO: untested. What's this about?
|
221
207
|
c.class_eval do
|
222
208
|
define_method(:complete) do |input|
|
223
209
|
cmd.new(context).complete(input)
|
@@ -238,12 +224,12 @@ class Pry
|
|
238
224
|
# command description to be passed this way too.
|
239
225
|
# @example Renaming the `ls` command and changing its description.
|
240
226
|
# Pry.config.commands.rename "dir", "ls", :description => "DOS friendly ls"
|
241
|
-
def rename_command(new_match, search, options={})
|
227
|
+
def rename_command(new_match, search, options = {})
|
242
228
|
cmd = find_command_by_match_or_listing(search)
|
243
229
|
|
244
230
|
options = {
|
245
|
-
:
|
246
|
-
:
|
231
|
+
listing: new_match,
|
232
|
+
description: cmd.description
|
247
233
|
}.merge!(options)
|
248
234
|
|
249
235
|
@commands[new_match] = cmd.dup
|
@@ -253,17 +239,6 @@ class Pry
|
|
253
239
|
@commands.delete(cmd.match)
|
254
240
|
end
|
255
241
|
|
256
|
-
def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command)
|
257
|
-
create_command name_of_disabled_command do
|
258
|
-
match matcher
|
259
|
-
description ""
|
260
|
-
|
261
|
-
define_method(:process) do
|
262
|
-
output.puts "DISABLED: #{message}"
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
242
|
# Sets or gets the description for a command (replacing the old
|
268
243
|
# description). Returns current description if no description
|
269
244
|
# parameter provided.
|
@@ -275,53 +250,35 @@ class Pry
|
|
275
250
|
# end
|
276
251
|
# @example Getting
|
277
252
|
# Pry.config.commands.desc "amend-line"
|
278
|
-
def desc(search, description=nil)
|
253
|
+
def desc(search, description = nil)
|
279
254
|
cmd = find_command_by_match_or_listing(search)
|
280
|
-
return cmd.description
|
255
|
+
return cmd.description unless description
|
281
256
|
|
282
257
|
cmd.description = description
|
283
258
|
end
|
284
259
|
|
285
|
-
# Defines helpers methods for this command sets.
|
286
|
-
# Those helpers are only defined in this command set.
|
287
|
-
#
|
288
|
-
# @yield A block defining helper methods
|
289
|
-
# @example
|
290
|
-
# helpers do
|
291
|
-
# def hello
|
292
|
-
# puts "Hello!"
|
293
|
-
# end
|
294
|
-
#
|
295
|
-
# include OtherModule
|
296
|
-
# end
|
297
|
-
def helpers(&block)
|
298
|
-
helper_module.class_eval(&block)
|
299
|
-
end
|
300
|
-
|
301
|
-
|
302
260
|
# @return [Array]
|
303
261
|
# The list of commands provided by the command set.
|
304
262
|
def list_commands
|
305
263
|
@commands.keys
|
306
264
|
end
|
307
|
-
|
265
|
+
alias keys list_commands
|
308
266
|
|
309
267
|
def to_hash
|
310
268
|
@commands.dup
|
311
269
|
end
|
312
|
-
|
270
|
+
alias to_h to_hash
|
313
271
|
|
314
272
|
# Find a command that matches the given line
|
315
273
|
# @param [String] pattern The line that might be a command invocation
|
316
274
|
# @return [Pry::Command, nil]
|
317
275
|
def [](pattern)
|
318
|
-
@commands.values.select do |command|
|
276
|
+
commands = @commands.values.select do |command|
|
319
277
|
command.matches?(pattern)
|
320
|
-
end
|
321
|
-
|
322
|
-
end.last
|
278
|
+
end
|
279
|
+
commands.max_by { |command| command.match_score(pattern) }
|
323
280
|
end
|
324
|
-
|
281
|
+
alias find_command []
|
325
282
|
|
326
283
|
#
|
327
284
|
# Re-assign the command found at _pattern_ with _command_.
|
@@ -340,11 +297,14 @@ class Pry
|
|
340
297
|
#
|
341
298
|
def []=(pattern, command)
|
342
299
|
if command.equal?(nil)
|
343
|
-
|
300
|
+
@commands.delete(pattern)
|
301
|
+
return
|
344
302
|
end
|
345
|
-
|
303
|
+
|
304
|
+
unless command.is_a?(Class) && command < Pry::Command
|
346
305
|
raise TypeError, "command is not a subclass of Pry::Command"
|
347
306
|
end
|
307
|
+
|
348
308
|
bind_command_to_pattern = pattern != command.match
|
349
309
|
if bind_command_to_pattern
|
350
310
|
command_copy = command.dup
|
@@ -369,11 +329,12 @@ class Pry
|
|
369
329
|
# @param [String] search The user's search.
|
370
330
|
# @return [Pry::Command?]
|
371
331
|
def find_command_for_help(search)
|
372
|
-
find_command(search) ||
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
332
|
+
find_command(search) ||
|
333
|
+
(begin
|
334
|
+
find_command_by_match_or_listing(search)
|
335
|
+
rescue ArgumentError
|
336
|
+
nil
|
337
|
+
end)
|
377
338
|
end
|
378
339
|
|
379
340
|
# Is the given line a command invocation?
|
@@ -387,9 +348,9 @@ class Pry
|
|
387
348
|
# @param [String] val The line to execute
|
388
349
|
# @param [Hash] context The context to execute the commands with
|
389
350
|
# @return [CommandSet::Result]
|
390
|
-
def process_line(val, context={})
|
391
|
-
if command = find_command(val)
|
392
|
-
context = context.merge(:
|
351
|
+
def process_line(val, context = {})
|
352
|
+
if (command = find_command(val))
|
353
|
+
context = context.merge(command_set: self)
|
393
354
|
retval = command.new(context).process_line(val)
|
394
355
|
Result.new(true, retval)
|
395
356
|
else
|
@@ -397,25 +358,38 @@ class Pry
|
|
397
358
|
end
|
398
359
|
end
|
399
360
|
|
400
|
-
# @private (used for testing)
|
401
|
-
def run_command(context, match, *args)
|
402
|
-
command = @commands[match] or raise NoCommandError.new(match, self)
|
403
|
-
command.new(context).call_safely(*args)
|
404
|
-
end
|
405
|
-
|
406
361
|
# Generate completions for the user's search.
|
407
362
|
# @param [String] search The line to search for
|
408
363
|
# @param [Hash] context The context to create the command with
|
409
364
|
# @return [Array<String>]
|
410
|
-
def complete(search, context={})
|
411
|
-
if command = find_command(search)
|
365
|
+
def complete(search, context = {})
|
366
|
+
if (command = find_command(search))
|
412
367
|
command.new(context).complete(search)
|
413
368
|
else
|
414
|
-
@commands.keys.select do |key|
|
415
|
-
String
|
416
|
-
end
|
369
|
+
keys = @commands.keys.select do |key|
|
370
|
+
key.is_a?(String) && key.start_with?(search)
|
371
|
+
end
|
372
|
+
keys.map { |key| key + " " }
|
417
373
|
end
|
418
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
|
419
393
|
end
|
420
394
|
|
421
395
|
# Wraps the return result of process_commands, indicates if the
|
@@ -424,7 +398,8 @@ class Pry
|
|
424
398
|
attr_reader :retval
|
425
399
|
|
426
400
|
def initialize(is_command, retval = nil)
|
427
|
-
@is_command
|
401
|
+
@is_command = is_command
|
402
|
+
@retval = retval
|
428
403
|
end
|
429
404
|
|
430
405
|
# Is the result a command?
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
class Pry
|
6
|
+
# CommandState is a data structure to hold per-command state.
|
7
|
+
#
|
8
|
+
# Pry commands can store arbitrary state here. This state persists between
|
9
|
+
# subsequent command invocations. All state saved here is unique to the
|
10
|
+
# command.
|
11
|
+
#
|
12
|
+
# @since v0.13.0
|
13
|
+
# @api private
|
14
|
+
class CommandState
|
15
|
+
def self.default
|
16
|
+
@default ||= new
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@command_state = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def state_for(command_name)
|
24
|
+
@command_state[command_name] ||= OpenStruct.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def reset(command_name)
|
28
|
+
@command_state[command_name] = OpenStruct.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,99 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
26
29
|
|
27
|
-
|
30
|
+
private
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
input_array = eval_string.each_line.to_a
|
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
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
+
input_array.join
|
45
|
+
end
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
def delete_from_array(array, range)
|
48
|
+
array.slice!(range)
|
49
|
+
end
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
def replace_in_array(array, range)
|
57
|
+
array[range] = arg_string + "\n"
|
58
|
+
end
|
57
59
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
62
65
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
70
73
|
|
71
|
-
|
72
|
-
|
74
|
+
[start_line_number.to_i, end_line_number.to_i] if start_line_number
|
75
|
+
end
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
+
# indentified 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
|
84
87
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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
|
94
98
|
end
|
95
99
|
end
|
96
|
-
end
|
97
100
|
|
98
|
-
|
101
|
+
Pry::Commands.add_command(Pry::Command::AmendLine)
|
102
|
+
end
|
99
103
|
end
|
data/lib/pry/commands/bang.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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: '!'
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
def process
|
17
|
+
output.puts 'Input buffer cleared!'
|
18
|
+
eval_string.replace('')
|
19
|
+
end
|
16
20
|
end
|
17
|
-
end
|
18
21
|
|
19
|
-
|
22
|
+
Pry::Commands.add_command(Pry::Command::Bang)
|
23
|
+
end
|
20
24
|
end
|
@@ -1,17 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Pry
|
2
|
-
class Command
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
class Command
|
5
|
+
class BangPry < Pry::ClassCommand
|
6
|
+
match '!pry'
|
7
|
+
group 'Navigating Pry'
|
8
|
+
description 'Start a Pry session on current self.'
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
banner <<-'BANNER'
|
11
|
+
Start a Pry session on current self. Also works mid multi-line expression.
|
12
|
+
BANNER
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
def process
|
15
|
+
target.pry
|
16
|
+
end
|
13
17
|
end
|
14
|
-
end
|
15
18
|
|
16
|
-
|
19
|
+
Pry::Commands.add_command(Pry::Command::BangPry)
|
20
|
+
end
|
17
21
|
end
|