pry 0.9.4pre1-i386-mingw32 → 0.9.4pre2-i386-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/CHANGELOG +23 -0
  2. data/CONTRIBUTORS +13 -11
  3. data/README.markdown +2 -0
  4. data/Rakefile +16 -2
  5. data/TODO +8 -0
  6. data/lib/pry.rb +58 -9
  7. data/lib/pry/command_context.rb +11 -0
  8. data/lib/pry/command_processor.rb +43 -6
  9. data/lib/pry/command_set.rb +14 -4
  10. data/lib/pry/completion.rb +5 -5
  11. data/lib/pry/config.rb +6 -2
  12. data/lib/pry/default_commands/context.rb +83 -35
  13. data/lib/pry/default_commands/documentation.rb +37 -31
  14. data/lib/pry/default_commands/easter_eggs.rb +5 -0
  15. data/lib/pry/default_commands/input.rb +13 -10
  16. data/lib/pry/default_commands/introspection.rb +54 -40
  17. data/lib/pry/default_commands/shell.rb +9 -5
  18. data/lib/pry/helpers/base_helpers.rb +16 -5
  19. data/lib/pry/helpers/command_helpers.rb +41 -17
  20. data/lib/pry/helpers/text.rb +2 -1
  21. data/lib/pry/history.rb +61 -0
  22. data/lib/pry/plugins.rb +19 -8
  23. data/lib/pry/pry_class.rb +25 -62
  24. data/lib/pry/pry_instance.rb +105 -120
  25. data/lib/pry/version.rb +1 -1
  26. data/pry.gemspec +15 -14
  27. data/test/helper.rb +31 -0
  28. data/test/test_command_set.rb +7 -2
  29. data/test/test_completion.rb +7 -3
  30. data/test/test_default_commands/test_context.rb +185 -1
  31. data/test/test_default_commands/test_documentation.rb +10 -0
  32. data/test/test_default_commands/test_input.rb +16 -11
  33. data/test/test_default_commands/test_introspection.rb +10 -0
  34. data/test/test_default_commands/test_shell.rb +18 -0
  35. data/test/test_pry.rb +189 -40
  36. data/test/test_pry_history.rb +13 -13
  37. data/test/test_pry_output.rb +44 -0
  38. data/test/test_special_locals.rb +35 -0
  39. metadata +182 -173
@@ -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
@@ -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
@@ -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
- MessageSink = Object.new.tap { |o| def o.method_missing(*args) end }
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 = Pry.config.plugins.strict_loading ? {} : Hash.new { MessageSink }
69
+ h = Hash.new { |_, key| NoPlugin.new(key) }
59
70
  @plugins.each do |plugin|
60
71
  h[plugin.name] = plugin
61
72
  end
@@ -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, max_size=60)
133
- if obj.inspect.size < max_size
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
- Readline::HISTORY.push(*File.readlines(history_file).map(&:chomp)) if File.exists?(history_file)
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
- history_to_save = Readline::HISTORY.to_a
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 = 0
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`
@@ -10,10 +10,15 @@ class Pry
10
10
  attr_accessor :hooks
11
11
  attr_accessor :custom_completions
12
12
 
13
- # Returns the target binding for the session. Note that altering this
14
- # attribute will not change the target binding.
15
- # @return [Binding] The target object for the session
16
- attr_accessor :session_target
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
- Pry.active_instance = self
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
- self.session_target = target
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, nesting_level, break_data)
141
- nesting.pop
152
+ def repl_epilogue(target, break_data)
142
153
  exec_hook :after_session, output, target
143
154
 
144
- # If break_data is an array, then the last element is the return value
145
- break_level, return_value = Array(break_data)
146
-
147
- # keep throwing until we reach the desired nesting level
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(target)
177
+ rep(binding_stack.last)
179
178
  end
180
179
  end
181
180
 
182
- return_value = repl_epilogue(target, nesting_level, break_data)
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
- # save the pry instance to active_instance
215
- Pry.active_instance = self
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
- res = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
225
- res
226
- rescue SystemExit => e
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/ || null_input?(val)
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
- end
269
-
270
- # Returns true if input is "" and a command is not returning a
271
- # value.
272
- # @param [String] val The input string.
273
- # @return [Boolean] Whether the input is null.
274
- def null_input?(val)
275
- val.empty? && !Pry.cmd_ret_value
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
- throw(:breakout, nesting.level)
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
- Pry.cmd_ret_value = @command_processor.process_commands(val, eval_string, target)
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 Pry.cmd_ret_value
305
- eval_string << "Pry.cmd_ret_value\n"
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 (with no ret_value) should have an empty `val` so this ignores their result
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
- Pry.last_result = result
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
- Pry.last_exception = ex
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
- # Readline must be treated differently
393
- # as it has a second parameter.
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, nesting.level)
412
+ Array(prompt).first.call(target_self, binding_stack.size - 1, self)
428
413
  else
429
- Array(prompt).last.call(target_self, nesting.level)
414
+ Array(prompt).last.call(target_self, binding_stack.size - 1, self)
430
415
  end
431
416
  end
432
417