pry 0.10.3 → 0.12.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 +4 -4
- data/CHANGELOG.md +251 -16
- data/LICENSE +1 -1
- data/README.md +35 -51
- data/bin/pry +3 -11
- data/lib/pry/basic_object.rb +6 -0
- data/lib/pry/cli.rb +50 -52
- data/lib/pry/code/code_file.rb +13 -6
- data/lib/pry/code/code_range.rb +3 -3
- data/lib/pry/code/loc.rb +14 -8
- data/lib/pry/code.rb +12 -5
- data/lib/pry/code_object.rb +27 -4
- data/lib/pry/color_printer.rb +20 -10
- data/lib/pry/command.rb +76 -45
- data/lib/pry/command_set.rb +17 -45
- data/lib/pry/commands/amend_line.rb +3 -4
- data/lib/pry/commands/bang.rb +1 -1
- data/lib/pry/commands/cat/exception_formatter.rb +10 -8
- data/lib/pry/commands/cat/file_formatter.rb +7 -3
- data/lib/pry/commands/cat/input_expression_formatter.rb +1 -1
- data/lib/pry/commands/cat.rb +7 -6
- data/lib/pry/commands/change_prompt.rb +29 -9
- data/lib/pry/commands/clear_screen.rb +14 -0
- data/lib/pry/commands/code_collector.rb +25 -23
- data/lib/pry/commands/easter_eggs.rb +12 -12
- data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
- data/lib/pry/commands/edit.rb +15 -10
- data/lib/pry/commands/exit.rb +2 -1
- data/lib/pry/commands/find_method.rb +12 -14
- data/lib/pry/commands/gem_cd.rb +1 -1
- data/lib/pry/commands/gem_install.rb +2 -2
- data/lib/pry/commands/gem_list.rb +2 -2
- data/lib/pry/commands/gem_open.rb +2 -2
- data/lib/pry/commands/gem_readme.rb +25 -0
- data/lib/pry/commands/gem_search.rb +40 -0
- data/lib/pry/commands/gem_stats.rb +83 -0
- data/lib/pry/commands/gist.rb +7 -6
- data/lib/pry/commands/help.rb +3 -3
- data/lib/pry/commands/hist.rb +11 -10
- data/lib/pry/commands/import_set.rb +2 -1
- data/lib/pry/commands/install_command.rb +7 -6
- data/lib/pry/commands/jump_to.rb +7 -7
- data/lib/pry/commands/list_inspectors.rb +2 -2
- data/lib/pry/commands/ls/constants.rb +14 -3
- data/lib/pry/commands/ls/formatter.rb +4 -2
- data/lib/pry/commands/ls/globals.rb +0 -2
- data/lib/pry/commands/ls/grep.rb +0 -2
- data/lib/pry/commands/ls/instance_vars.rb +0 -1
- data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
- data/lib/pry/commands/ls/local_names.rb +0 -2
- data/lib/pry/commands/ls/local_vars.rb +0 -2
- data/lib/pry/commands/ls/ls_entity.rb +0 -1
- data/lib/pry/commands/ls/methods.rb +0 -3
- data/lib/pry/commands/ls/methods_helper.rb +1 -1
- data/lib/pry/commands/ls/self_methods.rb +2 -1
- data/lib/pry/commands/ls.rb +30 -31
- data/lib/pry/commands/play.rb +3 -4
- data/lib/pry/commands/pry_backtrace.rb +1 -1
- data/lib/pry/commands/raise_up.rb +2 -1
- data/lib/pry/commands/reload_code.rb +2 -2
- data/lib/pry/commands/ri.rb +9 -4
- data/lib/pry/commands/shell_command.rb +36 -9
- data/lib/pry/commands/shell_mode.rb +6 -6
- data/lib/pry/commands/show_doc.rb +5 -7
- data/lib/pry/commands/show_info.rb +41 -20
- data/lib/pry/commands/show_source.rb +5 -2
- data/lib/pry/commands/stat.rb +1 -1
- data/lib/pry/commands/watch_expression/expression.rb +1 -1
- data/lib/pry/commands/watch_expression.rb +9 -7
- data/lib/pry/commands/whereami.rb +16 -9
- data/lib/pry/commands/wtf.rb +15 -2
- data/lib/pry/config/behavior.rb +230 -114
- data/lib/pry/config/convenience.rb +24 -21
- data/lib/pry/config/default.rb +151 -153
- data/lib/pry/config/memoization.rb +48 -0
- data/lib/pry/config.rb +30 -19
- data/lib/pry/core_extensions.rb +15 -4
- data/lib/pry/editor.rb +5 -12
- data/lib/pry/exceptions.rb +1 -3
- data/lib/pry/forwardable.rb +23 -0
- data/lib/pry/helpers/base_helpers.rb +197 -110
- data/lib/pry/helpers/command_helpers.rb +5 -4
- data/lib/pry/helpers/documentation_helpers.rb +3 -2
- data/lib/pry/helpers/options_helpers.rb +6 -6
- data/lib/pry/helpers/platform.rb +58 -0
- data/lib/pry/helpers/table.rb +20 -15
- data/lib/pry/helpers/text.rb +82 -74
- data/lib/pry/helpers.rb +1 -0
- data/lib/pry/history.rb +44 -10
- data/lib/pry/hooks.rb +50 -109
- data/lib/pry/indent.rb +21 -19
- data/lib/pry/input_completer.rb +146 -123
- data/lib/pry/input_lock.rb +0 -2
- data/lib/pry/last_exception.rb +2 -2
- data/lib/pry/method/disowned.rb +3 -1
- data/lib/pry/method/patcher.rb +2 -5
- data/lib/pry/method/weird_method_locator.rb +21 -11
- data/lib/pry/method.rb +44 -38
- data/lib/pry/object_path.rb +5 -4
- data/lib/pry/output.rb +37 -37
- data/lib/pry/pager.rb +195 -181
- data/lib/pry/platform.rb +91 -0
- data/lib/pry/plugins.rb +27 -8
- data/lib/pry/prompt.rb +144 -25
- data/lib/pry/pry_class.rb +83 -33
- data/lib/pry/pry_instance.rb +94 -59
- data/lib/pry/repl.rb +70 -11
- data/lib/pry/repl_file_loader.rb +2 -3
- data/lib/pry/ring.rb +84 -0
- data/lib/pry/rubygem.rb +9 -7
- data/lib/pry/slop/LICENSE +20 -0
- data/lib/pry/slop/commands.rb +195 -0
- data/lib/pry/slop/option.rb +206 -0
- data/lib/pry/slop.rb +661 -0
- data/lib/pry/terminal.rb +18 -6
- data/lib/pry/testable/evalable.rb +15 -0
- data/lib/pry/testable/mockable.rb +14 -0
- data/lib/pry/testable/pry_tester.rb +73 -0
- data/lib/pry/testable/utility.rb +26 -0
- data/lib/pry/testable/variables.rb +46 -0
- data/lib/pry/testable.rb +70 -0
- data/lib/pry/version.rb +1 -1
- data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +9 -14
- data/lib/pry/wrapped_module.rb +22 -21
- data/lib/pry.rb +21 -50
- metadata +35 -46
- data/lib/pry/commands/list_prompts.rb +0 -35
- data/lib/pry/commands/simple_prompt.rb +0 -22
- data/lib/pry/history_array.rb +0 -121
- data/lib/pry/rbx_path.rb +0 -22
- data/lib/pry/test/helper.rb +0 -170
data/lib/pry/pry_instance.rb
CHANGED
@@ -16,11 +16,12 @@
|
|
16
16
|
# This will show a list of available commands and their usage. For more
|
17
17
|
# information about Pry you can refer to the following resources:
|
18
18
|
#
|
19
|
-
# * http://
|
19
|
+
# * http://pryrepl.org/
|
20
20
|
# * https://github.com/pry/pry
|
21
21
|
# * the IRC channel, which is #pry on the Freenode network
|
22
22
|
#
|
23
23
|
|
24
|
+
# rubocop:disable Metrics/ClassLength
|
24
25
|
class Pry
|
25
26
|
attr_accessor :binding_stack
|
26
27
|
attr_accessor :custom_completions
|
@@ -34,8 +35,13 @@ class Pry
|
|
34
35
|
attr_reader :last_exception
|
35
36
|
attr_reader :command_state
|
36
37
|
attr_reader :exit_value
|
37
|
-
|
38
|
-
|
38
|
+
|
39
|
+
# @since v0.12.0
|
40
|
+
attr_reader :input_ring
|
41
|
+
|
42
|
+
# @since v0.12.0
|
43
|
+
attr_reader :output_ring
|
44
|
+
|
39
45
|
attr_reader :config
|
40
46
|
|
41
47
|
extend Pry::Config::Convenience
|
@@ -62,7 +68,7 @@ class Pry
|
|
62
68
|
# The backtrace of the session's `binding.pry` line, if applicable.
|
63
69
|
# @option options [Object] :target
|
64
70
|
# The initial context for this session.
|
65
|
-
def initialize(options={})
|
71
|
+
def initialize(options = {})
|
66
72
|
@binding_stack = []
|
67
73
|
@indent = Pry::Indent.new
|
68
74
|
@command_state = {}
|
@@ -72,23 +78,47 @@ class Pry
|
|
72
78
|
@config = Pry::Config.new
|
73
79
|
config.merge!(options)
|
74
80
|
push_prompt(config.prompt)
|
75
|
-
@
|
76
|
-
@
|
81
|
+
@input_ring = Pry::Ring.new(config.memory_size)
|
82
|
+
@output_ring = Pry::Ring.new(config.memory_size)
|
77
83
|
@custom_completions = config.command_completions
|
78
84
|
set_last_result nil
|
79
|
-
@
|
85
|
+
@input_ring << nil
|
80
86
|
push_initial_binding(target)
|
81
87
|
exec_hook(:when_started, target, options, self)
|
82
88
|
end
|
83
89
|
|
84
|
-
|
90
|
+
@input_array_warn = false
|
91
|
+
# @deprecated Use {#input_ring} instead.
|
92
|
+
def input_array
|
93
|
+
unless @input_array_warn
|
94
|
+
loc = caller_locations(1..1).first
|
95
|
+
warn(
|
96
|
+
"#{loc.path}:#{loc.lineno}: warning: method #{self.class}##{__method__} " \
|
97
|
+
"is deprecated. Use #{self.class}#input_ring instead"
|
98
|
+
)
|
99
|
+
@input_array_warn = true
|
100
|
+
end
|
101
|
+
|
102
|
+
@input_ring
|
103
|
+
end
|
104
|
+
|
105
|
+
@output_array_warn = false
|
106
|
+
# @deprecated Use {#output_ring} instead.
|
107
|
+
def output_array
|
108
|
+
unless @output_array_warn
|
109
|
+
loc = caller_locations(1..1).first
|
110
|
+
warn(
|
111
|
+
"#{loc.path}:#{loc.lineno}: warning: method #{self.class}##{__method__} " \
|
112
|
+
"is deprecated. Use #{self.class}#output_ring instead"
|
113
|
+
)
|
114
|
+
@output_array_warn = true
|
115
|
+
end
|
116
|
+
|
117
|
+
@output_ring
|
118
|
+
end
|
119
|
+
|
85
120
|
# This is the prompt at the top of the prompt stack.
|
86
|
-
#
|
87
|
-
# @example
|
88
|
-
# self.prompt = Pry::SIMPLE_PROMPT
|
89
|
-
# self.prompt # => Pry::SIMPLE_PROMPT
|
90
|
-
#
|
91
|
-
# @return [Array<Proc>] Current prompt.
|
121
|
+
# @return [Array<Proc>] the current prompt
|
92
122
|
def prompt
|
93
123
|
prompt_stack.last
|
94
124
|
end
|
@@ -103,7 +133,7 @@ class Pry
|
|
103
133
|
|
104
134
|
# Initialize this instance by pushing its initial context into the binding
|
105
135
|
# stack. If no target is given, start at the top level.
|
106
|
-
def push_initial_binding(target=nil)
|
136
|
+
def push_initial_binding(target = nil)
|
107
137
|
push_binding(target || Pry.toplevel_binding)
|
108
138
|
end
|
109
139
|
|
@@ -124,7 +154,7 @@ class Pry
|
|
124
154
|
#
|
125
155
|
# Generate completions.
|
126
156
|
#
|
127
|
-
# @param [String]
|
157
|
+
# @param [String] str
|
128
158
|
# What the user has typed so far
|
129
159
|
#
|
130
160
|
# @return [Array<String>]
|
@@ -132,6 +162,7 @@ class Pry
|
|
132
162
|
#
|
133
163
|
def complete(str)
|
134
164
|
return EMPTY_COMPLETIONS unless config.completer
|
165
|
+
|
135
166
|
Pry.critical_section do
|
136
167
|
completer = config.completer.new(config.input, self)
|
137
168
|
completer.call str, target: current_binding, custom_completions: custom_completions.call.push(*sticky_locals.keys)
|
@@ -171,13 +202,13 @@ class Pry
|
|
171
202
|
# @return [Integer] The maximum amount of objects remembered by the inp and
|
172
203
|
# out arrays. Defaults to 100.
|
173
204
|
def memory_size
|
174
|
-
@
|
205
|
+
@output_ring.max_size
|
175
206
|
end
|
176
207
|
|
177
208
|
undef :memory_size= if method_defined? :memory_size=
|
178
209
|
def memory_size=(size)
|
179
|
-
@
|
180
|
-
@
|
210
|
+
@input_ring = Pry::Ring.new(size)
|
211
|
+
@output_ring = Pry::Ring.new(size)
|
181
212
|
end
|
182
213
|
|
183
214
|
# Inject all the sticky locals into the current binding.
|
@@ -197,14 +228,14 @@ class Pry
|
|
197
228
|
end
|
198
229
|
|
199
230
|
def sticky_locals
|
200
|
-
{ _in_:
|
201
|
-
_out_:
|
231
|
+
{ _in_: input_ring,
|
232
|
+
_out_: output_ring,
|
202
233
|
_pry_: self,
|
203
234
|
_ex_: last_exception && last_exception.wrapped_exception,
|
204
235
|
_file_: last_file,
|
205
236
|
_dir_: last_dir,
|
206
237
|
_: proc { last_result },
|
207
|
-
__: proc {
|
238
|
+
__: proc { output_ring[-2] }
|
208
239
|
}.merge(config.extra_sticky_locals)
|
209
240
|
end
|
210
241
|
|
@@ -234,7 +265,7 @@ class Pry
|
|
234
265
|
# @return [Boolean] Is Pry ready to accept more input?
|
235
266
|
# @raise [Exception] If the user uses the `raise-up` command, this method
|
236
267
|
# will raise that exception.
|
237
|
-
def eval(line, options={})
|
268
|
+
def eval(line, options = {})
|
238
269
|
return false if @stopped
|
239
270
|
|
240
271
|
exit_value = nil
|
@@ -254,6 +285,7 @@ class Pry
|
|
254
285
|
|
255
286
|
# TODO: make this configurable?
|
256
287
|
raise exception if exception
|
288
|
+
|
257
289
|
return false
|
258
290
|
end
|
259
291
|
|
@@ -269,7 +301,7 @@ class Pry
|
|
269
301
|
@suppress_output = false
|
270
302
|
inject_sticky_locals!
|
271
303
|
begin
|
272
|
-
if !process_command_safely(line
|
304
|
+
if !process_command_safely(line)
|
273
305
|
@eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
|
274
306
|
end
|
275
307
|
rescue RescuableException => e
|
@@ -310,7 +342,7 @@ class Pry
|
|
310
342
|
# This workaround has a side effect: java exceptions specified
|
311
343
|
# in `Pry.config.exception_whitelist` are ignored.
|
312
344
|
jruby_exceptions = []
|
313
|
-
if
|
345
|
+
if Helpers::Platform.jruby?
|
314
346
|
jruby_exceptions << Java::JavaLang::Exception
|
315
347
|
end
|
316
348
|
|
@@ -325,7 +357,7 @@ class Pry
|
|
325
357
|
# Eliminate following warning:
|
326
358
|
# warning: singleton on non-persistent Java type X
|
327
359
|
# (http://wiki.jruby.org/Persistence)
|
328
|
-
if
|
360
|
+
if Helpers::Platform.jruby? && e.class.respond_to?('__persistent__')
|
329
361
|
e.class.__persistent__ = true
|
330
362
|
end
|
331
363
|
self.last_exception = e
|
@@ -345,7 +377,7 @@ class Pry
|
|
345
377
|
# (If nested sessions are going to exist, this method is fine, but a goal is
|
346
378
|
# to come up with an alternative to nested sessions altogether.)
|
347
379
|
def repl(target = nil)
|
348
|
-
Pry::REPL.new(self, :
|
380
|
+
Pry::REPL.new(self, target: target).start
|
349
381
|
end
|
350
382
|
|
351
383
|
def evaluate_ruby(code)
|
@@ -373,7 +405,7 @@ class Pry
|
|
373
405
|
# serialize something in the user's program, let's not assume we can serialize
|
374
406
|
# the exception either.
|
375
407
|
begin
|
376
|
-
output.puts "(pry) output error: #{e.inspect}"
|
408
|
+
output.puts "(pry) output error: #{e.inspect}\n#{e.backtrace.join("\n")}"
|
377
409
|
rescue RescuableException => e
|
378
410
|
if last_result_is_exception?
|
379
411
|
output.puts "(pry) output error: failed to show exception"
|
@@ -400,12 +432,14 @@ class Pry
|
|
400
432
|
# @param [String] val The line to process.
|
401
433
|
# @return [Boolean] `true` if `val` is a command, `false` otherwise
|
402
434
|
def process_command(val)
|
435
|
+
val = val.lstrip if /^\s\S/ !~ val
|
403
436
|
val = val.chomp
|
404
437
|
result = commands.process_line(val,
|
405
|
-
:
|
406
|
-
:
|
407
|
-
:
|
408
|
-
:
|
438
|
+
target: current_binding,
|
439
|
+
output: output,
|
440
|
+
eval_string: @eval_string,
|
441
|
+
pry_instance: self,
|
442
|
+
hooks: hooks
|
409
443
|
)
|
410
444
|
|
411
445
|
# set a temporary (just so we can inject the value we want into eval_string)
|
@@ -433,7 +467,7 @@ class Pry
|
|
433
467
|
# @return [Boolean] `true` if `val` is a command, `false` otherwise
|
434
468
|
def process_command_safely(val)
|
435
469
|
process_command(val)
|
436
|
-
rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
|
470
|
+
rescue CommandError, Pry::Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
|
437
471
|
Pry.last_internal_error = e
|
438
472
|
output.puts "Error: #{e.message}"
|
439
473
|
true
|
@@ -446,10 +480,10 @@ class Pry
|
|
446
480
|
# pry_instance.run_command("ls -m")
|
447
481
|
def run_command(val)
|
448
482
|
commands.process_line(val,
|
449
|
-
:
|
450
|
-
:
|
451
|
-
:
|
452
|
-
:
|
483
|
+
eval_string: @eval_string,
|
484
|
+
target: current_binding,
|
485
|
+
pry_instance: self,
|
486
|
+
output: output
|
453
487
|
)
|
454
488
|
Pry::Command::VOID_VALUE
|
455
489
|
end
|
@@ -477,9 +511,9 @@ class Pry
|
|
477
511
|
# This method should not need to be invoked directly.
|
478
512
|
# @param [Object] result The result.
|
479
513
|
# @param [String] code The code that was run.
|
480
|
-
def set_last_result(result, code="")
|
514
|
+
def set_last_result(result, code = "")
|
481
515
|
@last_result_is_exception = false
|
482
|
-
@
|
516
|
+
@output_ring << result
|
483
517
|
|
484
518
|
self.last_result = result unless code =~ /\A\s*\z/
|
485
519
|
end
|
@@ -493,7 +527,7 @@ class Pry
|
|
493
527
|
def last_exception=(e)
|
494
528
|
last_exception = Pry::LastException.new(e)
|
495
529
|
@last_result_is_exception = true
|
496
|
-
@
|
530
|
+
@output_ring << last_exception
|
497
531
|
@last_exception = last_exception
|
498
532
|
end
|
499
533
|
|
@@ -501,8 +535,8 @@ class Pry
|
|
501
535
|
# This method should not need to be invoked directly.
|
502
536
|
# @param [String] code The code we just eval'd
|
503
537
|
def update_input_history(code)
|
504
|
-
# Always push to the @
|
505
|
-
@
|
538
|
+
# Always push to the @input_ring as the @output_ring is always pushed to.
|
539
|
+
@input_ring << code
|
506
540
|
if code
|
507
541
|
Pry.line_buffer.push(*code.each_line)
|
508
542
|
Pry.current_line += code.lines.count
|
@@ -527,28 +561,26 @@ class Pry
|
|
527
561
|
# @return [String] The prompt.
|
528
562
|
def select_prompt
|
529
563
|
object = current_binding.eval('self')
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
:cont => !@eval_string.empty?})
|
564
|
+
open_token = @indent.open_delimiters.last || @indent.stack.last
|
565
|
+
|
566
|
+
c = Pry::Config.assign({
|
567
|
+
object: object,
|
568
|
+
nesting_level: binding_stack.size - 1,
|
569
|
+
open_token: open_token,
|
570
|
+
session_line: Pry.history.session_line_count + 1,
|
571
|
+
history_line: Pry.history.history_line_count + 1,
|
572
|
+
expr_number: input_ring.count,
|
573
|
+
_pry_: self,
|
574
|
+
binding_stack: binding_stack,
|
575
|
+
input_ring: input_ring,
|
576
|
+
eval_string: @eval_string,
|
577
|
+
cont: !@eval_string.empty?
|
578
|
+
})
|
546
579
|
|
547
580
|
Pry.critical_section do
|
548
581
|
# If input buffer is empty then use normal prompt
|
549
582
|
if eval_string.empty?
|
550
583
|
generate_prompt(Array(prompt).first, c)
|
551
|
-
|
552
584
|
# Otherwise use the wait prompt (indicating multi-line expression)
|
553
585
|
else
|
554
586
|
generate_prompt(Array(prompt).last, c)
|
@@ -653,7 +685,9 @@ class Pry
|
|
653
685
|
raise exception
|
654
686
|
end
|
655
687
|
end
|
688
|
+
|
656
689
|
def raise_up(*args); raise_up_common(false, *args); end
|
690
|
+
|
657
691
|
def raise_up!(*args); raise_up_common(true, *args); end
|
658
692
|
|
659
693
|
# Convenience accessor for the `quiet` config key.
|
@@ -662,3 +696,4 @@ class Pry
|
|
662
696
|
config.quiet
|
663
697
|
end
|
664
698
|
end
|
699
|
+
# rubocop:enable Metrics/ClassLength
|
data/lib/pry/repl.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
1
|
class Pry
|
4
2
|
class REPL
|
5
|
-
extend Forwardable
|
3
|
+
extend Pry::Forwardable
|
6
4
|
def_delegators :@pry, :input, :output
|
7
5
|
|
8
6
|
# @return [Pry] The instance of {Pry} that the user is controlling.
|
@@ -23,6 +21,8 @@ class Pry
|
|
23
21
|
@pry = pry
|
24
22
|
@indent = Pry::Indent.new
|
25
23
|
|
24
|
+
@readline_output = nil
|
25
|
+
|
26
26
|
if options[:target]
|
27
27
|
@pry.push_binding options[:target]
|
28
28
|
end
|
@@ -49,7 +49,7 @@ class Pry
|
|
49
49
|
|
50
50
|
# Clear the line before starting Pry. This fixes issue #566.
|
51
51
|
if pry.config.correct_indent
|
52
|
-
Kernel.print
|
52
|
+
Kernel.print(Helpers::Platform.windows_ansi? ? "\e[0F" : "\e[0G")
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -106,8 +106,9 @@ class Pry
|
|
106
106
|
|
107
107
|
if output.tty? && pry.config.correct_indent && Pry::Helpers::BaseHelpers.use_ansi_codes?
|
108
108
|
output.print @indent.correct_indentation(
|
109
|
-
current_prompt,
|
110
|
-
|
109
|
+
current_prompt,
|
110
|
+
indented_val,
|
111
|
+
calculate_overhang(current_prompt, original_val, indented_val)
|
111
112
|
)
|
112
113
|
output.flush
|
113
114
|
end
|
@@ -168,20 +169,21 @@ class Pry
|
|
168
169
|
# @return [String?] The next line of input, or `nil` on <Ctrl-D>.
|
169
170
|
def read_line(current_prompt)
|
170
171
|
handle_read_errors do
|
171
|
-
if
|
172
|
+
if coolline_available?
|
172
173
|
input.completion_proc = proc do |cool|
|
173
174
|
completions = @pry.complete cool.completed_word
|
174
175
|
completions.compact
|
175
176
|
end
|
176
177
|
elsif input.respond_to? :completion_proc=
|
177
|
-
input.completion_proc = proc do |
|
178
|
-
@pry.complete
|
178
|
+
input.completion_proc = proc do |inp|
|
179
|
+
@pry.complete inp
|
179
180
|
end
|
180
181
|
end
|
181
182
|
|
182
|
-
if
|
183
|
+
if readline_available?
|
184
|
+
set_readline_output
|
183
185
|
input_readline(current_prompt, false) # false since we'll add it manually
|
184
|
-
elsif
|
186
|
+
elsif coolline_available?
|
185
187
|
input_readline(current_prompt)
|
186
188
|
else
|
187
189
|
if input.method(:readline).arity == 1
|
@@ -198,5 +200,62 @@ class Pry
|
|
198
200
|
input.readline(*args)
|
199
201
|
end
|
200
202
|
end
|
203
|
+
|
204
|
+
def readline_available?
|
205
|
+
defined?(Readline) && input == Readline
|
206
|
+
end
|
207
|
+
|
208
|
+
def coolline_available?
|
209
|
+
defined?(Coolline) && input.is_a?(Coolline)
|
210
|
+
end
|
211
|
+
|
212
|
+
# If `$stdout` is not a tty, it's probably a pipe.
|
213
|
+
# @example
|
214
|
+
# # `piping?` returns `false`
|
215
|
+
# % pry
|
216
|
+
# [1] pry(main)
|
217
|
+
#
|
218
|
+
# # `piping?` returns `true`
|
219
|
+
# % pry | tee log
|
220
|
+
def piping?
|
221
|
+
return false unless $stdout.respond_to?(:tty?)
|
222
|
+
|
223
|
+
!$stdout.tty? && $stdin.tty? && !Helpers::Platform.windows?
|
224
|
+
end
|
225
|
+
|
226
|
+
# @return [void]
|
227
|
+
def set_readline_output
|
228
|
+
return if @readline_output
|
229
|
+
|
230
|
+
if piping?
|
231
|
+
@readline_output = (Readline.output = Pry.config.output)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# Calculates correct overhang for current line. Supports vi Readline
|
236
|
+
# mode and its indicators such as "(ins)" or "(cmd)".
|
237
|
+
#
|
238
|
+
# @return [Integer]
|
239
|
+
# @note This doesn't calculate overhang for Readline's emacs mode with an
|
240
|
+
# indicator because emacs is the default mode and it doesn't use
|
241
|
+
# indicators in 99% of cases.
|
242
|
+
def calculate_overhang(current_prompt, original_val, indented_val)
|
243
|
+
overhang = original_val.length - indented_val.length
|
244
|
+
|
245
|
+
if readline_available? && Readline.respond_to?(:vi_editing_mode?)
|
246
|
+
begin
|
247
|
+
# rb-readline doesn't support this method:
|
248
|
+
# https://github.com/ConnorAtherton/rb-readline/issues/152
|
249
|
+
if Readline.vi_editing_mode?
|
250
|
+
overhang += current_prompt.length - indented_val.length
|
251
|
+
end
|
252
|
+
rescue NotImplementedError
|
253
|
+
# VI editing mode is unsupported on JRuby.
|
254
|
+
# https://github.com/pry/pry/issues/1840
|
255
|
+
nil
|
256
|
+
end
|
257
|
+
end
|
258
|
+
[0, overhang].max
|
259
|
+
end
|
201
260
|
end
|
202
261
|
end
|
data/lib/pry/repl_file_loader.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Pry
|
2
|
-
|
3
2
|
# A class to manage the loading of files through the REPL loop.
|
4
3
|
# This is an interesting trick as it processes your file as if it
|
5
4
|
# was user input in an interactive session. As a result, all Pry
|
@@ -13,7 +12,7 @@ class Pry
|
|
13
12
|
class REPLFileLoader
|
14
13
|
def initialize(file_name)
|
15
14
|
full_name = File.expand_path(file_name)
|
16
|
-
raise RuntimeError, "No such file: #{full_name}" if !File.
|
15
|
+
raise RuntimeError, "No such file: #{full_name}" if !File.exist?(full_name)
|
17
16
|
|
18
17
|
define_additional_commands
|
19
18
|
@content = File.read(full_name)
|
@@ -42,7 +41,7 @@ class Pry
|
|
42
41
|
end
|
43
42
|
|
44
43
|
content.lines.each do |line|
|
45
|
-
break unless _pry_.eval line, :
|
44
|
+
break unless _pry_.eval line, generated: true
|
46
45
|
end
|
47
46
|
|
48
47
|
unless _pry_.eval_string.empty?
|
data/lib/pry/ring.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
class Pry
|
2
|
+
# A ring is a thread-safe fixed-capacity array to which you can only add
|
3
|
+
# elements. Older entries are overwritten as you add new elements, so that the
|
4
|
+
# ring can never contain more than `max_size` elemens.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# ring = Pry::Ring.new(3)
|
8
|
+
# ring << 1 << 2 << 3
|
9
|
+
# ring.to_a #=> [1, 2, 3]
|
10
|
+
# ring << 4
|
11
|
+
# ring.to_a #=> [2, 3, 4]
|
12
|
+
#
|
13
|
+
# ring[0] #=> 2
|
14
|
+
# ring[-1] #=> 4
|
15
|
+
# ring.clear
|
16
|
+
# ring[0] #=> nil
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
# @since v0.12.0
|
20
|
+
class Ring
|
21
|
+
# @return [Integer] maximum buffer size
|
22
|
+
attr_reader :max_size
|
23
|
+
|
24
|
+
# @return [Integer] how many objects were added during the lifetime of the
|
25
|
+
# ring
|
26
|
+
attr_reader :count
|
27
|
+
alias size count
|
28
|
+
|
29
|
+
# @param [Integer] max_size Maximum buffer size. The buffer will start
|
30
|
+
# overwriting elements once its reaches its maximum capacity
|
31
|
+
def initialize(max_size)
|
32
|
+
@max_size = max_size
|
33
|
+
@mutex = Mutex.new
|
34
|
+
clear
|
35
|
+
end
|
36
|
+
|
37
|
+
# Push `value` to the current index.
|
38
|
+
#
|
39
|
+
# @param [Object] value
|
40
|
+
# @return [self]
|
41
|
+
def <<(value)
|
42
|
+
@mutex.synchronize do
|
43
|
+
@buffer[count % max_size] = value
|
44
|
+
@count += 1
|
45
|
+
self
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Read the value stored at `index`.
|
50
|
+
#
|
51
|
+
# @param [Integer, Range] index The element (if Integer) or elements
|
52
|
+
# (if Range) associated with `index`
|
53
|
+
# @return [Object, Array<Object>, nil] element(s) at `index`, `nil` if none
|
54
|
+
# exist
|
55
|
+
def [](index)
|
56
|
+
@mutex.synchronize do
|
57
|
+
return @buffer[(count + index) % max_size] if index.is_a?(Integer)
|
58
|
+
return @buffer[index] if count <= max_size
|
59
|
+
|
60
|
+
# Swap parts of array when the array turns page and starts overwriting
|
61
|
+
# from the beginning, then apply the range.
|
62
|
+
last_part = @buffer.slice([index.end, max_size - 1].min, count % max_size)
|
63
|
+
(last_part + (@buffer - last_part))[index]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Array<Object>] the buffer as unwinded array
|
68
|
+
def to_a
|
69
|
+
return @buffer.dup if count <= max_size
|
70
|
+
|
71
|
+
last_part = @buffer.slice(count % max_size, @buffer.size)
|
72
|
+
last_part + (@buffer - last_part)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Clear the buffer and reset count.
|
76
|
+
# @return [void]
|
77
|
+
def clear
|
78
|
+
@mutex.synchronize do
|
79
|
+
@buffer = []
|
80
|
+
@count = 0
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/pry/rubygem.rb
CHANGED
@@ -23,7 +23,7 @@ class Pry
|
|
23
23
|
Gem.source_index.find_name(name)
|
24
24
|
end
|
25
25
|
|
26
|
-
first_spec = specs.sort_by{ |spec| Gem::Version.new(spec.version) }.last
|
26
|
+
first_spec = specs.sort_by { |spec| Gem::Version.new(spec.version) }.last
|
27
27
|
|
28
28
|
first_spec or raise CommandError, "Gem `#{name}` not found"
|
29
29
|
end
|
@@ -34,9 +34,9 @@ class Pry
|
|
34
34
|
# @return [Array<Gem::Specification>]
|
35
35
|
def list(pattern = /.*/)
|
36
36
|
if Gem::Specification.respond_to?(:each)
|
37
|
-
Gem::Specification.select{|spec| spec.name =~ pattern }
|
37
|
+
Gem::Specification.select { |spec| spec.name =~ pattern }
|
38
38
|
else
|
39
|
-
Gem.source_index.gems.values.select{|spec| spec.name =~ pattern }
|
39
|
+
Gem.source_index.gems.values.select { |spec| spec.name =~ pattern }
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -57,7 +57,9 @@ class Pry
|
|
57
57
|
# @param [String] name
|
58
58
|
# @return [void]
|
59
59
|
def install(name)
|
60
|
-
|
60
|
+
require 'rubygems/dependency_installer'
|
61
|
+
gem_config = Gem.configuration['gem']
|
62
|
+
gemrc_opts = (gem_config.nil? ? "" : gem_config.split(' '))
|
61
63
|
destination = if gemrc_opts.include?('--user-install')
|
62
64
|
Gem.user_dir
|
63
65
|
elsif File.writable?(Gem.dir)
|
@@ -65,14 +67,14 @@ class Pry
|
|
65
67
|
else
|
66
68
|
Gem.user_dir
|
67
69
|
end
|
68
|
-
installer = Gem::DependencyInstaller.new(:
|
70
|
+
installer = Gem::DependencyInstaller.new(install_dir: destination)
|
69
71
|
installer.install(name)
|
70
72
|
rescue Errno::EACCES
|
71
73
|
raise CommandError,
|
72
|
-
"Insufficient permissions to install #{
|
74
|
+
"Insufficient permissions to install #{green(name)}."
|
73
75
|
rescue Gem::GemNotFoundException
|
74
76
|
raise CommandError,
|
75
|
-
"Gem #{
|
77
|
+
"Gem #{green(name)} not found. Aborting installation."
|
76
78
|
else
|
77
79
|
Gem.refresh
|
78
80
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Lee Jarvis
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|