pry 0.9.4pre1-i386-mswin32 → 0.9.4pre2-i386-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +23 -0
- data/CONTRIBUTORS +13 -11
- data/README.markdown +2 -0
- data/Rakefile +16 -2
- data/TODO +8 -0
- data/lib/pry.rb +58 -9
- data/lib/pry/command_context.rb +11 -0
- data/lib/pry/command_processor.rb +43 -6
- data/lib/pry/command_set.rb +14 -4
- data/lib/pry/completion.rb +5 -5
- data/lib/pry/config.rb +6 -2
- data/lib/pry/default_commands/context.rb +83 -35
- data/lib/pry/default_commands/documentation.rb +37 -31
- data/lib/pry/default_commands/easter_eggs.rb +5 -0
- data/lib/pry/default_commands/input.rb +13 -10
- data/lib/pry/default_commands/introspection.rb +54 -40
- data/lib/pry/default_commands/shell.rb +9 -5
- data/lib/pry/helpers/base_helpers.rb +16 -5
- data/lib/pry/helpers/command_helpers.rb +41 -17
- data/lib/pry/helpers/text.rb +2 -1
- data/lib/pry/history.rb +61 -0
- data/lib/pry/plugins.rb +19 -8
- data/lib/pry/pry_class.rb +25 -62
- data/lib/pry/pry_instance.rb +105 -120
- data/lib/pry/version.rb +1 -1
- data/pry.gemspec +15 -14
- data/test/helper.rb +31 -0
- data/test/test_command_set.rb +7 -2
- data/test/test_completion.rb +7 -3
- data/test/test_default_commands/test_context.rb +185 -1
- data/test/test_default_commands/test_documentation.rb +10 -0
- data/test/test_default_commands/test_input.rb +16 -11
- data/test/test_default_commands/test_introspection.rb +10 -0
- data/test/test_default_commands/test_shell.rb +18 -0
- data/test/test_pry.rb +189 -40
- data/test/test_pry_history.rb +13 -13
- data/test/test_pry_output.rb +44 -0
- data/test/test_special_locals.rb +35 -0
- metadata +182 -173
data/lib/pry/helpers/text.rb
CHANGED
@@ -69,8 +69,9 @@ class Pry
|
|
69
69
|
# @return [String]
|
70
70
|
def with_line_numbers(text, offset, color=:blue)
|
71
71
|
lines = text.each_line.to_a
|
72
|
+
max_width = (offset + lines.count).to_s.length
|
72
73
|
lines.each_with_index.map do |line, index|
|
73
|
-
adjusted_index = index + offset
|
74
|
+
adjusted_index = (index + offset).to_s.rjust(max_width)
|
74
75
|
"#{self.send(color, adjusted_index)}: #{line}"
|
75
76
|
end.join
|
76
77
|
end
|
data/lib/pry/history.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
class Pry
|
2
|
+
# The History class is responsible for maintaining the user's input history, both
|
3
|
+
# internally and within Readline::HISTORY.
|
4
|
+
class History
|
5
|
+
def initialize
|
6
|
+
@history = []
|
7
|
+
@saved_lines = 0
|
8
|
+
end
|
9
|
+
|
10
|
+
# Loads a file's contents into the input history.
|
11
|
+
# @param [String] filename
|
12
|
+
# @return [Integer] The number of lines loaded
|
13
|
+
def load(filename)
|
14
|
+
File.foreach(filename) do |line|
|
15
|
+
Readline::HISTORY << line.chomp
|
16
|
+
@history << line.chomp
|
17
|
+
end
|
18
|
+
@saved_lines = @history.length
|
19
|
+
end
|
20
|
+
|
21
|
+
# Appends input history from this session to a file.
|
22
|
+
# @param [String] filename
|
23
|
+
# @return [Integer] The number of lines saved
|
24
|
+
def save(filename)
|
25
|
+
history_to_save = @history[@saved_lines..-1]
|
26
|
+
File.open(filename, 'a') do |f|
|
27
|
+
history_to_save.each { |ln| f.puts ln }
|
28
|
+
end
|
29
|
+
@saved_lines = @history.length
|
30
|
+
history_to_save.length
|
31
|
+
end
|
32
|
+
|
33
|
+
# Adds a line to the input history, ignoring blank and duplicate lines.
|
34
|
+
# @param [String] line
|
35
|
+
# @return [String] The same line that was passed in
|
36
|
+
def push(line)
|
37
|
+
unless line.empty? || (@history.last && line.strip == @history.last.strip)
|
38
|
+
Readline::HISTORY << line
|
39
|
+
@history << line
|
40
|
+
end
|
41
|
+
line
|
42
|
+
end
|
43
|
+
alias << push
|
44
|
+
|
45
|
+
# Clears all history. Anything the user entered before this point won't be
|
46
|
+
# saved, but anything they put in afterwards will still be appended to the
|
47
|
+
# history file on exit.
|
48
|
+
def clear
|
49
|
+
Readline::HISTORY.shift until Readline::HISTORY.empty?
|
50
|
+
@history = []
|
51
|
+
@saved_lines = 0
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns an Array containing all stored history.
|
55
|
+
# @return [Array<String>] An Array containing all lines of history loaded
|
56
|
+
# or entered by the user in the current session.
|
57
|
+
def to_a
|
58
|
+
@history.dup
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/pry/plugins.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
class Pry
|
2
2
|
class PluginManager
|
3
3
|
PRY_PLUGIN_PREFIX = /^pry-/
|
4
|
-
PluginNotFound = Class.new(LoadError)
|
5
4
|
|
6
|
-
|
5
|
+
# Placeholder when no associated gem found, displays warning
|
6
|
+
class NoPlugin
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(*args)
|
12
|
+
$stderr.puts "Warning: The plugin '#{@name}' was not found! (no gem found)"
|
13
|
+
end
|
14
|
+
end
|
7
15
|
|
8
16
|
class Plugin
|
9
17
|
attr_accessor :name, :gem_name, :enabled, :spec, :active
|
@@ -12,22 +20,25 @@ class Pry
|
|
12
20
|
@name, @gem_name, @enabled, @spec = name, gem_name, enabled, spec
|
13
21
|
end
|
14
22
|
|
15
|
-
# Disable a plugin.
|
23
|
+
# Disable a plugin. (prevents plugin from being loaded, cannot
|
24
|
+
# disable an already activated plugin)
|
16
25
|
def disable!
|
17
26
|
self.enabled = false
|
18
27
|
end
|
19
28
|
|
20
|
-
# Enable a plugin.
|
29
|
+
# Enable a plugin. (does not load it immediately but puts on
|
30
|
+
# 'white list' to be loaded)
|
21
31
|
def enable!
|
22
32
|
self.enabled = true
|
23
33
|
end
|
24
34
|
|
25
|
-
# Activate the plugin (require the gem
|
35
|
+
# Activate the plugin (require the gem - enables/loads the
|
36
|
+
# plugin immediately at point of call, even if plugin is disabled)
|
26
37
|
def activate!
|
27
38
|
begin
|
28
|
-
require gem_name
|
39
|
+
require gem_name if !active?
|
29
40
|
rescue LoadError
|
30
|
-
$stderr.puts "Warning: The plugin '#{gem_name}' was not found!"
|
41
|
+
$stderr.puts "Warning: The plugin '#{gem_name}' was not found! (gem found but could not be loaded)"
|
31
42
|
end
|
32
43
|
self.active = true
|
33
44
|
self.enabled = true
|
@@ -55,7 +66,7 @@ class Pry
|
|
55
66
|
# @return [Hash] A hash with all plugin names (minus the 'pry-') as
|
56
67
|
# keys and Plugin objects as values.
|
57
68
|
def plugins
|
58
|
-
h =
|
69
|
+
h = Hash.new { |_, key| NoPlugin.new(key) }
|
59
70
|
@plugins.each do |plugin|
|
60
71
|
h[plugin.name] = plugin
|
61
72
|
end
|
data/lib/pry/pry_class.rb
CHANGED
@@ -18,26 +18,6 @@ class Pry
|
|
18
18
|
def_delegators delagatee, *names.map { |v| "#{v}=" }
|
19
19
|
end
|
20
20
|
|
21
|
-
# Get nesting data.
|
22
|
-
# This method should not need to be accessed directly.
|
23
|
-
# @return [Array] The unparsed nesting information.
|
24
|
-
attr_reader :nesting
|
25
|
-
|
26
|
-
# Get last value evaluated by Pry.
|
27
|
-
# This method should not need to be accessed directly.
|
28
|
-
# @return [Object] The last result.
|
29
|
-
attr_accessor :last_result
|
30
|
-
|
31
|
-
# Get last exception raised.
|
32
|
-
# This method should not need to be accessed directly.
|
33
|
-
# @return [Exception] The last exception.
|
34
|
-
attr_accessor :last_exception
|
35
|
-
|
36
|
-
# Get the active Pry instance that manages the active Pry session.
|
37
|
-
# This method should not need to be accessed directly.
|
38
|
-
# @return [Pry] The active Pry instance.
|
39
|
-
attr_accessor :active_instance
|
40
|
-
|
41
21
|
# Get/Set the Proc that defines extra Readline completions (on top
|
42
22
|
# of the ones defined for IRB).
|
43
23
|
# @return [Proc] The Proc that defines extra Readline completions (on top
|
@@ -45,10 +25,6 @@ class Pry
|
|
45
25
|
# Pry.custom_completions = proc { Dir.entries('.') }
|
46
26
|
attr_accessor :custom_completions
|
47
27
|
|
48
|
-
# Value returned by last executed Pry command.
|
49
|
-
# @return [Object] The command value
|
50
|
-
attr_accessor :cmd_ret_value
|
51
|
-
|
52
28
|
# @return [Fixnum] The current input line.
|
53
29
|
attr_accessor :current_line
|
54
30
|
|
@@ -62,9 +38,15 @@ class Pry
|
|
62
38
|
# @return [OpenStruct] Return Pry's config object.
|
63
39
|
attr_accessor :config
|
64
40
|
|
41
|
+
# @return [History] Return Pry's line history object.
|
42
|
+
attr_accessor :history
|
43
|
+
|
65
44
|
# @return [Boolean] Whether Pry was activated from the command line.
|
66
45
|
attr_accessor :cli
|
67
46
|
|
47
|
+
# @return [Fixnum] The number of active Pry sessions.
|
48
|
+
attr_accessor :active_sessions
|
49
|
+
|
68
50
|
# plugin forwardables
|
69
51
|
def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
|
70
52
|
|
@@ -129,38 +111,27 @@ class Pry
|
|
129
111
|
# @param obj The object to view.
|
130
112
|
# @param max_size The maximum number of chars before clipping occurs.
|
131
113
|
# @return [String] The string representation of `obj`.
|
132
|
-
def self.view_clip(obj,
|
133
|
-
if obj.
|
114
|
+
def self.view_clip(obj, max_length = 60)
|
115
|
+
if obj.kind_of?(Module) && obj.name && obj.name != "" && obj.name.to_s.length <= max_length
|
116
|
+
obj.name.to_s
|
117
|
+
elsif obj.inspect.length <= max_length
|
134
118
|
obj.inspect
|
135
|
-
else
|
119
|
+
else
|
136
120
|
"#<#{obj.class}:%#x>" % (obj.object_id << 1)
|
137
121
|
end
|
122
|
+
|
123
|
+
rescue
|
124
|
+
"unknown"
|
138
125
|
end
|
139
126
|
|
140
127
|
# Load Readline history if required.
|
141
128
|
def self.load_history
|
142
|
-
|
143
|
-
@loaded_history = Readline::HISTORY.to_a
|
129
|
+
Pry.history.load(history_file) if File.exists?(history_file)
|
144
130
|
end
|
145
131
|
|
146
132
|
# Save new lines of Readline history if required.
|
147
133
|
def self.save_history
|
148
|
-
|
149
|
-
|
150
|
-
# Omit any history we read from the file.This check is needed because
|
151
|
-
# `hist --clear` would otherwise cause us to not save history in this
|
152
|
-
# session.
|
153
|
-
if history_to_save[0...@loaded_history.size] == @loaded_history
|
154
|
-
history_to_save = history_to_save[@loaded_history.size..-1]
|
155
|
-
end
|
156
|
-
|
157
|
-
File.open(history_file, 'a') do |f|
|
158
|
-
f.puts history_to_save.join("\n") if history_to_save.size > 0
|
159
|
-
end
|
160
|
-
|
161
|
-
# Update @loaded_history so that future calls to save_history
|
162
|
-
# will do the right thing.
|
163
|
-
@loaded_history = Readline::HISTORY.to_a
|
134
|
+
Pry.history.save(history_file)
|
164
135
|
end
|
165
136
|
|
166
137
|
# Get the full path of the history_path for pry.
|
@@ -205,9 +176,9 @@ class Pry
|
|
205
176
|
|
206
177
|
def self.default_editor_for_platform
|
207
178
|
if RUBY_PLATFORM =~ /mswin|mingw/
|
208
|
-
ENV['EDITOR'] || "notepad"
|
179
|
+
ENV['VISUAL'] || ENV['EDITOR'] || "notepad"
|
209
180
|
else
|
210
|
-
ENV['EDITOR'] || "nano"
|
181
|
+
ENV['VISUAL'] || ENV['EDITOR'] || "nano"
|
211
182
|
end
|
212
183
|
end
|
213
184
|
|
@@ -238,6 +209,8 @@ class Pry
|
|
238
209
|
config.history.should_load = true
|
239
210
|
config.history.file = File.expand_path("~/.pry_history")
|
240
211
|
|
212
|
+
config.control_d_handler = DEFAULT_CONTROL_D_HANDLER
|
213
|
+
|
241
214
|
config.memory_size = 100
|
242
215
|
end
|
243
216
|
|
@@ -249,32 +222,22 @@ class Pry
|
|
249
222
|
|
250
223
|
self.custom_completions = DEFAULT_CUSTOM_COMPLETIONS
|
251
224
|
self.cli = false
|
252
|
-
self.current_line =
|
253
|
-
self.line_buffer = []
|
225
|
+
self.current_line = 1
|
226
|
+
self.line_buffer = [""]
|
254
227
|
self.eval_path = "(pry)"
|
228
|
+
self.active_sessions = 0
|
255
229
|
end
|
256
230
|
|
257
231
|
# Basic initialization.
|
258
232
|
def self.init
|
259
233
|
@plugin_manager ||= PluginManager.new
|
260
|
-
|
261
234
|
self.config ||= Config.new
|
235
|
+
self.history ||= History.new
|
236
|
+
|
262
237
|
reset_defaults
|
263
238
|
locate_plugins
|
264
239
|
end
|
265
240
|
|
266
|
-
@nesting = []
|
267
|
-
def @nesting.level
|
268
|
-
last.is_a?(Array) ? last.first : nil
|
269
|
-
end
|
270
|
-
|
271
|
-
# Return all active Pry sessions.
|
272
|
-
# @return [Array<Pry>] Active Pry sessions.
|
273
|
-
def self.sessions
|
274
|
-
# last element in nesting array is the pry instance
|
275
|
-
nesting.map(&:last)
|
276
|
-
end
|
277
|
-
|
278
241
|
# Return a `Binding` object for `target` or return `target` if it is
|
279
242
|
# already a `Binding`.
|
280
243
|
# In the case where `target` is top-level then return `TOPLEVEL_BINDING`
|
data/lib/pry/pry_instance.rb
CHANGED
@@ -10,10 +10,15 @@ class Pry
|
|
10
10
|
attr_accessor :hooks
|
11
11
|
attr_accessor :custom_completions
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
attr_accessor :
|
13
|
+
attr_accessor :binding_stack
|
14
|
+
|
15
|
+
attr_accessor :last_result
|
16
|
+
attr_accessor :last_exception
|
17
|
+
attr_accessor :last_file
|
18
|
+
attr_accessor :last_dir
|
19
|
+
|
20
|
+
attr_reader :input_array
|
21
|
+
attr_reader :output_array
|
17
22
|
|
18
23
|
# Create a new `Pry` object.
|
19
24
|
# @param [Hash] options The optional configuration parameters.
|
@@ -28,6 +33,7 @@ class Pry
|
|
28
33
|
refresh(options)
|
29
34
|
|
30
35
|
@command_processor = CommandProcessor.new(self)
|
36
|
+
@binding_stack = []
|
31
37
|
end
|
32
38
|
|
33
39
|
# Refresh the Pry instance settings from the Pry class.
|
@@ -73,6 +79,18 @@ class Pry
|
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
82
|
+
# Injects a local variable into the provided binding.
|
83
|
+
# @param [String] name The name of the local to inject.
|
84
|
+
# @param [Object] value The value to set the local to.
|
85
|
+
# @param [Binding] b The binding to set the local on.
|
86
|
+
# @return [Object] The value the local was set to.
|
87
|
+
def inject_local(name, value, b)
|
88
|
+
Thread.current[:__pry_local__] = value
|
89
|
+
b.eval("#{name} = Thread.current[:__pry_local__]")
|
90
|
+
ensure
|
91
|
+
Thread.current[:__pry_local__] = nil
|
92
|
+
end
|
93
|
+
|
76
94
|
# @return [Integer] The maximum amount of objects remembered by the inp and
|
77
95
|
# out arrays. Defaults to 100.
|
78
96
|
def memory_size
|
@@ -84,32 +102,6 @@ class Pry
|
|
84
102
|
@output_array = Pry::HistoryArray.new(size)
|
85
103
|
end
|
86
104
|
|
87
|
-
# Get nesting data.
|
88
|
-
# This method should not need to be accessed directly.
|
89
|
-
# @return [Array] The unparsed nesting information.
|
90
|
-
def nesting
|
91
|
-
self.class.nesting
|
92
|
-
end
|
93
|
-
|
94
|
-
# Set nesting data.
|
95
|
-
# This method should not need to be accessed directly.
|
96
|
-
# @param v nesting data.
|
97
|
-
def nesting=(v)
|
98
|
-
self.class.nesting = v
|
99
|
-
end
|
100
|
-
|
101
|
-
# @return [Boolean] Whether top-level session has ended.
|
102
|
-
def finished_top_level_session?
|
103
|
-
nesting.empty?
|
104
|
-
end
|
105
|
-
|
106
|
-
# Return parent of current Pry session.
|
107
|
-
# @return [Pry] The parent of the current Pry session.
|
108
|
-
def parent
|
109
|
-
idx = Pry.sessions.index(self)
|
110
|
-
Pry.sessions[idx - 1] if idx && idx > 0
|
111
|
-
end
|
112
|
-
|
113
105
|
# Execute the hook `hook_name`, if it is defined.
|
114
106
|
# @param [Symbol] hook_name The hook to execute
|
115
107
|
# @param [Array] args The arguments to pass to the hook.
|
@@ -117,41 +109,53 @@ class Pry
|
|
117
109
|
hooks[hook_name].call(*args, &block) if hooks[hook_name]
|
118
110
|
end
|
119
111
|
|
112
|
+
# Make sure special locals exist at start of session
|
113
|
+
def initialize_special_locals(target)
|
114
|
+
inject_local("_in_", @input_array, target)
|
115
|
+
inject_local("_out_", @output_array, target)
|
116
|
+
inject_local("_pry_", self, target)
|
117
|
+
inject_local("_ex_", nil, target)
|
118
|
+
inject_local("_file_", nil, target)
|
119
|
+
inject_local("_dir_", nil, target)
|
120
|
+
|
121
|
+
# without this line we get 1 test failure, ask Mon_Ouie
|
122
|
+
set_last_result(nil, target)
|
123
|
+
inject_local("_", nil, target)
|
124
|
+
end
|
125
|
+
private :initialize_special_locals
|
126
|
+
|
127
|
+
def inject_special_locals(target)
|
128
|
+
inject_local("_in_", @input_array, target)
|
129
|
+
inject_local("_out_", @output_array, target)
|
130
|
+
inject_local("_pry_", self, target)
|
131
|
+
inject_local("_ex_", self.last_exception, target)
|
132
|
+
inject_local("_file_", self.last_file, target)
|
133
|
+
inject_local("_dir_", self.last_dir, target)
|
134
|
+
inject_local("_", self.last_result, target)
|
135
|
+
end
|
136
|
+
|
120
137
|
# Initialize the repl session.
|
121
138
|
# @param [Binding] target The target binding for the session.
|
122
139
|
def repl_prologue(target)
|
123
140
|
exec_hook :before_session, output, target
|
124
|
-
|
125
|
-
|
126
|
-
# Make sure special locals exist
|
127
|
-
target.eval("inp = ::Pry.active_instance.instance_eval { @input_array }")
|
128
|
-
target.eval("out = ::Pry.active_instance.instance_eval { @output_array }")
|
141
|
+
initialize_special_locals(target)
|
129
142
|
|
130
|
-
set_active_instance(target)
|
131
143
|
@input_array << nil # add empty input so inp and out match
|
132
|
-
set_last_result(Pry.last_result, target)
|
133
144
|
|
134
|
-
|
145
|
+
Pry.active_sessions += 1
|
146
|
+
binding_stack.push target
|
135
147
|
end
|
136
148
|
|
137
149
|
# Clean-up after the repl session.
|
138
150
|
# @param [Binding] target The target binding for the session.
|
139
151
|
# @return [Object] The return value of the repl session (if one exists).
|
140
|
-
def repl_epilogue(target,
|
141
|
-
nesting.pop
|
152
|
+
def repl_epilogue(target, break_data)
|
142
153
|
exec_hook :after_session, output, target
|
143
154
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
if nesting_level != break_level
|
149
|
-
throw :breakout, break_data
|
150
|
-
end
|
151
|
-
|
152
|
-
Pry.save_history if Pry.config.history.should_save && finished_top_level_session?
|
153
|
-
|
154
|
-
return_value
|
155
|
+
Pry.active_sessions -= 1
|
156
|
+
binding_stack.pop
|
157
|
+
Pry.save_history if Pry.config.history.should_save && Pry.active_sessions == 0
|
158
|
+
break_data
|
155
159
|
end
|
156
160
|
|
157
161
|
# Start a read-eval-print-loop.
|
@@ -168,18 +172,13 @@ class Pry
|
|
168
172
|
|
169
173
|
repl_prologue(target)
|
170
174
|
|
171
|
-
# cannot rely on nesting.level as
|
172
|
-
# nesting.level changes with new sessions
|
173
|
-
nesting_level = nesting.size
|
174
|
-
|
175
175
|
break_data = catch(:breakout) do
|
176
|
-
nesting.push [nesting.size, target_self, self]
|
177
176
|
loop do
|
178
|
-
rep(
|
177
|
+
rep(binding_stack.last)
|
179
178
|
end
|
180
179
|
end
|
181
180
|
|
182
|
-
return_value = repl_epilogue(target,
|
181
|
+
return_value = repl_epilogue(target, break_data)
|
183
182
|
return_value || target_self
|
184
183
|
end
|
185
184
|
|
@@ -211,21 +210,15 @@ class Pry
|
|
211
210
|
Readline.completion_proc = Pry::InputCompleter.build_completion_proc target, instance_eval(&custom_completions)
|
212
211
|
end
|
213
212
|
|
214
|
-
#
|
215
|
-
|
216
|
-
|
217
|
-
target.eval("inp = ::Pry.active_instance.instance_eval { @input_array }")
|
218
|
-
target.eval("out = ::Pry.active_instance.instance_eval { @output_array }")
|
219
|
-
|
220
|
-
set_active_instance(target)
|
213
|
+
# It's not actually redundant to inject them continually as we may have
|
214
|
+
# moved into the scope of a new Binding (e.g the user typed `cd`)
|
215
|
+
inject_special_locals(target)
|
221
216
|
|
222
217
|
code = r(target)
|
223
218
|
|
224
|
-
|
225
|
-
|
226
|
-
rescue
|
227
|
-
exit
|
228
|
-
rescue Exception => e
|
219
|
+
result = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
|
220
|
+
result
|
221
|
+
rescue RescuableException => e
|
229
222
|
set_last_exception(e, target)
|
230
223
|
ensure
|
231
224
|
update_input_history(code)
|
@@ -253,7 +246,7 @@ class Pry
|
|
253
246
|
break if valid_expression?(eval_string)
|
254
247
|
end
|
255
248
|
|
256
|
-
@suppress_output = true if eval_string =~ /;\Z/ ||
|
249
|
+
@suppress_output = true if eval_string =~ /;\Z/ || eval_string.empty?
|
257
250
|
|
258
251
|
eval_string
|
259
252
|
end
|
@@ -265,14 +258,19 @@ class Pry
|
|
265
258
|
else
|
266
259
|
print.call output, result
|
267
260
|
end
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
261
|
+
rescue RescuableException => e
|
262
|
+
# Being uber-paranoid here, given that this exception arose because we couldn't
|
263
|
+
# serialize something in the user's program, let's not assume we can serialize
|
264
|
+
# the exception either.
|
265
|
+
begin
|
266
|
+
output.puts "output error: #{e.inspect}"
|
267
|
+
rescue RescuableException => e
|
268
|
+
if last_result_is_exception?
|
269
|
+
output.puts "output error: failed to show exception"
|
270
|
+
else
|
271
|
+
output.puts "output error: failed to show result"
|
272
|
+
end
|
273
|
+
end
|
276
274
|
end
|
277
275
|
|
278
276
|
# Read a line of input and check for ^d, also determine prompt to use.
|
@@ -284,13 +282,14 @@ class Pry
|
|
284
282
|
current_prompt = select_prompt(eval_string.empty?, target.eval('self'))
|
285
283
|
val = readline(current_prompt)
|
286
284
|
|
287
|
-
# exit session if we receive EOF character
|
285
|
+
# exit session if we receive EOF character (^D)
|
288
286
|
if !val
|
289
|
-
output.puts
|
290
|
-
|
287
|
+
output.puts ""
|
288
|
+
Pry.config.control_d_handler.call(eval_string, self)
|
289
|
+
""
|
290
|
+
else
|
291
|
+
val
|
291
292
|
end
|
292
|
-
|
293
|
-
val
|
294
293
|
end
|
295
294
|
|
296
295
|
# Process the line received.
|
@@ -299,12 +298,23 @@ class Pry
|
|
299
298
|
# @param [String] eval_string The cumulative lines of input.
|
300
299
|
# @param [Binding] target The target of the Pry session.
|
301
300
|
def process_line(val, eval_string, target)
|
302
|
-
|
301
|
+
result = @command_processor.process_commands(val, eval_string, target)
|
302
|
+
|
303
|
+
# set a temporary (just so we can inject the value we want into eval_string)
|
304
|
+
Thread.current[:__pry_cmd_result__] = result
|
303
305
|
|
304
|
-
if
|
305
|
-
|
306
|
+
# note that `result` wraps the result of command processing; if a
|
307
|
+
# command was matched and invoked then `result.command?` returns true,
|
308
|
+
# otherwise it returns false.
|
309
|
+
if result.command? && !result.void_command?
|
310
|
+
|
311
|
+
# the command that was invoked was non-void (had a return value) and so we make
|
312
|
+
# the value of the current expression equal to the return value
|
313
|
+
# of the command.
|
314
|
+
eval_string.replace "Thread.current[:__pry_cmd_result__].retval\n"
|
306
315
|
else
|
307
|
-
# only commands
|
316
|
+
# only commands should have an empty `val`
|
317
|
+
# so this ignores their result
|
308
318
|
eval_string << "#{val.rstrip}\n" if !val.empty?
|
309
319
|
end
|
310
320
|
end
|
@@ -317,8 +327,7 @@ class Pry
|
|
317
327
|
@last_result_is_exception = false
|
318
328
|
@output_array << result
|
319
329
|
|
320
|
-
|
321
|
-
target.eval("_ = ::Pry.last_result")
|
330
|
+
self.last_result = result
|
322
331
|
end
|
323
332
|
|
324
333
|
# Set the last exception for a session.
|
@@ -336,8 +345,7 @@ class Pry
|
|
336
345
|
@last_result_is_exception = true
|
337
346
|
@output_array << ex
|
338
347
|
|
339
|
-
|
340
|
-
target.eval("_ex_ = ::Pry.last_exception")
|
348
|
+
self.last_exception = ex
|
341
349
|
end
|
342
350
|
|
343
351
|
# Update Pry's internal state after evalling code.
|
@@ -350,28 +358,6 @@ class Pry
|
|
350
358
|
Pry.line_buffer.push(*code.each_line)
|
351
359
|
Pry.current_line += code.each_line.count
|
352
360
|
end
|
353
|
-
if Readline::HISTORY.size > 0
|
354
|
-
|
355
|
-
# all this fluff is to get around annoying bug in libedit on
|
356
|
-
# ruby 1.8.7
|
357
|
-
final_index = -1
|
358
|
-
begin
|
359
|
-
Readline::HISTORY[-1]
|
360
|
-
rescue IndexError
|
361
|
-
final_index = -2
|
362
|
-
end
|
363
|
-
last = Readline::HISTORY[final_index].strip
|
364
|
-
prev = Readline::HISTORY.size > 1 ? Readline::HISTORY[final_index - 1].strip : ''
|
365
|
-
Readline::HISTORY.pop if last && (last.empty? || last == prev)
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
# Set the active instance for a session.
|
370
|
-
# This method should not need to be invoked directly.
|
371
|
-
# @param [Binding] target The binding to set `_ex_` on.
|
372
|
-
def set_active_instance(target)
|
373
|
-
Pry.active_instance = self
|
374
|
-
target.eval("_pry_ = ::Pry.active_instance")
|
375
361
|
end
|
376
362
|
|
377
363
|
# @return [Boolean] True if the last result is an exception that was raised,
|
@@ -388,10 +374,9 @@ class Pry
|
|
388
374
|
def readline(current_prompt="> ")
|
389
375
|
|
390
376
|
if input == Readline
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
input.readline(current_prompt, true)
|
377
|
+
line = input.readline(current_prompt, false)
|
378
|
+
Pry.history << line.dup if line
|
379
|
+
line
|
395
380
|
else
|
396
381
|
begin
|
397
382
|
if input.method(:readline).arity == 1
|
@@ -424,9 +409,9 @@ class Pry
|
|
424
409
|
def select_prompt(first_line, target_self)
|
425
410
|
|
426
411
|
if first_line
|
427
|
-
Array(prompt).first.call(target_self,
|
412
|
+
Array(prompt).first.call(target_self, binding_stack.size - 1, self)
|
428
413
|
else
|
429
|
-
Array(prompt).last.call(target_self,
|
414
|
+
Array(prompt).last.call(target_self, binding_stack.size - 1, self)
|
430
415
|
end
|
431
416
|
end
|
432
417
|
|