pry 0.13.1 → 0.15.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +118 -2
  3. data/README.md +47 -30
  4. data/lib/pry/basic_object.rb +1 -1
  5. data/lib/pry/class_command.rb +2 -2
  6. data/lib/pry/cli.rb +13 -29
  7. data/lib/pry/code.rb +1 -9
  8. data/lib/pry/code_object.rb +2 -2
  9. data/lib/pry/command.rb +1 -1
  10. data/lib/pry/command_set.rb +2 -2
  11. data/lib/pry/command_state.rb +11 -6
  12. data/lib/pry/commands/amend_line.rb +1 -1
  13. data/lib/pry/commands/cd.rb +2 -0
  14. data/lib/pry/commands/edit.rb +2 -0
  15. data/lib/pry/commands/find_method.rb +1 -1
  16. data/lib/pry/commands/ls/config.rb +54 -0
  17. data/lib/pry/commands/ls/constants.rb +2 -2
  18. data/lib/pry/commands/ls.rb +0 -21
  19. data/lib/pry/commands/raise_up.rb +1 -1
  20. data/lib/pry/commands/ri.rb +1 -1
  21. data/lib/pry/commands/shell_command.rb +1 -1
  22. data/lib/pry/commands/shell_mode.rb +1 -0
  23. data/lib/pry/commands/show_doc.rb +0 -1
  24. data/lib/pry/commands/show_source.rb +1 -0
  25. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  26. data/lib/pry/commands/watch_expression.rb +4 -6
  27. data/lib/pry/config.rb +26 -33
  28. data/lib/pry/control_d_handler.rb +1 -1
  29. data/lib/pry/core_extensions.rb +1 -1
  30. data/lib/pry/editor.rb +3 -1
  31. data/lib/pry/exception_handler.rb +7 -2
  32. data/lib/pry/helpers/command_helpers.rb +1 -1
  33. data/lib/pry/helpers/documentation_helpers.rb +2 -1
  34. data/lib/pry/helpers/platform.rb +1 -6
  35. data/lib/pry/helpers/text.rb +1 -1
  36. data/lib/pry/indent.rb +13 -11
  37. data/lib/pry/input/simple_stdio.rb +13 -0
  38. data/lib/pry/input_completer.rb +2 -2
  39. data/lib/pry/method/patcher.rb +2 -2
  40. data/lib/pry/method/weird_method_locator.rb +2 -2
  41. data/lib/pry/method.rb +4 -4
  42. data/lib/pry/pry_class.rb +17 -7
  43. data/lib/pry/pry_instance.rb +7 -45
  44. data/lib/pry/repl.rb +73 -4
  45. data/lib/pry/ring.rb +2 -2
  46. data/lib/pry/slop.rb +1 -1
  47. data/lib/pry/syntax_highlighter.rb +1 -1
  48. data/lib/pry/version.rb +1 -1
  49. data/lib/pry/warning.rb +3 -10
  50. data/lib/pry/wrapped_module/candidate.rb +9 -8
  51. data/lib/pry/wrapped_module.rb +3 -8
  52. data/lib/pry.rb +3 -1
  53. metadata +9 -8
  54. data/lib/pry/plugins.rb +0 -139
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'method_source'
4
- require 'ostruct'
5
4
 
6
5
  ##
7
6
  # Pry is a powerful alternative to the standard IRB shell for Ruby. It
@@ -20,7 +19,7 @@ require 'ostruct'
20
19
  # This will show a list of available commands and their usage. For more
21
20
  # information about Pry you can refer to the following resources:
22
21
  #
23
- # * http://pryrepl.org/
22
+ # * https://pry.github.io
24
23
  # * https://github.com/pry/pry
25
24
  # * the IRC channel, which is #pry on the Freenode network
26
25
  #
@@ -93,7 +92,6 @@ class Pry
93
92
  @input_ring << nil
94
93
  push_initial_binding(target)
95
94
  exec_hook(:when_started, target, options, self)
96
- @prompt_warn = false
97
95
  end
98
96
 
99
97
  # This is the prompt at the top of the prompt stack.
@@ -388,7 +386,7 @@ class Pry
388
386
  # @param [*Object] args The arguments to pass to the hook
389
387
  # @return [Object, Exception] The return value of the hook or the exception raised
390
388
  #
391
- # If executing a hook raises an exception, we log that and then continue sucessfully.
389
+ # If executing a hook raises an exception, we log that and then continue successfully.
392
390
  # To debug such errors, use the global variable $pry_hook_error, which is set as a
393
391
  # result.
394
392
  def exec_hook(name, *args, &block)
@@ -452,45 +450,17 @@ class Pry
452
450
  # @return [String] The prompt.
453
451
  def select_prompt
454
452
  object = current_binding.eval('self')
455
- open_token = @indent.open_delimiters.last || @indent.stack.last
456
-
457
- c = OpenStruct.new(
458
- object: object,
459
- nesting_level: binding_stack.size - 1,
460
- open_token: open_token,
461
- session_line: Pry.history.session_line_count + 1,
462
- history_line: Pry.history.history_line_count + 1,
463
- expr_number: input_ring.count,
464
- pry_instance: self,
465
- binding_stack: binding_stack,
466
- input_ring: input_ring,
467
- eval_string: @eval_string,
468
- cont: !@eval_string.empty?
469
- )
453
+ nesting_level = binding_stack.size - 1
454
+ pry_instance = self
470
455
 
471
456
  Pry.critical_section do
472
457
  # If input buffer is empty, then use normal prompt. Otherwise use the wait
473
458
  # prompt (indicating multi-line expression).
474
459
  if prompt.is_a?(Pry::Prompt)
475
460
  prompt_proc = eval_string.empty? ? prompt.wait_proc : prompt.incomplete_proc
476
- return prompt_proc.call(c.object, c.nesting_level, c.pry_instance)
477
- end
478
-
479
- unless @prompt_warn
480
- @prompt_warn = true
481
- Kernel.warn(
482
- "warning: setting prompt with help of " \
483
- "`Pry.config.prompt = [proc {}, proc {}]` is deprecated. " \
484
- "Use Pry::Prompt API instead"
485
- )
486
- end
487
-
488
- # If input buffer is empty then use normal prompt
489
- if eval_string.empty?
490
- generate_prompt(Array(prompt).first, c)
491
- # Otherwise use the wait prompt (indicating multi-line expression)
461
+ return prompt_proc.call(object, nesting_level, pry_instance)
492
462
  else
493
- generate_prompt(Array(prompt).last, c)
463
+ output.puts "ERROR: Use Pry::Prompt API."
494
464
  end
495
465
  end
496
466
  end
@@ -549,7 +519,7 @@ class Pry
549
519
  # and a mistake in specifying that exception.
550
520
  #
551
521
  # (i.e. raise-up RunThymeError.new should not be the same as
552
- # raise-up NameError, "unititialized constant RunThymeError")
522
+ # raise-up NameError, "uninitialized constant RunThymeError")
553
523
  #
554
524
  def raise_up_common(force, *args)
555
525
  exception = if args == []
@@ -685,14 +655,6 @@ class Pry
685
655
  end
686
656
  end
687
657
 
688
- def generate_prompt(prompt_proc, conf)
689
- if prompt_proc.arity == 1
690
- prompt_proc.call(conf)
691
- else
692
- prompt_proc.call(conf.object, conf.nesting_level, conf.pry_instance)
693
- end
694
- end
695
-
696
658
  # the array that the prompt stack is stored in
697
659
  def prompt_stack
698
660
  @prompt_stack ||= []
data/lib/pry/repl.rb CHANGED
@@ -100,7 +100,7 @@ class Pry
100
100
  # Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
101
101
  return val unless val.is_a?(String)
102
102
 
103
- if pry.config.auto_indent
103
+ if pry.config.auto_indent && !input_multiline?
104
104
  original_val = "#{indentation}#{val}"
105
105
  indented_val = @indent.indent(val)
106
106
 
@@ -141,8 +141,7 @@ class Pry
141
141
  retry
142
142
 
143
143
  # Handle <Ctrl+C> like Bash: empty the current input buffer, but don't
144
- # quit. This is only for MRI 1.9; other versions of Ruby don't let you
145
- # send Interrupt from within Readline.
144
+ # quit.
146
145
  rescue Interrupt
147
146
  return :control_c
148
147
 
@@ -180,7 +179,31 @@ class Pry
180
179
  end
181
180
  end
182
181
 
183
- if readline_available?
182
+ if reline_available?
183
+ Reline.output_modifier_proc = lambda do |text, _|
184
+ if pry.color
185
+ SyntaxHighlighter.highlight(text)
186
+ else
187
+ text
188
+ end
189
+ end
190
+
191
+ if pry.config.auto_indent
192
+ Reline.auto_indent_proc = lambda do |lines, line_index, _byte_ptr, _newline|
193
+ if line_index == 0
194
+ 0
195
+ else
196
+ pry_indentation = Pry::Indent.new
197
+ pry_indentation.indent(lines.join("\n"))
198
+ pry_indentation.last_indent_level.length
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ if input_multiline?
205
+ input_readmultiline(current_prompt, false)
206
+ elsif readline_available?
184
207
  set_readline_output
185
208
  input_readline(current_prompt, false) # false since we'll add it manually
186
209
  elsif coolline_available?
@@ -193,12 +216,29 @@ class Pry
193
216
  end
194
217
  end
195
218
 
219
+ def input_readmultiline(*args)
220
+ Pry::InputLock.for(:all).interruptible_region do
221
+ input.readmultiline(*args) do |multiline_input|
222
+ Pry.commands.find_command(multiline_input) ||
223
+ (complete_expression?(multiline_input) && !Reline::IOGate.in_pasting?)
224
+ end
225
+ end
226
+ end
227
+
196
228
  def input_readline(*args)
197
229
  Pry::InputLock.for(:all).interruptible_region do
198
230
  input.readline(*args)
199
231
  end
200
232
  end
201
233
 
234
+ def input_multiline?
235
+ !!pry.config.multiline && reline_available?
236
+ end
237
+
238
+ def reline_available?
239
+ defined?(Reline) && input == Reline
240
+ end
241
+
202
242
  def readline_available?
203
243
  defined?(Readline) && input == Readline
204
244
  end
@@ -207,6 +247,20 @@ class Pry
207
247
  defined?(Coolline) && input.is_a?(Coolline)
208
248
  end
209
249
 
250
+ def prism_available?
251
+ @prism_available ||= begin
252
+ # rubocop:disable Lint/SuppressedException
253
+ begin
254
+ require 'prism'
255
+ rescue LoadError
256
+ end
257
+ # rubocop:enable Lint/SuppressedException
258
+
259
+ defined?(Prism::VERSION) &&
260
+ Gem::Version.new(Prism::VERSION) >= Gem::Version.new('0.25.0')
261
+ end
262
+ end
263
+
210
264
  # If `$stdout` is not a tty, it's probably a pipe.
211
265
  # @example
212
266
  # # `piping?` returns `false`
@@ -228,6 +282,21 @@ class Pry
228
282
  @readline_output = (Readline.output = Pry.config.output) if piping?
229
283
  end
230
284
 
285
+ UNEXPECTED_TOKENS = %i[unexpected_token_ignore lambda_open].freeze
286
+
287
+ def complete_expression?(multiline_input)
288
+ if prism_available?
289
+ lex = Prism.lex(multiline_input)
290
+
291
+ errors = lex.errors
292
+ return true if errors.empty?
293
+
294
+ errors.any? { |error| UNEXPECTED_TOKENS.include?(error.type) }
295
+ else
296
+ Pry::Code.complete_expression?(multiline_input)
297
+ end
298
+ end
299
+
231
300
  # Calculates correct overhang for current line. Supports vi Readline
232
301
  # mode and its indicators such as "(ins)" or "(cmd)".
233
302
  #
data/lib/pry/ring.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  class Pry
4
4
  # A ring is a thread-safe fixed-capacity array to which you can only add
5
5
  # elements. Older entries are overwritten as you add new elements, so that the
6
- # ring can never contain more than `max_size` elemens.
6
+ # ring can never contain more than `max_size` elements.
7
7
  #
8
8
  # @example
9
9
  # ring = Pry::Ring.new(3)
@@ -56,8 +56,8 @@ class Pry
56
56
  # exist
57
57
  def [](index)
58
58
  @mutex.synchronize do
59
- return @buffer[(count + index) % max_size] if index.is_a?(Integer)
60
59
  return @buffer[index] if count <= max_size
60
+ return @buffer[(count + index) % max_size] if index.is_a?(Integer)
61
61
 
62
62
  transpose_buffer_tail[index]
63
63
  end
data/lib/pry/slop.rb CHANGED
@@ -73,7 +73,7 @@ class Pry
73
73
  # Build a Slop object from a option specification.
74
74
  #
75
75
  # This allows you to design your options via a simple String rather
76
- # than programatically. Do note though that with this method, you're
76
+ # than programmatically. Do note though that with this method, you're
77
77
  # unable to pass any advanced options to the on() method when creating
78
78
  # options.
79
79
  #
@@ -11,7 +11,7 @@ class Pry
11
11
  end
12
12
 
13
13
  def self.tokenize(code, language = :ruby)
14
- CodeRay.scan(code, language)
14
+ CodeRay::Scanners[language].new(code).tokens
15
15
  end
16
16
 
17
17
  def self.keyword_token_color
data/lib/pry/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Pry
4
- VERSION = '0.13.1'.freeze
4
+ VERSION = '0.15.2'.freeze
5
5
  end
data/lib/pry/warning.rb CHANGED
@@ -10,16 +10,9 @@ class Pry
10
10
  # @param [String] message
11
11
  # @return [void]
12
12
  def self.warn(message)
13
- if Kernel.respond_to?(:caller_locations)
14
- location = caller_locations(2..2).first
15
- path = location.path
16
- lineno = location.lineno
17
- else
18
- # Ruby 1.9.3 support.
19
- frame = caller[1].split(':') # rubocop:disable Performance/Caller
20
- path = frame.first
21
- lineno = frame[1]
22
- end
13
+ location = caller_locations(2..2).first
14
+ path = location.path
15
+ lineno = location.lineno
23
16
 
24
17
  Kernel.warn("#{path}:#{lineno}: warning: #{message}")
25
18
  end
@@ -20,9 +20,9 @@ class Pry
20
20
 
21
21
  # Methods to delegate to associated `Pry::WrappedModule
22
22
  # instance`.
23
- private_delegates = [:lines_for_file, :method_candidates, :yard_docs?, :name]
24
- public_delegates = [:wrapped, :module?, :class?, :nonblank_name,
25
- :number_of_candidates]
23
+ private_delegates = %i[lines_for_file method_candidates yard_docs? name]
24
+ public_delegates = %i[wrapped module? class? nonblank_name
25
+ number_of_candidates]
26
26
 
27
27
  def_delegators :@wrapper, *public_delegates
28
28
  def_private_delegators :@wrapper, *private_delegates
@@ -98,14 +98,15 @@ class Pry
98
98
  # line number is one-indexed.
99
99
  def first_line_of_module_definition(file, line)
100
100
  searchable_lines = lines_for_file(file)[0..(line - 2)]
101
- searchable_lines.rindex { |v| class_regexes.any? { |r| r =~ v } } + 1
101
+ searchable_lines.rindex { |v| module_definition_first_line?(v) } + 1
102
102
  end
103
103
 
104
- def class_regexes
104
+ def module_definition_first_line?(line)
105
105
  mod_type_string = wrapped.class.to_s.downcase
106
- [/(^|=)\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped.name.split(/::/).last}/,
107
- /^\s*(::)?#{wrapped.name.split(/::/).last}\s*?=\s*?#{wrapped.class}/,
108
- /^\s*(::)?#{wrapped.name.split(/::/).last}\.(class|instance)_eval/]
106
+ wrapped_name_last = wrapped.name.split(/::/).last
107
+ /(^|=)\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped_name_last}/ =~ line ||
108
+ /^\s*(::)?#{wrapped_name_last}\s*?=\s*?#{wrapped.class}/ =~ line ||
109
+ /^\s*(::)?#{wrapped_name_last}\.(class|instance)_eval/ =~ line
109
110
  end
110
111
 
111
112
  # This method is used by `Candidate#source_location` as a
@@ -246,19 +246,14 @@ class Pry
246
246
  method_candidates.count
247
247
  end
248
248
 
249
- # @note On JRuby 1.9 and higher, in certain conditions, this method chucks
250
- # away its ability to be quick (when there are lots of monkey patches,
251
- # like in Rails). However, it should be efficient enough on other rubies.
252
- # @see https://github.com/jruby/jruby/issues/525
253
- # @return [Enumerator, Array] on JRuby 1.9 and higher returns Array, on
254
- # other rubies returns Enumerator
249
+ # @return [Array]
255
250
  def candidates
256
251
  enum = Enumerator.new do |y|
257
252
  (0...number_of_candidates).each do |num|
258
253
  y.yield candidate(num)
259
254
  end
260
255
  end
261
- Helpers::Platform.jruby_19? ? enum.to_a : enum
256
+ enum
262
257
  end
263
258
 
264
259
  # @return [Boolean] Whether YARD docs are available for this module.
@@ -291,7 +286,7 @@ class Pry
291
286
  # highest rank, that is the 'monkey patch' of this module with the
292
287
  # highest number of methods, which contains a source code line that
293
288
  # defines the module. It is considered the 'canonical' definition
294
- # for the module. In the absense of a suitable candidate, the
289
+ # for the module. In the absence of a suitable candidate, the
295
290
  # candidate of rank 0 will be returned, or a CommandError raised if
296
291
  # there are no candidates at all.
297
292
  def primary_candidate
data/lib/pry.rb CHANGED
@@ -13,7 +13,6 @@ require 'pry/helpers'
13
13
 
14
14
  require 'pry/basic_object'
15
15
  require 'pry/prompt'
16
- require 'pry/plugins'
17
16
  require 'pry/code_object'
18
17
  require 'pry/exceptions'
19
18
  require 'pry/hooks'
@@ -35,6 +34,7 @@ require 'pry/env'
35
34
 
36
35
  Pry::Commands = Pry::CommandSet.new unless defined?(Pry::Commands)
37
36
 
37
+ require 'pry/commands/ls/config'
38
38
  require 'pry/commands/ls/jruby_hacks'
39
39
  require 'pry/commands/ls/methods_helper'
40
40
  require 'pry/commands/ls/interrogatable'
@@ -58,6 +58,8 @@ require 'pry/config/memoized_value'
58
58
  require 'pry/config/lazy_value'
59
59
  require 'pry/config'
60
60
 
61
+ require 'pry/input/simple_stdio'
62
+
61
63
  require 'pry/pry_class'
62
64
  require 'pry/pry_instance'
63
65
  require 'pry/inspector'
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.1
4
+ version: 0.15.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mair (banisterfiend)
8
8
  - Conrad Irwin
9
9
  - Ryan Fitzgerald
10
10
  - Kyrylo Silin
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-04-12 00:00:00.000000000 Z
14
+ date: 2024-12-24 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: coderay
@@ -102,6 +102,7 @@ files:
102
102
  - lib/pry/commands/jump_to.rb
103
103
  - lib/pry/commands/list_inspectors.rb
104
104
  - lib/pry/commands/ls.rb
105
+ - lib/pry/commands/ls/config.rb
105
106
  - lib/pry/commands/ls/constants.rb
106
107
  - lib/pry/commands/ls/formatter.rb
107
108
  - lib/pry/commands/ls/globals.rb
@@ -160,6 +161,7 @@ files:
160
161
  - lib/pry/history.rb
161
162
  - lib/pry/hooks.rb
162
163
  - lib/pry/indent.rb
164
+ - lib/pry/input/simple_stdio.rb
163
165
  - lib/pry/input_completer.rb
164
166
  - lib/pry/input_lock.rb
165
167
  - lib/pry/inspector.rb
@@ -171,7 +173,6 @@ files:
171
173
  - lib/pry/object_path.rb
172
174
  - lib/pry/output.rb
173
175
  - lib/pry/pager.rb
174
- - lib/pry/plugins.rb
175
176
  - lib/pry/prompt.rb
176
177
  - lib/pry/pry_class.rb
177
178
  - lib/pry/pry_instance.rb
@@ -201,7 +202,7 @@ metadata:
201
202
  changelog_uri: https://github.com/pry/pry/blob/master/CHANGELOG.md
202
203
  source_code_uri: https://github.com/pry/pry
203
204
  bug_tracker_uri: https://github.com/pry/pry/issues
204
- post_install_message:
205
+ post_install_message:
205
206
  rdoc_options: []
206
207
  require_paths:
207
208
  - lib
@@ -209,15 +210,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
209
210
  requirements:
210
211
  - - ">="
211
212
  - !ruby/object:Gem::Version
212
- version: 1.9.3
213
+ version: '2.0'
213
214
  required_rubygems_version: !ruby/object:Gem::Requirement
214
215
  requirements:
215
216
  - - ">="
216
217
  - !ruby/object:Gem::Version
217
218
  version: '0'
218
219
  requirements: []
219
- rubygems_version: 3.1.2
220
- signing_key:
220
+ rubygems_version: 3.4.14
221
+ signing_key:
221
222
  specification_version: 4
222
223
  summary: A runtime developer console and IRB alternative with powerful introspection
223
224
  capabilities.
data/lib/pry/plugins.rb DELETED
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ostruct'
4
-
5
- class Pry
6
- class PluginManager
7
- PRY_PLUGIN_PREFIX = /^pry-/.freeze
8
-
9
- # Placeholder when no associated gem found, displays warning
10
- class NoPlugin
11
- def initialize(name)
12
- @name = name
13
- end
14
-
15
- def method_missing(*)
16
- warn "Warning: The plugin '#{@name}' was not found! (no gem found)"
17
- super
18
- end
19
-
20
- def respond_to_missing?(*)
21
- false
22
- end
23
- end
24
-
25
- class Plugin
26
- attr_accessor :name, :gem_name, :enabled, :spec, :active
27
-
28
- def initialize(name, gem_name, spec, enabled)
29
- @name = name
30
- @gem_name = gem_name
31
- @enabled = enabled
32
- @spec = spec
33
- end
34
-
35
- # Disable a plugin. (prevents plugin from being loaded, cannot
36
- # disable an already activated plugin)
37
- def disable!
38
- self.enabled = false
39
- end
40
-
41
- # Enable a plugin. (does not load it immediately but puts on
42
- # 'white list' to be loaded)
43
- def enable!
44
- self.enabled = true
45
- end
46
-
47
- # Load the Command line options defined by this plugin (if they exist)
48
- def load_cli_options
49
- cli_options_file = File.join(spec.full_gem_path, "lib/#{spec.name}/cli.rb")
50
- return unless File.exist?(cli_options_file)
51
-
52
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.4.4")
53
- cli_options_file = File.realpath(cli_options_file)
54
- end
55
- require cli_options_file
56
- end
57
-
58
- # Activate the plugin (require the gem - enables/loads the
59
- # plugin immediately at point of call, even if plugin is
60
- # disabled)
61
- # Does not reload plugin if it's already active.
62
- def activate!
63
- # Create the configuration object for the plugin.
64
- Pry.config.send("#{gem_name.tr('-', '_')}=", OpenStruct.new)
65
-
66
- begin
67
- require gem_name unless active?
68
- rescue LoadError => e
69
- warn "Found plugin #{gem_name}, but could not require '#{gem_name}'"
70
- warn e
71
- rescue StandardError => e
72
- warn "require '#{gem_name}' # Failed, saying: #{e}"
73
- end
74
-
75
- self.active = true
76
- self.enabled = true
77
- end
78
-
79
- alias active? active
80
- alias enabled? enabled
81
-
82
- def supported?
83
- pry_version = Gem::Version.new(VERSION)
84
- spec.dependencies.each do |dependency|
85
- if dependency.name == "pry"
86
- return dependency.requirement.satisfied_by?(pry_version)
87
- end
88
- end
89
- true
90
- end
91
- end
92
-
93
- def initialize
94
- @plugins = []
95
- end
96
-
97
- # Find all installed Pry plugins and store them in an internal array.
98
- def locate_plugins
99
- gem_list.each do |gem|
100
- next if gem.name !~ PRY_PLUGIN_PREFIX
101
-
102
- plugin_name = gem.name.split('-', 2).last
103
- plugin = Plugin.new(plugin_name, gem.name, gem, false)
104
- @plugins << plugin.tap(&:enable!) if plugin.supported? && !plugin_located?(plugin)
105
- end
106
- @plugins
107
- end
108
-
109
- # @return [Hash] A hash with all plugin names (minus the 'pry-') as
110
- # keys and Plugin objects as values.
111
- def plugins
112
- h = Hash.new { |_, key| NoPlugin.new(key) }
113
- @plugins.each do |plugin|
114
- h[plugin.name] = plugin
115
- end
116
- h
117
- end
118
-
119
- # Require all enabled plugins, disabled plugins are skipped.
120
- def load_plugins
121
- @plugins.each do |plugin|
122
- plugin.activate! if plugin.enabled?
123
- end
124
- end
125
-
126
- private
127
-
128
- def plugin_located?(plugin)
129
- @plugins.any? { |existing| existing.gem_name == plugin.gem_name }
130
- end
131
-
132
- def gem_list
133
- Gem.refresh
134
- return Gem::Specification if Gem::Specification.respond_to?(:each)
135
-
136
- Gem.source_index.find_name('')
137
- end
138
- end
139
- end