pry 0.10.0.pre2-universal-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +702 -0
  3. data/LICENSE +25 -0
  4. data/README.md +406 -0
  5. data/bin/pry +16 -0
  6. data/lib/pry.rb +161 -0
  7. data/lib/pry/cli.rb +220 -0
  8. data/lib/pry/code.rb +346 -0
  9. data/lib/pry/code/code_file.rb +103 -0
  10. data/lib/pry/code/code_range.rb +71 -0
  11. data/lib/pry/code/loc.rb +92 -0
  12. data/lib/pry/code_object.rb +172 -0
  13. data/lib/pry/color_printer.rb +55 -0
  14. data/lib/pry/command.rb +692 -0
  15. data/lib/pry/command_set.rb +443 -0
  16. data/lib/pry/commands.rb +6 -0
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +62 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +77 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +67 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +41 -0
  26. data/lib/pry/commands/change_inspector.rb +27 -0
  27. data/lib/pry/commands/change_prompt.rb +26 -0
  28. data/lib/pry/commands/code_collector.rb +165 -0
  29. data/lib/pry/commands/disable_pry.rb +27 -0
  30. data/lib/pry/commands/disabled_commands.rb +2 -0
  31. data/lib/pry/commands/easter_eggs.rb +112 -0
  32. data/lib/pry/commands/edit.rb +195 -0
  33. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  34. data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
  35. data/lib/pry/commands/exit.rb +42 -0
  36. data/lib/pry/commands/exit_all.rb +29 -0
  37. data/lib/pry/commands/exit_program.rb +23 -0
  38. data/lib/pry/commands/find_method.rb +193 -0
  39. data/lib/pry/commands/fix_indent.rb +19 -0
  40. data/lib/pry/commands/gem_cd.rb +26 -0
  41. data/lib/pry/commands/gem_install.rb +32 -0
  42. data/lib/pry/commands/gem_list.rb +33 -0
  43. data/lib/pry/commands/gem_open.rb +29 -0
  44. data/lib/pry/commands/gist.rb +101 -0
  45. data/lib/pry/commands/help.rb +164 -0
  46. data/lib/pry/commands/hist.rb +180 -0
  47. data/lib/pry/commands/import_set.rb +22 -0
  48. data/lib/pry/commands/install_command.rb +53 -0
  49. data/lib/pry/commands/jump_to.rb +29 -0
  50. data/lib/pry/commands/list_inspectors.rb +35 -0
  51. data/lib/pry/commands/list_prompts.rb +35 -0
  52. data/lib/pry/commands/ls.rb +114 -0
  53. data/lib/pry/commands/ls/constants.rb +47 -0
  54. data/lib/pry/commands/ls/formatter.rb +49 -0
  55. data/lib/pry/commands/ls/globals.rb +48 -0
  56. data/lib/pry/commands/ls/grep.rb +21 -0
  57. data/lib/pry/commands/ls/instance_vars.rb +39 -0
  58. data/lib/pry/commands/ls/interrogatable.rb +18 -0
  59. data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
  60. data/lib/pry/commands/ls/local_names.rb +35 -0
  61. data/lib/pry/commands/ls/local_vars.rb +39 -0
  62. data/lib/pry/commands/ls/ls_entity.rb +70 -0
  63. data/lib/pry/commands/ls/methods.rb +57 -0
  64. data/lib/pry/commands/ls/methods_helper.rb +46 -0
  65. data/lib/pry/commands/ls/self_methods.rb +32 -0
  66. data/lib/pry/commands/nesting.rb +25 -0
  67. data/lib/pry/commands/play.rb +103 -0
  68. data/lib/pry/commands/pry_backtrace.rb +25 -0
  69. data/lib/pry/commands/pry_version.rb +17 -0
  70. data/lib/pry/commands/raise_up.rb +32 -0
  71. data/lib/pry/commands/reload_code.rb +62 -0
  72. data/lib/pry/commands/reset.rb +18 -0
  73. data/lib/pry/commands/ri.rb +60 -0
  74. data/lib/pry/commands/save_file.rb +61 -0
  75. data/lib/pry/commands/shell_command.rb +48 -0
  76. data/lib/pry/commands/shell_mode.rb +25 -0
  77. data/lib/pry/commands/show_doc.rb +83 -0
  78. data/lib/pry/commands/show_info.rb +195 -0
  79. data/lib/pry/commands/show_input.rb +17 -0
  80. data/lib/pry/commands/show_source.rb +50 -0
  81. data/lib/pry/commands/simple_prompt.rb +22 -0
  82. data/lib/pry/commands/stat.rb +40 -0
  83. data/lib/pry/commands/switch_to.rb +23 -0
  84. data/lib/pry/commands/toggle_color.rb +24 -0
  85. data/lib/pry/commands/watch_expression.rb +105 -0
  86. data/lib/pry/commands/watch_expression/expression.rb +38 -0
  87. data/lib/pry/commands/whereami.rb +190 -0
  88. data/lib/pry/commands/wtf.rb +57 -0
  89. data/lib/pry/config.rb +24 -0
  90. data/lib/pry/config/behavior.rb +139 -0
  91. data/lib/pry/config/convenience.rb +26 -0
  92. data/lib/pry/config/default.rb +165 -0
  93. data/lib/pry/core_extensions.rb +131 -0
  94. data/lib/pry/editor.rb +133 -0
  95. data/lib/pry/exceptions.rb +77 -0
  96. data/lib/pry/helpers.rb +5 -0
  97. data/lib/pry/helpers/base_helpers.rb +113 -0
  98. data/lib/pry/helpers/command_helpers.rb +156 -0
  99. data/lib/pry/helpers/documentation_helpers.rb +75 -0
  100. data/lib/pry/helpers/options_helpers.rb +27 -0
  101. data/lib/pry/helpers/table.rb +109 -0
  102. data/lib/pry/helpers/text.rb +107 -0
  103. data/lib/pry/history.rb +125 -0
  104. data/lib/pry/history_array.rb +121 -0
  105. data/lib/pry/hooks.rb +230 -0
  106. data/lib/pry/indent.rb +406 -0
  107. data/lib/pry/input_completer.rb +242 -0
  108. data/lib/pry/input_lock.rb +132 -0
  109. data/lib/pry/inspector.rb +27 -0
  110. data/lib/pry/last_exception.rb +61 -0
  111. data/lib/pry/method.rb +546 -0
  112. data/lib/pry/method/disowned.rb +53 -0
  113. data/lib/pry/method/patcher.rb +125 -0
  114. data/lib/pry/method/weird_method_locator.rb +186 -0
  115. data/lib/pry/module_candidate.rb +136 -0
  116. data/lib/pry/object_path.rb +82 -0
  117. data/lib/pry/output.rb +50 -0
  118. data/lib/pry/pager.rb +234 -0
  119. data/lib/pry/plugins.rb +103 -0
  120. data/lib/pry/prompt.rb +26 -0
  121. data/lib/pry/pry_class.rb +375 -0
  122. data/lib/pry/pry_instance.rb +654 -0
  123. data/lib/pry/rbx_path.rb +22 -0
  124. data/lib/pry/repl.rb +202 -0
  125. data/lib/pry/repl_file_loader.rb +74 -0
  126. data/lib/pry/rubygem.rb +82 -0
  127. data/lib/pry/terminal.rb +79 -0
  128. data/lib/pry/test/helper.rb +170 -0
  129. data/lib/pry/version.rb +3 -0
  130. data/lib/pry/wrapped_module.rb +373 -0
  131. metadata +248 -0
data/lib/pry/prompt.rb ADDED
@@ -0,0 +1,26 @@
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
+ }
26
+ end
@@ -0,0 +1,375 @@
1
+ require 'pry/config'
2
+ class Pry
3
+
4
+ HOME_RC_FILE = ENV["PRYRC"] || "~/.pryrc"
5
+ LOCAL_RC_FILE = "./.pryrc"
6
+
7
+ class << self
8
+ extend Forwardable
9
+ attr_accessor :custom_completions
10
+ attr_accessor :current_line
11
+ attr_accessor :line_buffer
12
+ attr_accessor :eval_path
13
+ attr_accessor :cli
14
+ attr_accessor :quiet
15
+ attr_accessor :last_internal_error
16
+ attr_accessor :config
17
+ attr_writer :history
18
+
19
+ def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
20
+
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
34
+ end
35
+ end
36
+
37
+ #
38
+ # @return [main]
39
+ # returns the special instance of Object, "main".
40
+ #
41
+ def self.main
42
+ @main ||= TOPLEVEL_BINDING.eval "self"
43
+ end
44
+
45
+ #
46
+ # @return [Pry::Config]
47
+ # Returns a value store for an instance of Pry running on the current thread.
48
+ #
49
+ def self.current
50
+ Thread.current[:__pry__] ||= Pry::Config.from_hash({}, nil)
51
+ end
52
+
53
+ # Load the given file in the context of `Pry.toplevel_binding`
54
+ # @param [String] file The unexpanded file path.
55
+ def self.load_file_at_toplevel(file)
56
+ toplevel_binding.eval(File.read(file), file)
57
+ rescue RescuableException => e
58
+ puts "Error loading #{file}: #{e}\n#{e.backtrace.first}"
59
+ end
60
+
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.
63
+ def self.load_rc_files
64
+ rc_files_to_load.each do |file|
65
+ critical_section do
66
+ load_file_at_toplevel(file)
67
+ end
68
+ end
69
+ end
70
+
71
+ # Load the local RC file (./.pryrc)
72
+ def self.rc_files_to_load
73
+ files = []
74
+ files << HOME_RC_FILE if Pry.config.should_load_rc
75
+ files << LOCAL_RC_FILE if Pry.config.should_load_local_rc
76
+ files.map { |file| real_path_to(file) }.compact.uniq
77
+ end
78
+
79
+ # Expand a file to its canonical name (following symlinks as appropriate)
80
+ 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
85
+ nil
86
+ end
87
+
88
+ # Load any Ruby files specified with the -r flag on the command line.
89
+ def self.load_requires
90
+ Pry.config.requires.each do |file|
91
+ require file
92
+ end
93
+ end
94
+
95
+ # Trap interrupts on jruby, and make them behave like MRI so we can
96
+ # catch them.
97
+ def self.load_traps
98
+ trap('INT'){ raise Interrupt }
99
+ end
100
+
101
+ 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
109
+ For a better Pry experience on Windows, please use ansicon:
110
+ https://github.com/adoxa/ansicon
111
+ 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
115
+ end
116
+
117
+ # Do basic setup for initial session.
118
+ # Including: loading .pryrc, loading plugins, loading requires, and
119
+ # loading history.
120
+ def self.initial_session_setup
121
+ return unless initial_session?
122
+ @initial_session = false
123
+
124
+ # note these have to be loaded here rather than in pry_instance as
125
+ # we only want them loaded once per entire Pry lifetime.
126
+ load_rc_files
127
+ load_plugins if Pry.config.should_load_plugins
128
+ load_requires if Pry.config.should_load_requires
129
+ load_history if Pry.config.history.should_load
130
+ load_traps if Pry.config.should_trap_interrupts
131
+ load_win32console if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi?
132
+ end
133
+
134
+ # Start a Pry REPL.
135
+ # This method also loads `~/.pryrc` and `./.pryrc` as necessary the
136
+ # first time it is invoked.
137
+ # @param [Object, Binding] target The receiver of the Pry session
138
+ # @param [Hash] options
139
+ # @option options (see Pry#initialize)
140
+ # @example
141
+ # Pry.start(Object.new, :input => MyInput.new)
142
+ def self.start(target=nil, options={})
143
+ return if ENV['DISABLE_PRY']
144
+ options = options.to_hash
145
+
146
+ if in_critical_section?
147
+ 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."
149
+ return
150
+ end
151
+
152
+ options[:target] = Pry.binding_for(target || toplevel_binding)
153
+ options[:hooks] = Pry::Hooks.from_hash options.delete(:hooks) if options.key?(:hooks)
154
+ initial_session_setup
155
+
156
+ # Unless we were given a backtrace, save the current one
157
+ if options[:backtrace].nil?
158
+ options[:backtrace] = caller
159
+
160
+ # If Pry was started via `binding.pry`, elide that from the backtrace
161
+ if options[:backtrace].first =~ /pry.*core_extensions.*pry/
162
+ options[:backtrace].shift
163
+ end
164
+ end
165
+
166
+ driver = options[:driver] || Pry::REPL
167
+
168
+ # Enter the matrix
169
+ driver.start(options)
170
+ rescue Pry::TooSafeException
171
+ puts "ERROR: Pry cannot work with $SAFE > 0"
172
+ raise
173
+ end
174
+
175
+ # Execute the file through the REPL loop, non-interactively.
176
+ # @param [String] file_name File name to load through the REPL.
177
+ def self.load_file_through_repl(file_name)
178
+ require "pry/repl_file_loader"
179
+ REPLFileLoader.new(file_name).load
180
+ end
181
+
182
+ #
183
+ # An inspector that clips the output to `max_length` chars.
184
+ # In case of > `max_length` chars the `#<Object...> notation is used.
185
+ #
186
+ # @param [Object] obj
187
+ # The object to view.
188
+ #
189
+ # @param [Hash] options
190
+ # @option options [Integer] :max_length (60)
191
+ # The maximum number of chars before clipping occurs.
192
+ #
193
+ # @option options [Boolean] :id (false)
194
+ # Boolean to indicate whether or not a hex reprsentation of the object ID
195
+ # is attached to the return value when the length of inspect is greater than
196
+ # value of `:max_length`.
197
+ #
198
+ # @return [String]
199
+ # The string representation of `obj`.
200
+ #
201
+ def self.view_clip(obj, options = {})
202
+ max = options.fetch :max_length, 60
203
+ id = options.fetch :id, false
204
+ if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max
205
+ obj.name.to_s
206
+ elsif Pry.main == obj
207
+ # special-case to support jruby.
208
+ # fixed as of https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039
209
+ # we can drop in the future.
210
+ obj.to_s
211
+ elsif Pry.config.prompt_safe_objects.any? { |v| v === obj } && obj.inspect.length <= max
212
+ obj.inspect
213
+ else
214
+ id == true ? "#<#{obj.class}:0x%x>" % (obj.object_id << 1) : "#<#{obj.class}>"
215
+ end
216
+ rescue RescuableException
217
+ "unknown"
218
+ end
219
+
220
+ # Load Readline history if required.
221
+ def self.load_history
222
+ Pry.history.load
223
+ end
224
+
225
+ # @return [Boolean] Whether this is the first time a Pry session has
226
+ # been started since loading the Pry class.
227
+ def self.initial_session?
228
+ @initial_session
229
+ end
230
+
231
+ # Run a Pry command from outside a session. The commands available are
232
+ # those referenced by `Pry.config.commands` (the default command set).
233
+ # @param [String] command_string The Pry command (including arguments,
234
+ # if any).
235
+ # @param [Hash] options Optional named parameters.
236
+ # @return [Object] The return value of the Pry command.
237
+ # @option options [Object, Binding] :target The object to run the
238
+ # command under. Defaults to `TOPLEVEL_BINDING` (main).
239
+ # @option options [Boolean] :show_output Whether to show command
240
+ # output. Defaults to true.
241
+ # @example Run at top-level with no output.
242
+ # Pry.run_command "ls"
243
+ # @example Run under Pry class, returning only public methods.
244
+ # Pry.run_command "ls -m", :target => Pry
245
+ # @example Display command output.
246
+ # Pry.run_command "ls -av", :show_output => true
247
+ def self.run_command(command_string, options={})
248
+ options = {
249
+ :target => TOPLEVEL_BINDING,
250
+ :show_output => true,
251
+ :output => Pry.config.output,
252
+ :commands => Pry.config.commands
253
+ }.merge!(options)
254
+
255
+ # :context for compatibility with <= 0.9.11.4
256
+ target = options[:context] || options[:target]
257
+ output = options[:show_output] ? options[:output] : StringIO.new
258
+
259
+ pry = Pry.new(:output => output, :target => target, :commands => options[:commands])
260
+ 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
273
+ end
274
+
275
+ def self.auto_resize!
276
+ Pry.config.input # by default, load Readline
277
+
278
+ if !defined?(Readline) || Pry.config.input != Readline
279
+ warn "Sorry, you must be using Readline for Pry.auto_resize! to work."
280
+ return
281
+ end
282
+
283
+ if Readline::VERSION =~ /edit/i
284
+ warn <<-EOT
285
+ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly.
286
+ 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
289
+ return
290
+ end
291
+
292
+ trap :WINCH do
293
+ begin
294
+ Readline.set_screen_size(*Terminal.size!)
295
+ rescue => e
296
+ warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}"
297
+ end
298
+ begin
299
+ Readline.refresh_line
300
+ rescue => e
301
+ warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}"
302
+ end
303
+ end
304
+ end
305
+
306
+ # Set all the configurable options back to their default values
307
+ def self.reset_defaults
308
+ @initial_session = true
309
+ self.config = Pry::Config.new Pry::Config::Default.new
310
+ self.cli = false
311
+ self.current_line = 1
312
+ self.line_buffer = [""]
313
+ self.eval_path = "(pry)"
314
+ end
315
+
316
+ # Basic initialization.
317
+ def self.init
318
+ @plugin_manager ||= PluginManager.new
319
+ reset_defaults
320
+ locate_plugins
321
+ end
322
+
323
+ # Return a `Binding` object for `target` or return `target` if it is
324
+ # already a `Binding`.
325
+ # In the case where `target` is top-level then return `TOPLEVEL_BINDING`
326
+ # @param [Object] target The object to get a `Binding` object for.
327
+ # @return [Binding] The `Binding` object.
328
+ 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
338
+ end
339
+
340
+ def self.toplevel_binding
341
+ unless defined?(@toplevel_binding) && @toplevel_binding
342
+ # Grab a copy of the TOPLEVEL_BINDING without any local variables.
343
+ # This binding has a default definee of Object, and new methods are
344
+ # private (just as in TOPLEVEL_BINDING).
345
+ TOPLEVEL_BINDING.eval <<-RUBY
346
+ def self.__pry__
347
+ binding
348
+ end
349
+ Pry.toplevel_binding = __pry__
350
+ class << self; undef __pry__; end
351
+ RUBY
352
+ end
353
+ @toplevel_binding.eval('private')
354
+ @toplevel_binding
355
+ end
356
+
357
+ def self.toplevel_binding=(binding)
358
+ @toplevel_binding = binding
359
+ end
360
+
361
+ def self.in_critical_section?
362
+ Thread.current[:pry_critical_section] ||= 0
363
+ Thread.current[:pry_critical_section] > 0
364
+ end
365
+
366
+ def self.critical_section(&block)
367
+ Thread.current[:pry_critical_section] ||= 0
368
+ Thread.current[:pry_critical_section] += 1
369
+ yield
370
+ ensure
371
+ Thread.current[:pry_critical_section] -= 1
372
+ end
373
+ end
374
+
375
+ Pry.init
@@ -0,0 +1,654 @@
1
+ # -*- coding: utf-8 -*-
2
+ ##
3
+ # Pry is a powerful alternative to the standard IRB shell for Ruby. It
4
+ # features syntax highlighting, a flexible plugin architecture, runtime
5
+ # invocation and source and documentation browsing.
6
+ #
7
+ # Pry can be started similar to other command line utilities by simply running
8
+ # the following command:
9
+ #
10
+ # pry
11
+ #
12
+ # Once inside Pry you can invoke the help message:
13
+ #
14
+ # help
15
+ #
16
+ # This will show a list of available commands and their usage. For more
17
+ # information about Pry you can refer to the following resources:
18
+ #
19
+ # * http://pry.github.com/
20
+ # * https://github.com/pry/pry
21
+ # * the IRC channel, which is #pry on the Freenode network
22
+ #
23
+
24
+ class Pry
25
+ attr_accessor :binding_stack
26
+ attr_accessor :custom_completions
27
+ attr_accessor :eval_string
28
+ attr_accessor :backtrace
29
+ attr_accessor :suppress_output
30
+ attr_accessor :last_result
31
+ attr_accessor :last_file
32
+ attr_accessor :last_dir
33
+
34
+ attr_reader :last_exception
35
+ attr_reader :command_state
36
+ attr_reader :exit_value
37
+ attr_reader :input_array
38
+ attr_reader :output_array
39
+ attr_reader :config
40
+
41
+ extend Pry::Config::Convenience
42
+ config_shortcut *Pry::Config.shortcuts
43
+ EMPTY_COMPLETIONS = [].freeze
44
+
45
+ # Create a new {Pry} instance.
46
+ # @param [Hash] options
47
+ # @option options [#readline] :input
48
+ # The object to use for input.
49
+ # @option options [#puts] :output
50
+ # The object to use for output.
51
+ # @option options [Pry::CommandBase] :commands
52
+ # The object to use for commands.
53
+ # @option options [Hash] :hooks
54
+ # The defined hook Procs.
55
+ # @option options [Array<Proc>] :prompt
56
+ # The array of Procs to use for prompts.
57
+ # @option options [Proc] :print
58
+ # The Proc to use for printing return values.
59
+ # @option options [Boolean] :quiet
60
+ # Omit the `whereami` banner when starting.
61
+ # @option options [Array<String>] :backtrace
62
+ # The backtrace of the session's `binding.pry` line, if applicable.
63
+ # @option options [Object] :target
64
+ # The initial context for this session.
65
+ def initialize(options={})
66
+ @binding_stack = []
67
+ @indent = Pry::Indent.new
68
+ @command_state = {}
69
+ @eval_string = ""
70
+ @backtrace = options.delete(:backtrace) || caller
71
+ target = options.delete(:target)
72
+ @config = Pry::Config.new
73
+ config.merge!(options)
74
+ push_prompt(config.prompt)
75
+ @input_array = Pry::HistoryArray.new config.memory_size
76
+ @output_array = Pry::HistoryArray.new config.memory_size
77
+ @custom_completions = config.command_completions
78
+ set_last_result nil
79
+ @input_array << nil
80
+ push_initial_binding(target)
81
+ exec_hook(:when_started, target, options, self)
82
+ end
83
+
84
+ # The current prompt.
85
+ # 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.
92
+ def prompt
93
+ prompt_stack.last
94
+ end
95
+
96
+ def prompt=(new_prompt)
97
+ if prompt_stack.empty?
98
+ push_prompt new_prompt
99
+ else
100
+ prompt_stack[-1] = new_prompt
101
+ end
102
+ end
103
+
104
+ # Initialize this instance by pushing its initial context into the binding
105
+ # stack. If no target is given, start at the top level.
106
+ def push_initial_binding(target=nil)
107
+ push_binding(target || Pry.toplevel_binding)
108
+ end
109
+
110
+ # The currently active `Binding`.
111
+ # @return [Binding] The currently active `Binding` for the session.
112
+ def current_binding
113
+ binding_stack.last
114
+ end
115
+ alias current_context current_binding # support previous API
116
+
117
+ # Push a binding for the given object onto the stack. If this instance is
118
+ # currently stopped, mark it as usable again.
119
+ def push_binding(object)
120
+ @stopped = false
121
+ binding_stack << Pry.binding_for(object)
122
+ end
123
+
124
+ #
125
+ # Generate completions.
126
+ #
127
+ # @param [String] input
128
+ # What the user has typed so far
129
+ #
130
+ # @return [Array<String>]
131
+ # Possible completions
132
+ #
133
+ def complete(str)
134
+ return EMPTY_COMPLETIONS unless config.completer
135
+ Pry.critical_section do
136
+ completer = config.completer.new(config.input, self)
137
+ completer.call str, target: current_binding, custom_completions: custom_completions.call.push(*sticky_locals.keys)
138
+ end
139
+ end
140
+
141
+ #
142
+ # Injects a local variable into the provided binding.
143
+ #
144
+ # @param [String] name
145
+ # The name of the local to inject.
146
+ #
147
+ # @param [Object] value
148
+ # The value to set the local to.
149
+ #
150
+ # @param [Binding] b
151
+ # The binding to set the local on.
152
+ #
153
+ # @return [Object]
154
+ # The value the local was set to.
155
+ #
156
+ def inject_local(name, value, b)
157
+ value = Proc === value ? value.call : value
158
+ if b.respond_to?(:local_variable_set)
159
+ b.local_variable_set name, value
160
+ else # < 2.1
161
+ begin
162
+ Pry.current[:pry_local] = value
163
+ b.eval "#{name} = ::Pry.current[:pry_local]"
164
+ ensure
165
+ Pry.current[:pry_local] = nil
166
+ end
167
+ end
168
+ end
169
+
170
+ # @return [Integer] The maximum amount of objects remembered by the inp and
171
+ # out arrays. Defaults to 100.
172
+ def memory_size
173
+ @output_array.max_size
174
+ end
175
+
176
+ def memory_size=(size)
177
+ @input_array = Pry::HistoryArray.new(size)
178
+ @output_array = Pry::HistoryArray.new(size)
179
+ end
180
+
181
+ # Inject all the sticky locals into the current binding.
182
+ def inject_sticky_locals!
183
+ sticky_locals.each_pair do |name, value|
184
+ inject_local(name, value, current_binding)
185
+ end
186
+ end
187
+
188
+ # Add a sticky local to this Pry instance.
189
+ # A sticky local is a local that persists between all bindings in a session.
190
+ # @param [Symbol] name The name of the sticky local.
191
+ # @yield The block that defines the content of the local. The local
192
+ # will be refreshed at each tick of the repl loop.
193
+ def add_sticky_local(name, &block)
194
+ config.extra_sticky_locals[name] = block
195
+ end
196
+
197
+ def sticky_locals
198
+ { _in_: input_array,
199
+ _out_: output_array,
200
+ _pry_: self,
201
+ _ex_: last_exception && last_exception.wrapped_exception,
202
+ _file_: last_file,
203
+ _dir_: last_dir,
204
+ _: proc { last_result },
205
+ __: proc { output_array[-2] }
206
+ }.merge(config.extra_sticky_locals)
207
+ end
208
+
209
+ # Reset the current eval string. If the user has entered part of a multiline
210
+ # expression, this discards that input.
211
+ def reset_eval_string
212
+ @eval_string = ""
213
+ end
214
+
215
+ # Pass a line of input to Pry.
216
+ #
217
+ # This is the equivalent of `Binding#eval` but with extra Pry!
218
+ #
219
+ # In particular:
220
+ # 1. Pry commands will be executed immediately if the line matches.
221
+ # 2. Partial lines of input will be queued up until a complete expression has
222
+ # been accepted.
223
+ # 3. Output is written to `#output` in pretty colours, not returned.
224
+ #
225
+ # Once this method has raised an exception or returned false, this instance
226
+ # is no longer usable. {#exit_value} will return the session's breakout
227
+ # value if applicable.
228
+ #
229
+ # @param [String?] line The line of input; `nil` if the user types `<Ctrl-D>`
230
+ # @option options [Boolean] :generated Whether this line was generated automatically.
231
+ # Generated lines are not stored in history.
232
+ # @return [Boolean] Is Pry ready to accept more input?
233
+ # @raise [Exception] If the user uses the `raise-up` command, this method
234
+ # will raise that exception.
235
+ def eval(line, options={})
236
+ return false if @stopped
237
+
238
+ exit_value = nil
239
+ exception = catch(:raise_up) do
240
+ exit_value = catch(:breakout) do
241
+ handle_line(line, options)
242
+ # We use 'return !@stopped' here instead of 'return true' so that if
243
+ # handle_line has stopped this pry instance (e.g. by opening _pry_.repl and
244
+ # then popping all the bindings) we still exit immediately.
245
+ return !@stopped
246
+ end
247
+ exception = false
248
+ end
249
+
250
+ @stopped = true
251
+ @exit_value = exit_value
252
+
253
+ # TODO: make this configurable?
254
+ raise exception if exception
255
+ return false
256
+ end
257
+
258
+ def handle_line(line, options)
259
+ if line.nil?
260
+ config.control_d_handler.call(@eval_string, self)
261
+ return
262
+ end
263
+
264
+ ensure_correct_encoding!(line)
265
+ Pry.history << line unless options[:generated]
266
+
267
+ @suppress_output = false
268
+ inject_sticky_locals!
269
+ begin
270
+ if !process_command_safely(line.lstrip)
271
+ @eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
272
+ end
273
+ rescue RescuableException => e
274
+ self.last_exception = e
275
+ result = e
276
+
277
+ Pry.critical_section do
278
+ show_result(result)
279
+ end
280
+ return
281
+ end
282
+
283
+ # This hook is supposed to be executed after each line of ruby code
284
+ # has been read (regardless of whether eval_string is yet a complete expression)
285
+ exec_hook :after_read, eval_string, self
286
+
287
+ begin
288
+ complete_expr = Pry::Code.complete_expression?(@eval_string)
289
+ rescue SyntaxError => e
290
+ output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}"
291
+ reset_eval_string
292
+ end
293
+
294
+ if complete_expr
295
+ if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/
296
+ @suppress_output = true
297
+ end
298
+
299
+ # A bug in jruby makes java.lang.Exception not rescued by
300
+ # `rescue Pry::RescuableException` clause.
301
+ #
302
+ # * https://github.com/pry/pry/issues/854
303
+ # * https://jira.codehaus.org/browse/JRUBY-7100
304
+ #
305
+ # Until that gets fixed upstream, treat java.lang.Exception
306
+ # as an additional exception to be rescued explicitly.
307
+ #
308
+ # This workaround has a side effect: java exceptions specified
309
+ # in `Pry.config.exception_whitelist` are ignored.
310
+ jruby_exceptions = []
311
+ if Pry::Helpers::BaseHelpers.jruby?
312
+ jruby_exceptions << Java::JavaLang::Exception
313
+ end
314
+
315
+ begin
316
+ # Reset eval string, in case we're evaluating Ruby that does something
317
+ # like open a nested REPL on this instance.
318
+ eval_string = @eval_string
319
+ reset_eval_string
320
+
321
+ result = evaluate_ruby(eval_string)
322
+ rescue RescuableException, *jruby_exceptions => e
323
+ # Eliminate following warning:
324
+ # warning: singleton on non-persistent Java type X
325
+ # (http://wiki.jruby.org/Persistence)
326
+ if Pry::Helpers::BaseHelpers.jruby? && e.class.respond_to?('__persistent__')
327
+ e.class.__persistent__ = true
328
+ end
329
+ self.last_exception = e
330
+ result = e
331
+ end
332
+
333
+ Pry.critical_section do
334
+ show_result(result)
335
+ end
336
+ end
337
+
338
+ throw(:breakout) if current_binding.nil?
339
+ end
340
+ private :handle_line
341
+
342
+ # Potentially deprecated — Use `Pry::REPL.new(pry, :target => target).start`
343
+ # (If nested sessions are going to exist, this method is fine, but a goal is
344
+ # to come up with an alternative to nested sessions altogether.)
345
+ def repl(target = nil)
346
+ Pry::REPL.new(self, :target => target).start
347
+ end
348
+
349
+ def evaluate_ruby(code)
350
+ inject_sticky_locals!
351
+ exec_hook :before_eval, code, self
352
+
353
+ result = current_binding.eval(code, Pry.eval_path, Pry.current_line)
354
+ set_last_result(result, code)
355
+ ensure
356
+ update_input_history(code)
357
+ exec_hook :after_eval, result, self
358
+ end
359
+
360
+ # Output the result or pass to an exception handler (if result is an exception).
361
+ def show_result(result)
362
+ if last_result_is_exception?
363
+ exception_handler.call(output, result, self)
364
+ elsif should_print?
365
+ print.call(output, result, self)
366
+ else
367
+ # nothin'
368
+ end
369
+ rescue RescuableException => e
370
+ # Being uber-paranoid here, given that this exception arose because we couldn't
371
+ # serialize something in the user's program, let's not assume we can serialize
372
+ # the exception either.
373
+ begin
374
+ output.puts "(pry) output error: #{e.inspect}"
375
+ rescue RescuableException => e
376
+ if last_result_is_exception?
377
+ output.puts "(pry) output error: failed to show exception"
378
+ else
379
+ output.puts "(pry) output error: failed to show result"
380
+ end
381
+ end
382
+ ensure
383
+ output.flush if output.respond_to?(:flush)
384
+ end
385
+
386
+ # Force `eval_string` into the encoding of `val`. [Issue #284]
387
+ def ensure_correct_encoding!(val)
388
+ if @eval_string.empty? &&
389
+ val.respond_to?(:encoding) &&
390
+ val.encoding != @eval_string.encoding
391
+ @eval_string.force_encoding(val.encoding)
392
+ end
393
+ end
394
+ private :ensure_correct_encoding!
395
+
396
+ # If the given line is a valid command, process it in the context of the
397
+ # current `eval_string` and binding.
398
+ # @param [String] val The line to process.
399
+ # @return [Boolean] `true` if `val` is a command, `false` otherwise
400
+ def process_command(val)
401
+ val = val.chomp
402
+ result = commands.process_line(val,
403
+ :target => current_binding,
404
+ :output => output,
405
+ :eval_string => @eval_string,
406
+ :pry_instance => self
407
+ )
408
+
409
+ # set a temporary (just so we can inject the value we want into eval_string)
410
+ Pry.current[:pry_cmd_result] = result
411
+
412
+ # note that `result` wraps the result of command processing; if a
413
+ # command was matched and invoked then `result.command?` returns true,
414
+ # otherwise it returns false.
415
+ if result.command?
416
+ if !result.void_command?
417
+ # the command that was invoked was non-void (had a return value) and so we make
418
+ # the value of the current expression equal to the return value
419
+ # of the command.
420
+ @eval_string.replace "::Pry.current[:pry_cmd_result].retval\n"
421
+ end
422
+ true
423
+ else
424
+ false
425
+ end
426
+ end
427
+
428
+ # Same as process_command, but outputs exceptions to `#output` instead of
429
+ # raising.
430
+ # @param [String] val The line to process.
431
+ # @return [Boolean] `true` if `val` is a command, `false` otherwise
432
+ def process_command_safely(val)
433
+ process_command(val)
434
+ rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e
435
+ Pry.last_internal_error = e
436
+ output.puts "Error: #{e.message}"
437
+ true
438
+ end
439
+
440
+ # Run the specified command.
441
+ # @param [String] val The command (and its params) to execute.
442
+ # @return [Pry::Command::VOID_VALUE]
443
+ # @example
444
+ # pry_instance.run_command("ls -m")
445
+ def run_command(val)
446
+ commands.process_line(val,
447
+ :eval_string => @eval_string,
448
+ :target => current_binding,
449
+ :pry_instance => self,
450
+ :output => output
451
+ )
452
+ Pry::Command::VOID_VALUE
453
+ end
454
+
455
+ # Execute the specified hook.
456
+ # @param [Symbol] name The hook name to execute
457
+ # @param [*Object] args The arguments to pass to the hook
458
+ # @return [Object, Exception] The return value of the hook or the exception raised
459
+ #
460
+ # If executing a hook raises an exception, we log that and then continue sucessfully.
461
+ # To debug such errors, use the global variable $pry_hook_error, which is set as a
462
+ # result.
463
+ def exec_hook(name, *args, &block)
464
+ e_before = hooks.errors.size
465
+ hooks.exec_hook(name, *args, &block).tap do
466
+ hooks.errors[e_before..-1].each do |e|
467
+ output.puts "#{name} hook failed: #{e.class}: #{e.message}"
468
+ output.puts "#{e.backtrace.first}"
469
+ output.puts "(see _pry_.hooks.errors to debug)"
470
+ end
471
+ end
472
+ end
473
+
474
+ # Set the last result of an eval.
475
+ # This method should not need to be invoked directly.
476
+ # @param [Object] result The result.
477
+ # @param [String] code The code that was run.
478
+ def set_last_result(result, code="")
479
+ @last_result_is_exception = false
480
+ @output_array << result
481
+
482
+ self.last_result = result unless code =~ /\A\s*\z/
483
+ end
484
+
485
+ #
486
+ # Set the last exception for a session.
487
+ #
488
+ # @param [Exception] e
489
+ # the last exception.
490
+ #
491
+ def last_exception=(e)
492
+ last_exception = Pry::LastException.new(e)
493
+ @last_result_is_exception = true
494
+ @output_array << last_exception
495
+ @last_exception = last_exception
496
+ end
497
+
498
+ # Update Pry's internal state after evalling code.
499
+ # This method should not need to be invoked directly.
500
+ # @param [String] code The code we just eval'd
501
+ def update_input_history(code)
502
+ # Always push to the @input_array as the @output_array is always pushed to.
503
+ @input_array << code
504
+ if code
505
+ Pry.line_buffer.push(*code.each_line)
506
+ Pry.current_line += code.each_line.count
507
+ end
508
+ end
509
+
510
+ # @return [Boolean] True if the last result is an exception that was raised,
511
+ # as opposed to simply an instance of Exception (like the result of
512
+ # Exception.new)
513
+ def last_result_is_exception?
514
+ @last_result_is_exception
515
+ end
516
+
517
+ # Whether the print proc should be invoked.
518
+ # Currently only invoked if the output is not suppressed.
519
+ # @return [Boolean] Whether the print proc should be invoked.
520
+ def should_print?
521
+ !@suppress_output
522
+ end
523
+
524
+ # Returns the appropriate prompt to use.
525
+ # @return [String] The prompt.
526
+ def select_prompt
527
+ object = current_binding.eval('self')
528
+
529
+ open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last :
530
+ @indent.stack.last
531
+
532
+ c = Pry::Config.from_hash({
533
+ :object => object,
534
+ :nesting_level => binding_stack.size - 1,
535
+ :open_token => open_token,
536
+ :session_line => Pry.history.session_line_count + 1,
537
+ :history_line => Pry.history.history_line_count + 1,
538
+ :expr_number => input_array.count,
539
+ :_pry_ => self,
540
+ :binding_stack => binding_stack,
541
+ :input_array => input_array,
542
+ :eval_string => @eval_string,
543
+ :cont => !@eval_string.empty?})
544
+
545
+ Pry.critical_section do
546
+ # If input buffer is empty then use normal prompt
547
+ if eval_string.empty?
548
+ generate_prompt(Array(prompt).first, c)
549
+
550
+ # Otherwise use the wait prompt (indicating multi-line expression)
551
+ else
552
+ generate_prompt(Array(prompt).last, c)
553
+ end
554
+ end
555
+ end
556
+
557
+ def generate_prompt(prompt_proc, conf)
558
+ if prompt_proc.arity == 1
559
+ prompt_proc.call(conf)
560
+ else
561
+ prompt_proc.call(conf.object, conf.nesting_level, conf._pry_)
562
+ end
563
+ end
564
+ private :generate_prompt
565
+
566
+ # the array that the prompt stack is stored in
567
+ def prompt_stack
568
+ @prompt_stack ||= Array.new
569
+ end
570
+ private :prompt_stack
571
+
572
+ # Pushes the current prompt onto a stack that it can be restored from later.
573
+ # Use this if you wish to temporarily change the prompt.
574
+ # @param [Array<Proc>] new_prompt
575
+ # @return [Array<Proc>] new_prompt
576
+ # @example
577
+ # new_prompt = [ proc { '>' }, proc { '>>' } ]
578
+ # push_prompt(new_prompt) # => new_prompt
579
+ def push_prompt(new_prompt)
580
+ prompt_stack.push new_prompt
581
+ end
582
+
583
+ # Pops the current prompt off of the prompt stack.
584
+ # If the prompt you are popping is the last prompt, it will not be popped.
585
+ # Use this to restore the previous prompt.
586
+ # @return [Array<Proc>] Prompt being popped.
587
+ # @example
588
+ # prompt1 = [ proc { '>' }, proc { '>>' } ]
589
+ # prompt2 = [ proc { '$' }, proc { '>' } ]
590
+ # pry = Pry.new :prompt => prompt1
591
+ # pry.push_prompt(prompt2)
592
+ # pry.pop_prompt # => prompt2
593
+ # pry.pop_prompt # => prompt1
594
+ # pry.pop_prompt # => prompt1
595
+ def pop_prompt
596
+ prompt_stack.size > 1 ? prompt_stack.pop : prompt
597
+ end
598
+
599
+ # Returns the currently configured pager
600
+ # @example
601
+ # _pry_.pager.page text
602
+ def pager
603
+ Pry::Pager.new(self)
604
+ end
605
+
606
+ # Returns an output device
607
+ # @example
608
+ # _pry_.output.puts "ohai!"
609
+ def output
610
+ Pry::Output.new(self)
611
+ end
612
+
613
+ # Raise an exception out of Pry.
614
+ #
615
+ # See Kernel#raise for documentation of parameters.
616
+ # See rb_make_exception for the inbuilt implementation.
617
+ #
618
+ # This is necessary so that the raise-up command can tell the
619
+ # difference between an exception the user has decided to raise,
620
+ # and a mistake in specifying that exception.
621
+ #
622
+ # (i.e. raise-up RunThymeError.new should not be the same as
623
+ # raise-up NameError, "unititialized constant RunThymeError")
624
+ #
625
+ def raise_up_common(force, *args)
626
+ exception = if args == []
627
+ last_exception || RuntimeError.new
628
+ elsif args.length == 1 && args.first.is_a?(String)
629
+ RuntimeError.new(args.first)
630
+ elsif args.length > 3
631
+ raise ArgumentError, "wrong number of arguments"
632
+ elsif !args.first.respond_to?(:exception)
633
+ raise TypeError, "exception class/object expected"
634
+ elsif args.length === 1
635
+ args.first.exception
636
+ else
637
+ args.first.exception(args[1])
638
+ end
639
+
640
+ raise TypeError, "exception object expected" unless exception.is_a? Exception
641
+
642
+ exception.set_backtrace(args.length === 3 ? args[2] : caller(1))
643
+
644
+ if force || binding_stack.one?
645
+ binding_stack.clear
646
+ throw :raise_up, exception
647
+ else
648
+ binding_stack.pop
649
+ raise exception
650
+ end
651
+ end
652
+ def raise_up(*args); raise_up_common(false, *args); end
653
+ def raise_up!(*args); raise_up_common(true, *args); end
654
+ end