pry 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +68 -2
  3. data/README.md +47 -30
  4. data/lib/pry/basic_object.rb +1 -1
  5. data/lib/pry/class_command.rb +2 -2
  6. data/lib/pry/cli.rb +6 -2
  7. data/lib/pry/code.rb +0 -8
  8. data/lib/pry/code_object.rb +2 -2
  9. data/lib/pry/command.rb +1 -1
  10. data/lib/pry/command_set.rb +2 -2
  11. data/lib/pry/command_state.rb +11 -6
  12. data/lib/pry/commands/amend_line.rb +1 -1
  13. data/lib/pry/commands/cd.rb +2 -0
  14. data/lib/pry/commands/edit.rb +2 -0
  15. data/lib/pry/commands/find_method.rb +1 -1
  16. data/lib/pry/commands/ls/config.rb +51 -0
  17. data/lib/pry/commands/ls/constants.rb +2 -2
  18. data/lib/pry/commands/ls.rb +0 -21
  19. data/lib/pry/commands/raise_up.rb +1 -1
  20. data/lib/pry/commands/ri.rb +1 -1
  21. data/lib/pry/commands/shell_command.rb +1 -1
  22. data/lib/pry/commands/shell_mode.rb +1 -0
  23. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  24. data/lib/pry/commands/watch_expression.rb +4 -6
  25. data/lib/pry/config.rb +26 -29
  26. data/lib/pry/control_d_handler.rb +1 -1
  27. data/lib/pry/core_extensions.rb +1 -1
  28. data/lib/pry/editor.rb +3 -1
  29. data/lib/pry/exception_handler.rb +7 -2
  30. data/lib/pry/helpers/command_helpers.rb +1 -1
  31. data/lib/pry/helpers/platform.rb +1 -6
  32. data/lib/pry/helpers/text.rb +5 -5
  33. data/lib/pry/indent.rb +13 -11
  34. data/lib/pry/input/simple_stdio.rb +13 -0
  35. data/lib/pry/input_completer.rb +2 -2
  36. data/lib/pry/method/patcher.rb +2 -2
  37. data/lib/pry/method/weird_method_locator.rb +2 -2
  38. data/lib/pry/method.rb +4 -4
  39. data/lib/pry/pry_class.rb +17 -2
  40. data/lib/pry/pry_instance.rb +7 -45
  41. data/lib/pry/repl.rb +66 -4
  42. data/lib/pry/ring.rb +2 -2
  43. data/lib/pry/slop.rb +1 -1
  44. data/lib/pry/syntax_highlighter.rb +1 -1
  45. data/lib/pry/version.rb +1 -1
  46. data/lib/pry/warning.rb +3 -10
  47. data/lib/pry/wrapped_module/candidate.rb +9 -8
  48. data/lib/pry/wrapped_module.rb +3 -8
  49. data/lib/pry.rb +3 -0
  50. metadata +6 -7
data/lib/pry/config.rb CHANGED
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ostruct'
4
-
5
3
  class Pry
6
4
  # @api private
7
5
  class Config
8
6
  extend Attributable
9
7
 
10
- # @return [IO, #readline] he object from which Pry retrieves its lines of
8
+ # @return [IO, #readline] the object from which Pry retrieves its lines of
11
9
  # input
12
10
  attribute :input
13
11
 
@@ -26,10 +24,6 @@ class Pry
26
24
  # @return [Array] Exception that Pry shouldn't rescue
27
25
  attribute :unrescued_exceptions
28
26
 
29
- # @deprecated
30
- # @return [Array] Exception that Pry shouldn't rescue
31
- attribute :exception_whitelist
32
-
33
27
  # @return [Integer] The number of lines of context to show before and after
34
28
  # exceptions
35
29
  attribute :default_window_size
@@ -67,6 +61,9 @@ class Pry
67
61
  # @return [Boolean]
68
62
  attribute :pager
69
63
 
64
+ # @return [Boolean]
65
+ attribute :multiline
66
+
70
67
  # @return [Boolean] whether the global ~/.pryrc should be loaded
71
68
  attribute :should_load_rc
72
69
 
@@ -153,7 +150,7 @@ class Pry
153
150
 
154
151
  def initialize
155
152
  merge!(
156
- input: MemoizedValue.new { lazy_readline },
153
+ input: MemoizedValue.new { choose_input },
157
154
  output: $stdout.tap { |out| out.sync = true },
158
155
  commands: Pry::Commands,
159
156
  prompt_name: 'pry',
@@ -167,17 +164,10 @@ class Pry
167
164
  ::SystemExit, ::SignalException, Pry::TooSafeException
168
165
  ],
169
166
 
170
- exception_whitelist: MemoizedValue.new do
171
- output.puts(
172
- '[warning] Pry.config.exception_whitelist is deprecated, ' \
173
- 'please use Pry.config.unrescued_exceptions instead.'
174
- )
175
- unrescued_exceptions
176
- end,
177
-
178
167
  hooks: Pry::Hooks.default,
179
168
  pager: true,
180
169
  system: Pry::SystemCommandHandler.method(:default),
170
+ multiline: true,
181
171
  color: Pry::Helpers::BaseHelpers.use_ansi_codes?,
182
172
  default_window_size: 5,
183
173
  editor: Pry::Editor.default,
@@ -199,7 +189,7 @@ class Pry
199
189
  extra_sticky_locals: {},
200
190
  command_completions: proc { commands.keys },
201
191
  file_completions: proc { Dir['.'] },
202
- ls: OpenStruct.new(Pry::Command::Ls::DEFAULT_OPTIONS),
192
+ ls: Pry::Command::Ls::Config.default,
203
193
  completer: Pry::InputCompleter,
204
194
  history_save: true,
205
195
  history_load: true,
@@ -286,7 +276,17 @@ class Pry
286
276
 
287
277
  private
288
278
 
289
- def lazy_readline
279
+ def choose_input
280
+ input = load_readline
281
+
282
+ if Pry::Env['TERM'] == 'dumb' && (defined?(Reline) && input == Reline)
283
+ input = Pry::Input::SimpleStdio
284
+ end
285
+
286
+ input
287
+ end
288
+
289
+ def load_readline
290
290
  require 'readline'
291
291
  ::Readline
292
292
  rescue LoadError
@@ -301,17 +301,14 @@ class Pry
301
301
  end
302
302
 
303
303
  def default_rc_file
304
- if (pryrc = Pry::Env['PRYRC'])
305
- pryrc
306
- elsif (xdg_home = Pry::Env['XDG_CONFIG_HOME'])
307
- # See XDG Base Directory Specification at
308
- # https://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
309
- xdg_home + '/pry/pryrc'
310
- elsif File.exist?(File.expand_path('~/.pryrc'))
311
- '~/.pryrc'
312
- else
313
- '~/.config/pry/pryrc'
314
- end
304
+ [Pry::Env['PRYRC'],
305
+ # See XDG Base Directory Specification at
306
+ # https://specifications.freedesktop.org/basedir-spec/latest/
307
+ "#{Pry::Env['XDG_CONFIG_HOME']}/pry/pryrc",
308
+ File.expand_path('~/.pryrc'),
309
+ File.expand_path('~/.config/pry/pryrc')]
310
+ .compact
311
+ .find { |file| File.exist?(file) }
315
312
  end
316
313
  end
317
314
  end
@@ -19,7 +19,7 @@ class Pry
19
19
  else
20
20
  # Otherwise, saves current binding stack as old stack and pops last
21
21
  # binding out of binding stack (the old stack still has that binding).
22
- cd_state = Pry::CommandState.default.state_for('cd')
22
+ cd_state = Pry::CommandState.default.state_for(Pry::Command::Cd)
23
23
  cd_state.old_stack = pry_instance.binding_stack.dup
24
24
  pry_instance.binding_stack.pop
25
25
  end
@@ -78,7 +78,7 @@ class Object
78
78
  # Module.new.class_eval("binding") has different behaviour than CRuby,
79
79
  # where this is not needed: class_eval("binding") vs class_eval{binding}.
80
80
  # Using a block works around the difference of behaviour on JRuby.
81
- # The scope is clear of local variabless. Don't add any.
81
+ # The scope is clear of local variables. Don't add any.
82
82
  #
83
83
  # This fixes the following two spec failures, at https://travis-ci.org/pry/pry/jobs/274470002
84
84
  # 1) ./spec/pry_spec.rb:360:in `block in (root)'
data/lib/pry/editor.rb CHANGED
@@ -105,7 +105,7 @@ class Pry
105
105
  '--nofork' if blocking
106
106
  when /^jedit/
107
107
  '-wait' if blocking
108
- when /^mate/, /^subl/, /^redcar/
108
+ when /^mate/, /^subl/, /^redcar/, /^code/
109
109
  '-w' if blocking
110
110
  end
111
111
  end
@@ -121,6 +121,8 @@ class Pry
121
121
  "+#{line_number} #{file_name}"
122
122
  when /^mate/, /^geany/
123
123
  "-l #{line_number} #{file_name}"
124
+ when /^code/
125
+ "-g #{file_name}:#{line_number}"
124
126
  when /^subl/
125
127
  "#{file_name}:#{line_number}"
126
128
  when /^uedit32/
@@ -30,8 +30,13 @@ class Pry
30
30
  end
31
31
 
32
32
  def exception_text(exception)
33
- "#{exception.class}: #{exception.message}\n" \
34
- "from #{exception.backtrace.first}\n"
33
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.2')
34
+ "#{exception.class}: #{exception.message}\n" \
35
+ "from #{exception.backtrace.first}\n"
36
+ else
37
+ "#{exception.class}: #{exception.detailed_message}\n" \
38
+ "from #{exception.backtrace.first}\n"
39
+ end
35
40
  end
36
41
 
37
42
  def cause_text(cause)
@@ -70,7 +70,7 @@ class Pry
70
70
 
71
71
  # Find the longest common whitespace to all indented lines. Ignore lines
72
72
  # containing just -- or ++ as these seem to be used by comment authors
73
- # as delimeters.
73
+ # as delimiters.
74
74
  scanned_text = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/)
75
75
  margin = scanned_text.inject do |current_margin, next_indent|
76
76
  if next_indent.start_with?(current_margin)
@@ -28,7 +28,7 @@ class Pry
28
28
  def self.windows_ansi?
29
29
  return false unless windows?
30
30
 
31
- !!(defined?(Win32::Console) || Pry::Env['ANSICON'] || mri_2?)
31
+ !!(defined?(Win32::Console) || Pry::Env['ANSICON'] || mri?)
32
32
  end
33
33
 
34
34
  # @return [Boolean]
@@ -46,11 +46,6 @@ class Pry
46
46
  RbConfig::CONFIG['ruby_install_name'] == 'ruby'
47
47
  end
48
48
 
49
- # @return [Boolean]
50
- def self.mri_19?
51
- mri? && RUBY_VERSION.start_with?('1.9')
52
- end
53
-
54
49
  # @return [Boolean]
55
50
  def self.mri_2?
56
51
  mri? && RUBY_VERSION.start_with?('2')
@@ -21,20 +21,20 @@ class Pry
21
21
 
22
22
  COLORS.each_pair do |color, value|
23
23
  define_method color do |text|
24
- "\001\033[0;#{30 + value}m\002#{text}\001\033[0m\002"
24
+ "\033[0;#{30 + value}m#{text}\033[0m"
25
25
  end
26
26
 
27
27
  define_method "bright_#{color}" do |text|
28
- "\001\033[1;#{30 + value}m\002#{text}\001\033[0m\002"
28
+ "\033[1;#{30 + value}m#{text}\033[0m"
29
29
  end
30
30
 
31
31
  COLORS.each_pair do |bg_color, bg_value|
32
32
  define_method "#{color}_on_#{bg_color}" do |text|
33
- "\001\033[0;#{30 + value};#{40 + bg_value}m\002#{text}\001\033[0m\002"
33
+ "\033[0;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
34
34
  end
35
35
 
36
36
  define_method "bright_#{color}_on_#{bg_color}" do |text|
37
- "\001\033[1;#{30 + value};#{40 + bg_value}m\002#{text}\001\033[0m\002"
37
+ "\033[1;#{30 + value};#{40 + bg_value}m#{text}\033[0m"
38
38
  end
39
39
  end
40
40
  end
@@ -52,7 +52,7 @@ class Pry
52
52
  # @param [String, #to_s] text
53
53
  # @return [String] _text_
54
54
  def bold(text)
55
- "\001\e[1m\002#{text}\001\e[0m\002"
55
+ "\e[1m#{text}\e[0m"
56
56
  end
57
57
 
58
58
  # Returns `text` in the default foreground colour.
data/lib/pry/indent.rb CHANGED
@@ -17,6 +17,9 @@ class Pry
17
17
  # @return [String] String containing the spaces to be inserted before the next line.
18
18
  attr_reader :indent_level
19
19
 
20
+ # @return [String] String containing the spaces for the current line.
21
+ attr_reader :last_indent_level
22
+
20
23
  # @return [Array<String>] The stack of open tokens.
21
24
  attr_reader :stack
22
25
 
@@ -57,8 +60,8 @@ class Pry
57
60
  #
58
61
  # :pre_constant and :preserved_constant are the CodeRay 0.9.8 and 1.0.0
59
62
  # classifications of "true", "false", and "nil".
60
- IGNORE_TOKENS = [:space, :content, :string, :method, :ident,
61
- :constant, :pre_constant, :predefined_constant].freeze
63
+ IGNORE_TOKENS = %i[space content string method ident
64
+ constant pre_constant predefined_constant].freeze
62
65
 
63
66
  # Tokens that indicate the end of a statement (i.e. that, if they appear
64
67
  # directly before an "if" indicates that that if applies to the same line,
@@ -66,10 +69,10 @@ class Pry
66
69
  #
67
70
  # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively
68
71
  # classifications of "super", "next", "return", etc.
69
- STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float,
70
- :keyword, :delimiter, :reserved,
71
- :instance_variable,
72
- :class_variable, :global_variable]
72
+ STATEMENT_END_TOKENS = IGNORE_TOKENS + %i[regexp integer float
73
+ keyword delimiter reserved
74
+ instance_variable
75
+ class_variable global_variable]
73
76
 
74
77
  # Collection of tokens that should appear dedented even though they
75
78
  # don't affect the surrounding code.
@@ -109,7 +112,8 @@ class Pry
109
112
  # reset internal state
110
113
  def reset
111
114
  @stack = []
112
- @indent_level = ''
115
+ @indent_level = String.new # rubocop:disable Style/EmptyLiteral
116
+ @last_indent_level = @indent_level
113
117
  @heredoc_queue = []
114
118
  @close_heredocs = {}
115
119
  @string_start = nil
@@ -164,11 +168,11 @@ class Pry
164
168
 
165
169
  output += line
166
170
 
171
+ @last_indent_level = prefix
167
172
  prefix = new_prefix
168
173
  end
169
174
 
170
175
  @indent_level = prefix
171
-
172
176
  output
173
177
  end
174
178
 
@@ -281,9 +285,7 @@ class Pry
281
285
  # @param [String] string The Ruby to lex
282
286
  # @return [Array] An Array of pairs of [token_value, token_type]
283
287
  def tokenize(string)
284
- tokens = SyntaxHighlighter.tokenize(string)
285
- tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens) # Coderay 1.0.0
286
- tokens.to_a
288
+ SyntaxHighlighter.tokenize(string).each_slice(2).to_a
287
289
  end
288
290
 
289
291
  # Update the internal state about what kind of strings are open.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ module Input
5
+ # Readline replacement for low-capability terminals.
6
+ class SimpleStdio
7
+ def self.readline(prompt)
8
+ Pry.config.output.print(prompt)
9
+ $stdin.gets
10
+ end
11
+ end
12
+ end
13
+ end
@@ -234,7 +234,7 @@ class Pry
234
234
  end.compact
235
235
  end
236
236
 
237
- # build_path seperates the input into two parts: path and input.
237
+ # build_path separates the input into two parts: path and input.
238
238
  # input is the partial string that should be completed
239
239
  # path is a proc that takes an input and builds a full path.
240
240
  def build_path(input)
@@ -270,7 +270,7 @@ class Pry
270
270
  end
271
271
 
272
272
  # FIXME: Add Pry here as well?
273
- [:IRB, :SLex, :RubyLex, :RubyToken].each do |module_name|
273
+ %i[IRB SLex RubyLex RubyToken].each do |module_name|
274
274
  next unless Object.const_defined?(module_name)
275
275
 
276
276
  scanner.call(Object.const_get(module_name))
@@ -43,7 +43,7 @@ class Pry
43
43
  #
44
44
  # When we're redefining aliased methods we will overwrite the method at the
45
45
  # unaliased name (so that super continues to work). By wrapping that code in a
46
- # transation we make that not happen, which means that alias_method_chains, etc.
46
+ # translation we make that not happen, which means that alias_method_chains, etc.
47
47
  # continue to work.
48
48
  #
49
49
  def with_method_transaction
@@ -95,7 +95,7 @@ class Pry
95
95
  # Update the source code so that when it has the right owner when eval'd.
96
96
  #
97
97
  # This (combined with definition_for_owner) is backup for the case that
98
- # wrap_for_nesting fails, to ensure that the method will stil be defined in
98
+ # wrap_for_nesting fails, to ensure that the method will still be defined in
99
99
  # the correct place.
100
100
  #
101
101
  # @param [String] source The source to wrap
@@ -123,7 +123,7 @@ class Pry
123
123
  # know which __FILE__ and __LINE__ the binding is at, we can hope to
124
124
  # disambiguate these cases.
125
125
  #
126
- # This obviously won't work if the source is unavaiable for some reason,
126
+ # This obviously won't work if the source is unavailable for some reason,
127
127
  # or if both methods have the same __FILE__ and __LINE__.
128
128
  #
129
129
  # @return [Pry::Method, nil] The Pry::Method representing the
@@ -158,7 +158,7 @@ class Pry
158
158
 
159
159
  alias_name = all_methods_for(target_self).find do |v|
160
160
  location = target_self.method(v).source_location
161
- expanded_source_location(location) == renamed_method_source_location
161
+ location && expanded_source_location(location) == renamed_method_source_location
162
162
  end
163
163
 
164
164
  alias_name && Pry::Method(target_self.method(alias_name))
data/lib/pry/method.rb CHANGED
@@ -530,8 +530,9 @@ class Pry
530
530
  else
531
531
  fail_msg = "Cannot locate this method: #{name}."
532
532
  if Helpers::Platform.mri?
533
- fail_msg += " Invoke the 'gem-install pry-doc' Pry command to get " \
534
- "access to Ruby Core documentation.\n"
533
+ fail_msg += " Run `gem install pry-doc` to install" \
534
+ " Ruby Core documentation," \
535
+ " and `require 'pry-doc'` to load it.\n"
535
536
  end
536
537
  raise CommandError, fail_msg
537
538
  end
@@ -563,8 +564,7 @@ class Pry
563
564
  def method_name_from_first_line(first_ln)
564
565
  return nil if first_ln.strip !~ /^def /
565
566
 
566
- tokens = SyntaxHighlighter.tokenize(first_ln)
567
- tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens)
567
+ tokens = SyntaxHighlighter.tokenize(first_ln).each_slice(2)
568
568
  tokens.each_cons(2) do |t1, t2|
569
569
  if t2.last == :method || t2.last == :ident && t1 == [".", :operator]
570
570
  return t2.first
data/lib/pry/pry_class.rb CHANGED
@@ -85,7 +85,7 @@ class Pry
85
85
  # Load the local RC file (./.pryrc)
86
86
  def self.rc_files_to_load
87
87
  files = []
88
- files << Pry.config.rc_file if Pry.config.should_load_rc
88
+ files << Pry.config.rc_file if Pry.config.rc_file && Pry.config.should_load_rc
89
89
  files << LOCAL_RC_FILE if Pry.config.should_load_local_rc
90
90
  files.map { |file| real_path_to(file) }.compact.uniq
91
91
  end
@@ -161,6 +161,8 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
161
161
 
162
162
  options = options.to_hash
163
163
 
164
+ options[:color] = false if Pry::Env['NO_COLOR']
165
+
164
166
  if in_critical_section?
165
167
  output.puts "ERROR: Pry started inside Pry."
166
168
  output.puts "This can happen if you have a binding.pry inside a #to_s " \
@@ -168,6 +170,12 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
168
170
  return
169
171
  end
170
172
 
173
+ unless mutex_available?
174
+ output.puts "ERROR: Unable to obtain mutex lock."
175
+ output.puts "This can happen if binding.pry is called from a signal handler"
176
+ return
177
+ end
178
+
171
179
  options[:target] = Pry.binding_for(target || toplevel_binding)
172
180
  initial_session_setup
173
181
  final_session_setup
@@ -209,7 +217,7 @@ you can add "Pry.config.windows_console_warning = false" to your pryrc.
209
217
  # The maximum number of chars before clipping occurs.
210
218
  #
211
219
  # @option options [Boolean] :id (false)
212
- # Boolean to indicate whether or not a hex reprsentation of the object ID
220
+ # Boolean to indicate whether or not a hex representation of the object ID
213
221
  # is attached to the return value when the length of inspect is greater than
214
222
  # value of `:max_length`.
215
223
  #
@@ -378,6 +386,13 @@ Readline version #{Readline::VERSION} detected - will not auto_resize! correctly
378
386
  ensure
379
387
  Thread.current[:pry_critical_section] -= 1
380
388
  end
389
+
390
+ def self.mutex_available?
391
+ Mutex.new.synchronize { true }
392
+ rescue ThreadError
393
+ false
394
+ end
395
+ private_class_method :mutex_available?
381
396
  end
382
397
 
383
398
  Pry.init
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'method_source'
4
- require 'ostruct'
5
4
 
6
5
  ##
7
6
  # Pry is a powerful alternative to the standard IRB shell for Ruby. It
@@ -20,7 +19,7 @@ require 'ostruct'
20
19
  # This will show a list of available commands and their usage. For more
21
20
  # information about Pry you can refer to the following resources:
22
21
  #
23
- # * http://pryrepl.org/
22
+ # * https://pry.github.io
24
23
  # * https://github.com/pry/pry
25
24
  # * the IRC channel, which is #pry on the Freenode network
26
25
  #
@@ -93,7 +92,6 @@ class Pry
93
92
  @input_ring << nil
94
93
  push_initial_binding(target)
95
94
  exec_hook(:when_started, target, options, self)
96
- @prompt_warn = false
97
95
  end
98
96
 
99
97
  # This is the prompt at the top of the prompt stack.
@@ -388,7 +386,7 @@ class Pry
388
386
  # @param [*Object] args The arguments to pass to the hook
389
387
  # @return [Object, Exception] The return value of the hook or the exception raised
390
388
  #
391
- # If executing a hook raises an exception, we log that and then continue sucessfully.
389
+ # If executing a hook raises an exception, we log that and then continue successfully.
392
390
  # To debug such errors, use the global variable $pry_hook_error, which is set as a
393
391
  # result.
394
392
  def exec_hook(name, *args, &block)
@@ -452,45 +450,17 @@ class Pry
452
450
  # @return [String] The prompt.
453
451
  def select_prompt
454
452
  object = current_binding.eval('self')
455
- open_token = @indent.open_delimiters.last || @indent.stack.last
456
-
457
- c = OpenStruct.new(
458
- object: object,
459
- nesting_level: binding_stack.size - 1,
460
- open_token: open_token,
461
- session_line: Pry.history.session_line_count + 1,
462
- history_line: Pry.history.history_line_count + 1,
463
- expr_number: input_ring.count,
464
- pry_instance: self,
465
- binding_stack: binding_stack,
466
- input_ring: input_ring,
467
- eval_string: @eval_string,
468
- cont: !@eval_string.empty?
469
- )
453
+ nesting_level = binding_stack.size - 1
454
+ pry_instance = self
470
455
 
471
456
  Pry.critical_section do
472
457
  # If input buffer is empty, then use normal prompt. Otherwise use the wait
473
458
  # prompt (indicating multi-line expression).
474
459
  if prompt.is_a?(Pry::Prompt)
475
460
  prompt_proc = eval_string.empty? ? prompt.wait_proc : prompt.incomplete_proc
476
- return prompt_proc.call(c.object, c.nesting_level, c.pry_instance)
477
- end
478
-
479
- unless @prompt_warn
480
- @prompt_warn = true
481
- Kernel.warn(
482
- "warning: setting prompt with help of " \
483
- "`Pry.config.prompt = [proc {}, proc {}]` is deprecated. " \
484
- "Use Pry::Prompt API instead"
485
- )
486
- end
487
-
488
- # If input buffer is empty then use normal prompt
489
- if eval_string.empty?
490
- generate_prompt(Array(prompt).first, c)
491
- # Otherwise use the wait prompt (indicating multi-line expression)
461
+ return prompt_proc.call(object, nesting_level, pry_instance)
492
462
  else
493
- generate_prompt(Array(prompt).last, c)
463
+ output.puts "ERROR: Use Pry::Prompt API."
494
464
  end
495
465
  end
496
466
  end
@@ -549,7 +519,7 @@ class Pry
549
519
  # and a mistake in specifying that exception.
550
520
  #
551
521
  # (i.e. raise-up RunThymeError.new should not be the same as
552
- # raise-up NameError, "unititialized constant RunThymeError")
522
+ # raise-up NameError, "uninitialized constant RunThymeError")
553
523
  #
554
524
  def raise_up_common(force, *args)
555
525
  exception = if args == []
@@ -685,14 +655,6 @@ class Pry
685
655
  end
686
656
  end
687
657
 
688
- def generate_prompt(prompt_proc, conf)
689
- if prompt_proc.arity == 1
690
- prompt_proc.call(conf)
691
- else
692
- prompt_proc.call(conf.object, conf.nesting_level, conf.pry_instance)
693
- end
694
- end
695
-
696
658
  # the array that the prompt stack is stored in
697
659
  def prompt_stack
698
660
  @prompt_stack ||= []
data/lib/pry/repl.rb CHANGED
@@ -100,7 +100,7 @@ class Pry
100
100
  # Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
101
101
  return val unless val.is_a?(String)
102
102
 
103
- if pry.config.auto_indent
103
+ if pry.config.auto_indent && !input_multiline?
104
104
  original_val = "#{indentation}#{val}"
105
105
  indented_val = @indent.indent(val)
106
106
 
@@ -141,8 +141,7 @@ class Pry
141
141
  retry
142
142
 
143
143
  # Handle <Ctrl+C> like Bash: empty the current input buffer, but don't
144
- # quit. This is only for MRI 1.9; other versions of Ruby don't let you
145
- # send Interrupt from within Readline.
144
+ # quit.
146
145
  rescue Interrupt
147
146
  return :control_c
148
147
 
@@ -180,7 +179,31 @@ class Pry
180
179
  end
181
180
  end
182
181
 
183
- if readline_available?
182
+ if reline_available?
183
+ Reline.output_modifier_proc = lambda do |text, _|
184
+ if pry.color
185
+ SyntaxHighlighter.highlight(text)
186
+ else
187
+ text
188
+ end
189
+ end
190
+
191
+ if pry.config.auto_indent
192
+ Reline.auto_indent_proc = lambda do |lines, line_index, _byte_ptr, _newline|
193
+ if line_index == 0
194
+ 0
195
+ else
196
+ pry_indentation = Pry::Indent.new
197
+ pry_indentation.indent(lines.join("\n"))
198
+ pry_indentation.last_indent_level.length
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ if input_multiline?
205
+ input_readmultiline(current_prompt, false)
206
+ elsif readline_available?
184
207
  set_readline_output
185
208
  input_readline(current_prompt, false) # false since we'll add it manually
186
209
  elsif coolline_available?
@@ -193,12 +216,29 @@ class Pry
193
216
  end
194
217
  end
195
218
 
219
+ def input_readmultiline(*args)
220
+ Pry::InputLock.for(:all).interruptible_region do
221
+ input.readmultiline(*args) do |multiline_input|
222
+ Pry.commands.find_command(multiline_input) ||
223
+ (complete_expression?(multiline_input) && !Reline::IOGate.in_pasting?)
224
+ end
225
+ end
226
+ end
227
+
196
228
  def input_readline(*args)
197
229
  Pry::InputLock.for(:all).interruptible_region do
198
230
  input.readline(*args)
199
231
  end
200
232
  end
201
233
 
234
+ def input_multiline?
235
+ !!pry.config.multiline && reline_available?
236
+ end
237
+
238
+ def reline_available?
239
+ defined?(Reline) && input == Reline
240
+ end
241
+
202
242
  def readline_available?
203
243
  defined?(Readline) && input == Readline
204
244
  end
@@ -207,6 +247,13 @@ class Pry
207
247
  defined?(Coolline) && input.is_a?(Coolline)
208
248
  end
209
249
 
250
+ def prism_available?
251
+ require 'prism'
252
+
253
+ @prism_available ||= defined?(Prism) &&
254
+ Gem::Version.new(Prism::VERSION) >= Gem::Version.new('0.25.0')
255
+ end
256
+
210
257
  # If `$stdout` is not a tty, it's probably a pipe.
211
258
  # @example
212
259
  # # `piping?` returns `false`
@@ -228,6 +275,21 @@ class Pry
228
275
  @readline_output = (Readline.output = Pry.config.output) if piping?
229
276
  end
230
277
 
278
+ UNEXPECTED_TOKENS = %i[unexpected_token_ignore lambda_open].freeze
279
+
280
+ def complete_expression?(multiline_input)
281
+ if prism_available?
282
+ lex = Prism.lex(multiline_input)
283
+
284
+ errors = lex.errors
285
+ return true if errors.empty?
286
+
287
+ errors.any? { |error| UNEXPECTED_TOKENS.include?(error.type) }
288
+ else
289
+ Pry::Code.complete_expression?(multiline_input)
290
+ end
291
+ end
292
+
231
293
  # Calculates correct overhang for current line. Supports vi Readline
232
294
  # mode and its indicators such as "(ins)" or "(cmd)".
233
295
  #