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.
Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +439 -16
  3. data/LICENSE +1 -1
  4. data/README.md +362 -302
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +84 -97
  10. data/lib/pry/code/code_file.rb +37 -26
  11. data/lib/pry/code/code_range.rb +7 -5
  12. data/lib/pry/code/loc.rb +26 -13
  13. data/lib/pry/code.rb +42 -31
  14. data/lib/pry/code_object.rb +53 -28
  15. data/lib/pry/color_printer.rb +46 -35
  16. data/lib/pry/command.rb +197 -369
  17. data/lib/pry/command_set.rb +89 -114
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -72
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -46
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +62 -54
  27. data/lib/pry/commands/cd.rb +40 -35
  28. data/lib/pry/commands/change_inspector.rb +29 -22
  29. data/lib/pry/commands/change_prompt.rb +48 -23
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  36. data/lib/pry/commands/edit.rb +185 -157
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -16
  40. data/lib/pry/commands/find_method.rb +168 -162
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +151 -149
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +35 -28
  47. data/lib/pry/commands/ls/constants.rb +59 -31
  48. data/lib/pry/commands/ls/formatter.rb +42 -36
  49. data/lib/pry/commands/ls/globals.rb +38 -36
  50. data/lib/pry/commands/ls/grep.rb +17 -15
  51. data/lib/pry/commands/ls/instance_vars.rb +29 -28
  52. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  53. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  54. data/lib/pry/commands/ls/local_names.rb +26 -24
  55. data/lib/pry/commands/ls/local_vars.rb +38 -30
  56. data/lib/pry/commands/ls/ls_entity.rb +47 -52
  57. data/lib/pry/commands/ls/methods.rb +49 -51
  58. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  59. data/lib/pry/commands/ls/self_methods.rb +23 -21
  60. data/lib/pry/commands/ls.rb +124 -103
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +92 -82
  63. data/lib/pry/commands/pry_backtrace.rb +22 -17
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +60 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -42
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +56 -29
  71. data/lib/pry/commands/shell_mode.rb +22 -18
  72. data/lib/pry/commands/show_doc.rb +80 -70
  73. data/lib/pry/commands/show_info.rb +194 -155
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +110 -42
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +20 -16
  79. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  80. data/lib/pry/commands/watch_expression.rb +89 -84
  81. data/lib/pry/commands/whereami.rb +156 -141
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +310 -20
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +22 -9
  90. data/lib/pry/editor.rb +56 -34
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +13 -18
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +20 -62
  96. data/lib/pry/helpers/command_helpers.rb +52 -62
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -12
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +55 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -85
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +81 -55
  104. data/lib/pry/hooks.rb +60 -110
  105. data/lib/pry/indent.rb +74 -68
  106. data/lib/pry/input_completer.rb +199 -158
  107. data/lib/pry/input_lock.rb +7 -10
  108. data/lib/pry/inspector.rb +36 -24
  109. data/lib/pry/last_exception.rb +45 -45
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/method/patcher.rb +14 -8
  112. data/lib/pry/method/weird_method_locator.rb +79 -45
  113. data/lib/pry/method.rb +178 -124
  114. data/lib/pry/object_path.rb +37 -28
  115. data/lib/pry/output.rb +102 -16
  116. data/lib/pry/pager.rb +187 -174
  117. data/lib/pry/prompt.rb +213 -25
  118. data/lib/pry/pry_class.rb +119 -98
  119. data/lib/pry/pry_instance.rb +261 -224
  120. data/lib/pry/repl.rb +83 -29
  121. data/lib/pry/repl_file_loader.rb +27 -22
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +35 -32
  138. data/lib/pry/wrapped_module.rb +68 -63
  139. data/lib/pry.rb +133 -149
  140. metadata +58 -69
  141. data/lib/pry/commands/disabled_commands.rb +0 -2
  142. data/lib/pry/commands/gem_cd.rb +0 -26
  143. data/lib/pry/commands/gem_install.rb +0 -32
  144. data/lib/pry/commands/gem_list.rb +0 -33
  145. data/lib/pry/commands/gem_open.rb +0 -29
  146. data/lib/pry/commands/gist.rb +0 -101
  147. data/lib/pry/commands/install_command.rb +0 -53
  148. data/lib/pry/commands/list_prompts.rb +0 -35
  149. data/lib/pry/commands/simple_prompt.rb +0 -22
  150. data/lib/pry/commands.rb +0 -6
  151. data/lib/pry/config/behavior.rb +0 -139
  152. data/lib/pry/config/convenience.rb +0 -25
  153. data/lib/pry/config/default.rb +0 -161
  154. data/lib/pry/history_array.rb +0 -121
  155. data/lib/pry/plugins.rb +0 -103
  156. data/lib/pry/rbx_path.rb +0 -22
  157. data/lib/pry/rubygem.rb +0 -82
  158. data/lib/pry/terminal.rb +0 -79
  159. data/lib/pry/test/helper.rb +0 -170
data/lib/pry/prompt.rb CHANGED
@@ -1,26 +1,214 @@
1
- class Pry::Prompt
2
- MAP = {
3
- "default" => {
4
- value: Pry::DEFAULT_PROMPT,
5
- description: "The default Pry prompt. Includes information about the\n" \
6
- "current expression number, evaluation context, and nesting\n" \
7
- "level, plus a reminder that you're using Pry."
8
- },
9
-
10
- "simple" => {
11
- value: Pry::SIMPLE_PROMPT,
12
- description: "A simple '>>'."
13
- },
14
-
15
- "nav" => {
16
- value: Pry::NAV_PROMPT,
17
- description: "A prompt that displays the binding stack as a path and\n" \
18
- "includes information about _in_ and _out_."
19
- },
20
-
21
- "none" => {
22
- value: Pry::NO_PROMPT,
23
- description: "Wave goodbye to the Pry prompt."
24
- }
25
- }
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # Prompt represents the Pry prompt, which can be used with Readline-like
5
+ # libraries. It defines a few default prompts (default prompt, simple prompt,
6
+ # etc) and also provides an API for adding and implementing custom prompts.
7
+ #
8
+ # @example Registering a new Pry prompt
9
+ # Pry::Prompt.add(
10
+ # :ipython,
11
+ # 'IPython-like prompt', [':', '...:']
12
+ # ) do |_context, _nesting, pry_instance, sep|
13
+ # sep == ':' ? "In [#{pry_instance.input_ring.count}]: " : ' ...: '
14
+ # end
15
+ #
16
+ # # Produces:
17
+ # # In [3]: def foo
18
+ # # ...: puts 'foo'
19
+ # # ...: end
20
+ # # => :foo
21
+ # # In [4]:
22
+ #
23
+ # @example Manually instantiating the Prompt class
24
+ # prompt_procs = [
25
+ # proc { '#{rand(1)}>" },
26
+ # proc { "#{('a'..'z').to_a.sample}*" }
27
+ # ]
28
+ # prompt = Pry::Prompt.new(
29
+ # :random,
30
+ # 'Random number or letter prompt.',
31
+ # prompt_procs
32
+ # )
33
+ # prompt.wait_proc.call(...) #=>
34
+ # prompt.incomplete_proc.call(...)
35
+ #
36
+ # @since v0.11.0
37
+ # @api public
38
+ class Prompt
39
+ # A Hash that holds all prompts. The keys of the Hash are prompt
40
+ # names, the values are Hash instances of the format {:description, :value}.
41
+ @prompts = {}
42
+
43
+ class << self
44
+ # Retrieves a prompt.
45
+ #
46
+ # @example
47
+ # Prompt[:my_prompt]
48
+ #
49
+ # @param [Symbol] name The name of the prompt you want to access
50
+ # @return [Hash{Symbol=>Object}]
51
+ # @since v0.12.0
52
+ def [](name)
53
+ @prompts[name.to_s]
54
+ end
55
+
56
+ # @return [Hash{Symbol=>Hash}] the duplicate of the internal prompts hash
57
+ # @note Use this for read-only operations
58
+ # @since v0.12.0
59
+ def all
60
+ @prompts.dup
61
+ end
62
+
63
+ # Adds a new prompt to the prompt hash.
64
+ #
65
+ # @param [Symbol] name
66
+ # @param [String] description
67
+ # @param [Array<String>] separators The separators to differentiate
68
+ # between prompt modes (default mode and class/method definition mode).
69
+ # The Array *must* have a size of 2.
70
+ # @yield [context, nesting, pry_instance, sep]
71
+ # @yieldparam context [Object] the context where Pry is currently in
72
+ # @yieldparam nesting [Integer] whether the context is nested
73
+ # @yieldparam pry_instance [Pry] the Pry instance
74
+ # @yieldparam separator [String] separator string
75
+ # @return [nil]
76
+ # @raise [ArgumentError] if the size of `separators` is not 2
77
+ # @raise [ArgumentError] if `prompt_name` is already occupied
78
+ # @since v0.12.0
79
+ def add(name, description = '', separators = %w[> *])
80
+ name = name.to_s
81
+
82
+ unless separators.size == 2
83
+ raise ArgumentError, "separators size must be 2, given #{separators.size}"
84
+ end
85
+
86
+ if @prompts.key?(name)
87
+ raise ArgumentError, "the '#{name}' prompt was already added"
88
+ end
89
+
90
+ @prompts[name] = new(
91
+ name,
92
+ description,
93
+ separators.map do |sep|
94
+ proc do |context, nesting, pry_instance|
95
+ yield(context, nesting, pry_instance, sep)
96
+ end
97
+ end
98
+ )
99
+
100
+ nil
101
+ end
102
+ end
103
+
104
+ # @return [String]
105
+ attr_reader :name
106
+
107
+ # @return [String]
108
+ attr_reader :description
109
+
110
+ # @return [Array<Proc>] the array of procs that hold
111
+ # `[wait_proc, incomplete_proc]`
112
+ attr_reader :prompt_procs
113
+
114
+ # @param [String] name
115
+ # @param [String] description
116
+ # @param [Array<Proc>] prompt_procs
117
+ def initialize(name, description, prompt_procs)
118
+ @name = name
119
+ @description = description
120
+ @prompt_procs = prompt_procs
121
+ end
122
+
123
+ # @return [Proc] the proc which builds the wait prompt (`>`)
124
+ def wait_proc
125
+ @prompt_procs.first
126
+ end
127
+
128
+ # @return [Proc] the proc which builds the prompt when in the middle of an
129
+ # expression such as open method, etc. (`*`)
130
+ def incomplete_proc
131
+ @prompt_procs.last
132
+ end
133
+
134
+ # @deprecated Use a `Pry::Prompt` instance directly
135
+ def [](key)
136
+ key = key.to_s
137
+ if %w[name description].include?(key)
138
+ Pry::Warning.warn(
139
+ "`Pry::Prompt[:#{@name}][:#{key}]` is deprecated. " \
140
+ "Use `#{self.class}##{key}` instead"
141
+ )
142
+ public_send(key)
143
+ elsif key.to_s == 'value'
144
+ Pry::Warning.warn(
145
+ "`#{self.class}[:#{@name}][:value]` is deprecated. Use " \
146
+ "`#{self.class}#prompt_procs` instead or an instance of " \
147
+ "`#{self.class}` directly"
148
+ )
149
+ @prompt_procs
150
+ end
151
+ end
152
+
153
+ add(
154
+ :default,
155
+ "The default Pry prompt. Includes information about the current expression \n" \
156
+ "number, evaluation context, and nesting level, plus a reminder that you're \n" \
157
+ 'using Pry.'
158
+ ) do |context, nesting, pry_instance, sep|
159
+ format(
160
+ "[%<in_count>s] %<name>s(%<context>s)%<nesting>s%<separator>s ",
161
+ in_count: pry_instance.input_ring.count,
162
+ name: pry_instance.config.prompt_name,
163
+ context: Pry.view_clip(context),
164
+ nesting: (nesting > 0 ? ":#{nesting}" : ''),
165
+ separator: sep
166
+ )
167
+ end
168
+
169
+ add(
170
+ :simple,
171
+ "A simple `>>`.",
172
+ ['>> ', ' | ']
173
+ ) do |_, _, _, sep|
174
+ sep
175
+ end
176
+
177
+ add(
178
+ :nav,
179
+ "A prompt that displays the binding stack as a path and includes information \n" \
180
+ "about #{Helpers::Text.bold('_in_')} and #{Helpers::Text.bold('_out_')}.",
181
+ %w[> *]
182
+ ) do |_context, _nesting, pry_instance, sep|
183
+ tree = pry_instance.binding_stack.map { |b| Pry.view_clip(b.eval('self')) }
184
+ format(
185
+ "[%<in_count>s] (%<name>s) %<tree>s: %<stack_size>s%<separator>s ",
186
+ in_count: pry_instance.input_ring.count,
187
+ name: pry_instance.config.prompt_name,
188
+ tree: tree.join(' / '),
189
+ stack_size: pry_instance.binding_stack.size - 1,
190
+ separator: sep
191
+ )
192
+ end
193
+
194
+ add(
195
+ :shell,
196
+ 'A prompt that displays `$PWD` as you change it.',
197
+ %w[$ *]
198
+ ) do |context, _nesting, pry_instance, sep|
199
+ format(
200
+ "%<name>s %<context>s:%<pwd>s %<separator>s ",
201
+ name: pry_instance.config.prompt_name,
202
+ context: Pry.view_clip(context),
203
+ pwd: Dir.pwd,
204
+ separator: sep
205
+ )
206
+ end
207
+
208
+ add(
209
+ :none,
210
+ 'Wave goodbye to the Pry prompt.',
211
+ Array.new(2)
212
+ ) { '' }
213
+ end
26
214
  end
data/lib/pry/pry_class.rb CHANGED
@@ -1,11 +1,20 @@
1
- require 'pry/config'
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+ require 'pathname'
5
+
2
6
  class Pry
7
+ LOCAL_RC_FILE = "./.pryrc".freeze
3
8
 
4
- HOME_RC_FILE = ENV["PRYRC"] || "~/.pryrc"
5
- LOCAL_RC_FILE = "./.pryrc"
9
+ # @return [Boolean] true if this Ruby supports safe levels and tainting,
10
+ # to guard against using deprecated or unsupported features
11
+ HAS_SAFE_LEVEL = (
12
+ RUBY_ENGINE == 'ruby' &&
13
+ Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7')
14
+ )
6
15
 
7
16
  class << self
8
- extend Forwardable
17
+ extend Pry::Forwardable
9
18
  attr_accessor :custom_completions
10
19
  attr_accessor :current_line
11
20
  attr_accessor :line_buffer
@@ -14,23 +23,28 @@ class Pry
14
23
  attr_accessor :quiet
15
24
  attr_accessor :last_internal_error
16
25
  attr_accessor :config
17
- attr_writer :history
18
-
19
- def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
20
26
 
21
- extend Pry::Config::Convenience
22
- config_shortcut(*Pry::Config.shortcuts)
23
-
24
- def prompt=(value)
25
- config.prompt = value
26
- end
27
-
28
- def prompt
29
- config.prompt
30
- end
31
-
32
- def history
33
- @history ||= History.new
27
+ def_delegators(
28
+ :@config, :input, :input=, :output, :output=, :commands,
29
+ :commands=, :print, :print=, :exception_handler, :exception_handler=,
30
+ :hooks, :hooks=, :color, :color=, :pager, :pager=, :editor, :editor=,
31
+ :memory_size, :memory_size=, :extra_sticky_locals, :extra_sticky_locals=,
32
+ :prompt, :prompt=, :history, :history=
33
+ )
34
+
35
+ #
36
+ # @example
37
+ # Pry.configure do |config|
38
+ # config.eager_load! # optional
39
+ # config.input = # ..
40
+ # config.foo = 2
41
+ # end
42
+ #
43
+ # @yield [config]
44
+ # Yields a block with {Pry.config} as its argument.
45
+ #
46
+ def configure
47
+ yield config
34
48
  end
35
49
  end
36
50
 
@@ -47,7 +61,7 @@ class Pry
47
61
  # Returns a value store for an instance of Pry running on the current thread.
48
62
  #
49
63
  def self.current
50
- Thread.current[:__pry__] ||= Pry::Config.from_hash({}, nil)
64
+ Thread.current[:__pry__] ||= {}
51
65
  end
52
66
 
53
67
  # Load the given file in the context of `Pry.toplevel_binding`
@@ -58,8 +72,8 @@ class Pry
58
72
  puts "Error loading #{file}: #{e}\n#{e.backtrace.first}"
59
73
  end
60
74
 
61
- # Load HOME_RC_FILE and LOCAL_RC_FILE if appropriate
62
- # This method can also be used to reload the files if they have changed.
75
+ # Load RC files if appropriate This method can also be used to reload the
76
+ # files if they have changed.
63
77
  def self.load_rc_files
64
78
  rc_files_to_load.each do |file|
65
79
  critical_section do
@@ -71,17 +85,15 @@ class Pry
71
85
  # Load the local RC file (./.pryrc)
72
86
  def self.rc_files_to_load
73
87
  files = []
74
- files << HOME_RC_FILE if Pry.config.should_load_rc
88
+ files << Pry.config.rc_file if Pry.config.rc_file && Pry.config.should_load_rc
75
89
  files << LOCAL_RC_FILE if Pry.config.should_load_local_rc
76
90
  files.map { |file| real_path_to(file) }.compact.uniq
77
91
  end
78
92
 
79
93
  # Expand a file to its canonical name (following symlinks as appropriate)
80
94
  def self.real_path_to(file)
81
- expanded = Pathname.new(File.expand_path(file)).realpath.to_s
82
- # For rbx 1.9 mode [see rubinius issue #2165]
83
- File.exist?(expanded) ? expanded : nil
84
- rescue Errno::ENOENT
95
+ Pathname.new(File.expand_path(file)).realpath.to_s
96
+ rescue Errno::ENOENT, Errno::EACCES
85
97
  nil
86
98
  end
87
99
 
@@ -95,63 +107,76 @@ class Pry
95
107
  # Trap interrupts on jruby, and make them behave like MRI so we can
96
108
  # catch them.
97
109
  def self.load_traps
98
- trap('INT'){ raise Interrupt }
110
+ trap('INT') { raise Interrupt }
99
111
  end
100
112
 
101
113
  def self.load_win32console
102
- begin
103
- require 'win32console'
104
- # The mswin and mingw versions of pry require win32console, so this should
105
- # only fail on jruby (where win32console doesn't work).
106
- # Instead we'll recommend ansicon, which does.
107
- rescue LoadError
108
- warn <<-WARNING if Pry.config.windows_console_warning
114
+ require 'win32console'
115
+ # The mswin and mingw versions of pry require win32console, so this should
116
+ # only fail on jruby (where win32console doesn't work).
117
+ # Instead we'll recommend ansicon, which does.
118
+ rescue LoadError
119
+ warn <<-WARNING if Pry.config.windows_console_warning
109
120
  For a better Pry experience on Windows, please use ansicon:
110
121
  https://github.com/adoxa/ansicon
111
122
  If you use an alternative to ansicon and don't want to see this warning again,
112
- you can add "Pry.config.windows_console_warning = false" to your .pryrc.
113
- WARNING
114
- end
123
+ you can add "Pry.config.windows_console_warning = false" to your pryrc.
124
+ WARNING
115
125
  end
116
126
 
117
- # Do basic setup for initial session.
118
- # Including: loading .pryrc, loading plugins, loading requires, and
119
- # loading history.
127
+ # Do basic setup for initial session including: loading pryrc, plugins,
128
+ # requires, and history.
120
129
  def self.initial_session_setup
121
130
  return unless initial_session?
131
+
122
132
  @initial_session = false
123
133
 
124
- # note these have to be loaded here rather than in pry_instance as
134
+ # note these have to be loaded here rather than in _pry_ as
125
135
  # we only want them loaded once per entire Pry lifetime.
126
136
  load_rc_files
127
- load_plugins if Pry.config.should_load_plugins
137
+ end
138
+
139
+ def self.final_session_setup
140
+ return if @session_finalized
141
+
142
+ @session_finalized = true
128
143
  load_requires if Pry.config.should_load_requires
129
- load_history if Pry.config.history.should_load
144
+ load_history if Pry.config.history_load
130
145
  load_traps if Pry.config.should_trap_interrupts
131
- load_win32console if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi?
146
+ load_win32console if Helpers::Platform.windows? && !Helpers::Platform.windows_ansi?
132
147
  end
133
148
 
134
149
  # Start a Pry REPL.
135
- # This method also loads `~/.pryrc` and `./.pryrc` as necessary the
136
- # first time it is invoked.
150
+ # This method also loads `pryrc` as necessary the first time it is invoked.
137
151
  # @param [Object, Binding] target The receiver of the Pry session
138
152
  # @param [Hash] options
139
153
  # @option options (see Pry#initialize)
140
154
  # @example
141
155
  # Pry.start(Object.new, :input => MyInput.new)
142
- def self.start(target=nil, options={})
143
- return if ENV['DISABLE_PRY']
156
+ def self.start(target = nil, options = {})
157
+ return if Pry::Env['DISABLE_PRY']
158
+ if Pry::Env['FAIL_PRY']
159
+ raise 'You have FAIL_PRY set to true, which results in Pry calls failing'
160
+ end
161
+
144
162
  options = options.to_hash
145
163
 
146
164
  if in_critical_section?
147
165
  output.puts "ERROR: Pry started inside Pry."
148
- output.puts "This can happen if you have a binding.pry inside a #to_s or #inspect function."
166
+ output.puts "This can happen if you have a binding.pry inside a #to_s " \
167
+ "or #inspect function."
168
+ return
169
+ end
170
+
171
+ unless mutex_available?
172
+ output.puts "ERROR: Unable to obtain mutex lock."
173
+ output.puts "This can happen if binding.pry is called from a signal handler"
149
174
  return
150
175
  end
151
176
 
152
177
  options[:target] = Pry.binding_for(target || toplevel_binding)
153
- options[:hooks] = Pry::Hooks.from_hash options.delete(:hooks) if options.key?(:hooks)
154
178
  initial_session_setup
179
+ final_session_setup
155
180
 
156
181
  # Unless we were given a backtrace, save the current one
157
182
  if options[:backtrace].nil?
@@ -175,7 +200,6 @@ you can add "Pry.config.windows_console_warning = false" to your .pryrc.
175
200
  # Execute the file through the REPL loop, non-interactively.
176
201
  # @param [String] file_name File name to load through the REPL.
177
202
  def self.load_file_through_repl(file_name)
178
- require "pry/repl_file_loader"
179
203
  REPLFileLoader.new(file_name).load
180
204
  end
181
205
 
@@ -201,17 +225,23 @@ you can add "Pry.config.windows_console_warning = false" to your .pryrc.
201
225
  def self.view_clip(obj, options = {})
202
226
  max = options.fetch :max_length, 60
203
227
  id = options.fetch :id, false
204
- if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max
228
+ if obj.is_a?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max
205
229
  obj.name.to_s
206
230
  elsif Pry.main == obj
207
- # special-case to support jruby.
208
- # fixed as of https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039
231
+ # Special-case to support jruby. Fixed as of:
232
+ # https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039
209
233
  # we can drop in the future.
210
234
  obj.to_s
211
- elsif Pry.config.prompt_safe_objects.any? { |v| v === obj } && obj.inspect.length <= max
235
+ # rubocop:disable Style/CaseEquality
236
+ elsif Pry.config.prompt_safe_contexts.any? { |v| v === obj } &&
237
+ obj.inspect.length <= max
238
+ # rubocop:enable Style/CaseEquality
239
+
212
240
  obj.inspect
241
+ elsif id
242
+ format("#<#{obj.class}:0x%<id>x>", id: obj.object_id << 1)
213
243
  else
214
- id == true ? "#<#{obj.class}:0x%x>" % (obj.object_id << 1) : "#<#{obj.class}>"
244
+ "#<#{obj.class}>"
215
245
  end
216
246
  rescue RescuableException
217
247
  "unknown"
@@ -233,7 +263,7 @@ you can add "Pry.config.windows_console_warning = false" to your .pryrc.
233
263
  # @param [String] command_string The Pry command (including arguments,
234
264
  # if any).
235
265
  # @param [Hash] options Optional named parameters.
236
- # @return [Object] The return value of the Pry command.
266
+ # @return [nil]
237
267
  # @option options [Object, Binding] :target The object to run the
238
268
  # command under. Defaults to `TOPLEVEL_BINDING` (main).
239
269
  # @option options [Boolean] :show_output Whether to show command
@@ -244,32 +274,21 @@ you can add "Pry.config.windows_console_warning = false" to your .pryrc.
244
274
  # Pry.run_command "ls -m", :target => Pry
245
275
  # @example Display command output.
246
276
  # Pry.run_command "ls -av", :show_output => true
247
- def self.run_command(command_string, options={})
277
+ def self.run_command(command_string, options = {})
248
278
  options = {
249
- :target => TOPLEVEL_BINDING,
250
- :show_output => true,
251
- :output => Pry.config.output,
252
- :commands => Pry.config.commands
279
+ target: TOPLEVEL_BINDING,
280
+ show_output: true,
281
+ output: Pry.config.output,
282
+ commands: Pry.config.commands
253
283
  }.merge!(options)
254
284
 
255
285
  # :context for compatibility with <= 0.9.11.4
256
286
  target = options[:context] || options[:target]
257
287
  output = options[:show_output] ? options[:output] : StringIO.new
258
288
 
259
- pry = Pry.new(:output => output, :target => target, :commands => options[:commands])
289
+ pry = Pry.new(output: output, target: target, commands: options[:commands])
260
290
  pry.eval command_string
261
- end
262
-
263
- def self.default_editor_for_platform
264
- return ENV['VISUAL'] if ENV['VISUAL'] and not ENV['VISUAL'].empty?
265
- return ENV['EDITOR'] if ENV['EDITOR'] and not ENV['EDITOR'].empty?
266
- if Helpers::BaseHelpers.windows?
267
- 'notepad'
268
- else
269
- %w(editor nano vi).detect do |editor|
270
- system("which #{editor} > /dev/null 2>&1")
271
- end
272
- end
291
+ nil
273
292
  end
274
293
 
275
294
  def self.auto_resize!
@@ -281,23 +300,23 @@ you can add "Pry.config.windows_console_warning = false" to your .pryrc.
281
300
  end
282
301
 
283
302
  if Readline::VERSION =~ /edit/i
284
- warn <<-EOT
303
+ warn(<<-WARN)
285
304
  Readline version #{Readline::VERSION} detected - will not auto_resize! correctly.
286
305
  For the fix, use GNU Readline instead:
287
- https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X
288
- EOT
306
+ https://github.com/guard/guard/wiki/Add-Readline-support-to-Ruby-on-Mac-OS-X
307
+ WARN
289
308
  return
290
309
  end
291
310
 
292
311
  trap :WINCH do
293
312
  begin
294
- Readline.set_screen_size(*Terminal.size!)
295
- rescue => e
313
+ Readline.set_screen_size(*output.size)
314
+ rescue StandardError => e
296
315
  warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}"
297
316
  end
298
317
  begin
299
318
  Readline.refresh_line
300
- rescue => e
319
+ rescue StandardError => e
301
320
  warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}"
302
321
  end
303
322
  end
@@ -306,7 +325,9 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
306
325
  # Set all the configurable options back to their default values
307
326
  def self.reset_defaults
308
327
  @initial_session = true
309
- self.config = Pry::Config.new Pry::Config::Default.new
328
+ @session_finalized = nil
329
+
330
+ self.config = Pry::Config.new
310
331
  self.cli = false
311
332
  self.current_line = 1
312
333
  self.line_buffer = [""]
@@ -315,9 +336,7 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
315
336
 
316
337
  # Basic initialization.
317
338
  def self.init
318
- @plugin_manager ||= PluginManager.new
319
339
  reset_defaults
320
- locate_plugins
321
340
  end
322
341
 
323
342
  # Return a `Binding` object for `target` or return `target` if it is
@@ -326,15 +345,10 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
326
345
  # @param [Object] target The object to get a `Binding` object for.
327
346
  # @return [Binding] The `Binding` object.
328
347
  def self.binding_for(target)
329
- if Binding === target
330
- target
331
- else
332
- if Pry.main == target
333
- TOPLEVEL_BINDING
334
- else
335
- target.__binding__
336
- end
337
- end
348
+ return target if Binding === target # rubocop:disable Style/CaseEquality
349
+ return TOPLEVEL_BINDING if Pry.main == target
350
+
351
+ target.__binding__
338
352
  end
339
353
 
340
354
  def self.toplevel_binding
@@ -354,8 +368,8 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
354
368
  @toplevel_binding
355
369
  end
356
370
 
357
- def self.toplevel_binding=(binding)
358
- @toplevel_binding = binding
371
+ class << self
372
+ attr_writer :toplevel_binding
359
373
  end
360
374
 
361
375
  def self.in_critical_section?
@@ -363,13 +377,20 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
363
377
  Thread.current[:pry_critical_section] > 0
364
378
  end
365
379
 
366
- def self.critical_section(&block)
380
+ def self.critical_section
367
381
  Thread.current[:pry_critical_section] ||= 0
368
382
  Thread.current[:pry_critical_section] += 1
369
383
  yield
370
384
  ensure
371
385
  Thread.current[:pry_critical_section] -= 1
372
386
  end
387
+
388
+ def self.mutex_available?
389
+ Mutex.new.synchronize { true }
390
+ rescue ThreadError
391
+ false
392
+ end
393
+ private_class_method :mutex_available?
373
394
  end
374
395
 
375
396
  Pry.init