pry 0.10.0.pre2-universal-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +702 -0
- data/LICENSE +25 -0
- data/README.md +406 -0
- data/bin/pry +16 -0
- data/lib/pry.rb +161 -0
- data/lib/pry/cli.rb +220 -0
- data/lib/pry/code.rb +346 -0
- data/lib/pry/code/code_file.rb +103 -0
- data/lib/pry/code/code_range.rb +71 -0
- data/lib/pry/code/loc.rb +92 -0
- data/lib/pry/code_object.rb +172 -0
- data/lib/pry/color_printer.rb +55 -0
- data/lib/pry/command.rb +692 -0
- data/lib/pry/command_set.rb +443 -0
- data/lib/pry/commands.rb +6 -0
- data/lib/pry/commands/amend_line.rb +99 -0
- data/lib/pry/commands/bang.rb +20 -0
- data/lib/pry/commands/bang_pry.rb +17 -0
- data/lib/pry/commands/cat.rb +62 -0
- data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
- data/lib/pry/commands/cat/exception_formatter.rb +77 -0
- data/lib/pry/commands/cat/file_formatter.rb +67 -0
- data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
- data/lib/pry/commands/cd.rb +41 -0
- data/lib/pry/commands/change_inspector.rb +27 -0
- data/lib/pry/commands/change_prompt.rb +26 -0
- data/lib/pry/commands/code_collector.rb +165 -0
- data/lib/pry/commands/disable_pry.rb +27 -0
- data/lib/pry/commands/disabled_commands.rb +2 -0
- data/lib/pry/commands/easter_eggs.rb +112 -0
- data/lib/pry/commands/edit.rb +195 -0
- data/lib/pry/commands/edit/exception_patcher.rb +25 -0
- data/lib/pry/commands/edit/file_and_line_locator.rb +36 -0
- data/lib/pry/commands/exit.rb +42 -0
- data/lib/pry/commands/exit_all.rb +29 -0
- data/lib/pry/commands/exit_program.rb +23 -0
- data/lib/pry/commands/find_method.rb +193 -0
- data/lib/pry/commands/fix_indent.rb +19 -0
- data/lib/pry/commands/gem_cd.rb +26 -0
- data/lib/pry/commands/gem_install.rb +32 -0
- data/lib/pry/commands/gem_list.rb +33 -0
- data/lib/pry/commands/gem_open.rb +29 -0
- data/lib/pry/commands/gist.rb +101 -0
- data/lib/pry/commands/help.rb +164 -0
- data/lib/pry/commands/hist.rb +180 -0
- data/lib/pry/commands/import_set.rb +22 -0
- data/lib/pry/commands/install_command.rb +53 -0
- data/lib/pry/commands/jump_to.rb +29 -0
- data/lib/pry/commands/list_inspectors.rb +35 -0
- data/lib/pry/commands/list_prompts.rb +35 -0
- data/lib/pry/commands/ls.rb +114 -0
- data/lib/pry/commands/ls/constants.rb +47 -0
- data/lib/pry/commands/ls/formatter.rb +49 -0
- data/lib/pry/commands/ls/globals.rb +48 -0
- data/lib/pry/commands/ls/grep.rb +21 -0
- data/lib/pry/commands/ls/instance_vars.rb +39 -0
- data/lib/pry/commands/ls/interrogatable.rb +18 -0
- data/lib/pry/commands/ls/jruby_hacks.rb +49 -0
- data/lib/pry/commands/ls/local_names.rb +35 -0
- data/lib/pry/commands/ls/local_vars.rb +39 -0
- data/lib/pry/commands/ls/ls_entity.rb +70 -0
- data/lib/pry/commands/ls/methods.rb +57 -0
- data/lib/pry/commands/ls/methods_helper.rb +46 -0
- data/lib/pry/commands/ls/self_methods.rb +32 -0
- data/lib/pry/commands/nesting.rb +25 -0
- data/lib/pry/commands/play.rb +103 -0
- data/lib/pry/commands/pry_backtrace.rb +25 -0
- data/lib/pry/commands/pry_version.rb +17 -0
- data/lib/pry/commands/raise_up.rb +32 -0
- data/lib/pry/commands/reload_code.rb +62 -0
- data/lib/pry/commands/reset.rb +18 -0
- data/lib/pry/commands/ri.rb +60 -0
- data/lib/pry/commands/save_file.rb +61 -0
- data/lib/pry/commands/shell_command.rb +48 -0
- data/lib/pry/commands/shell_mode.rb +25 -0
- data/lib/pry/commands/show_doc.rb +83 -0
- data/lib/pry/commands/show_info.rb +195 -0
- data/lib/pry/commands/show_input.rb +17 -0
- data/lib/pry/commands/show_source.rb +50 -0
- data/lib/pry/commands/simple_prompt.rb +22 -0
- data/lib/pry/commands/stat.rb +40 -0
- data/lib/pry/commands/switch_to.rb +23 -0
- data/lib/pry/commands/toggle_color.rb +24 -0
- data/lib/pry/commands/watch_expression.rb +105 -0
- data/lib/pry/commands/watch_expression/expression.rb +38 -0
- data/lib/pry/commands/whereami.rb +190 -0
- data/lib/pry/commands/wtf.rb +57 -0
- data/lib/pry/config.rb +24 -0
- data/lib/pry/config/behavior.rb +139 -0
- data/lib/pry/config/convenience.rb +26 -0
- data/lib/pry/config/default.rb +165 -0
- data/lib/pry/core_extensions.rb +131 -0
- data/lib/pry/editor.rb +133 -0
- data/lib/pry/exceptions.rb +77 -0
- data/lib/pry/helpers.rb +5 -0
- data/lib/pry/helpers/base_helpers.rb +113 -0
- data/lib/pry/helpers/command_helpers.rb +156 -0
- data/lib/pry/helpers/documentation_helpers.rb +75 -0
- data/lib/pry/helpers/options_helpers.rb +27 -0
- data/lib/pry/helpers/table.rb +109 -0
- data/lib/pry/helpers/text.rb +107 -0
- data/lib/pry/history.rb +125 -0
- data/lib/pry/history_array.rb +121 -0
- data/lib/pry/hooks.rb +230 -0
- data/lib/pry/indent.rb +406 -0
- data/lib/pry/input_completer.rb +242 -0
- data/lib/pry/input_lock.rb +132 -0
- data/lib/pry/inspector.rb +27 -0
- data/lib/pry/last_exception.rb +61 -0
- data/lib/pry/method.rb +546 -0
- data/lib/pry/method/disowned.rb +53 -0
- data/lib/pry/method/patcher.rb +125 -0
- data/lib/pry/method/weird_method_locator.rb +186 -0
- data/lib/pry/module_candidate.rb +136 -0
- data/lib/pry/object_path.rb +82 -0
- data/lib/pry/output.rb +50 -0
- data/lib/pry/pager.rb +234 -0
- data/lib/pry/plugins.rb +103 -0
- data/lib/pry/prompt.rb +26 -0
- data/lib/pry/pry_class.rb +375 -0
- data/lib/pry/pry_instance.rb +654 -0
- data/lib/pry/rbx_path.rb +22 -0
- data/lib/pry/repl.rb +202 -0
- data/lib/pry/repl_file_loader.rb +74 -0
- data/lib/pry/rubygem.rb +82 -0
- data/lib/pry/terminal.rb +79 -0
- data/lib/pry/test/helper.rb +170 -0
- data/lib/pry/version.rb +3 -0
- data/lib/pry/wrapped_module.rb +373 -0
- 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
|