pry 0.10.4 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -16
  3. data/LICENSE +1 -1
  4. data/README.md +352 -306
  5. data/bin/pry +4 -7
  6. data/lib/pry/basic_object.rb +10 -0
  7. data/lib/pry/block_command.rb +22 -0
  8. data/lib/pry/class_command.rb +194 -0
  9. data/lib/pry/cli.rb +81 -74
  10. data/lib/pry/code/code_file.rb +37 -26
  11. data/lib/pry/code/code_range.rb +7 -5
  12. data/lib/pry/code/loc.rb +26 -13
  13. data/lib/pry/code.rb +48 -31
  14. data/lib/pry/code_object.rb +53 -28
  15. data/lib/pry/color_printer.rb +46 -35
  16. data/lib/pry/command.rb +197 -369
  17. data/lib/pry/command_set.rb +89 -114
  18. data/lib/pry/command_state.rb +31 -0
  19. data/lib/pry/commands/amend_line.rb +86 -82
  20. data/lib/pry/commands/bang.rb +18 -14
  21. data/lib/pry/commands/bang_pry.rb +15 -11
  22. data/lib/pry/commands/cat/abstract_formatter.rb +23 -18
  23. data/lib/pry/commands/cat/exception_formatter.rb +85 -72
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -46
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +62 -54
  27. data/lib/pry/commands/cd.rb +40 -35
  28. data/lib/pry/commands/change_inspector.rb +29 -22
  29. data/lib/pry/commands/change_prompt.rb +48 -23
  30. data/lib/pry/commands/clear_screen.rb +20 -0
  31. data/lib/pry/commands/code_collector.rb +148 -131
  32. data/lib/pry/commands/disable_pry.rb +23 -19
  33. data/lib/pry/commands/easter_eggs.rb +23 -34
  34. data/lib/pry/commands/edit/exception_patcher.rb +21 -17
  35. data/lib/pry/commands/edit/file_and_line_locator.rb +34 -23
  36. data/lib/pry/commands/edit.rb +185 -157
  37. data/lib/pry/commands/exit.rb +40 -35
  38. data/lib/pry/commands/exit_all.rb +24 -20
  39. data/lib/pry/commands/exit_program.rb +20 -16
  40. data/lib/pry/commands/find_method.rb +168 -162
  41. data/lib/pry/commands/fix_indent.rb +16 -12
  42. data/lib/pry/commands/help.rb +140 -133
  43. data/lib/pry/commands/hist.rb +151 -149
  44. data/lib/pry/commands/import_set.rb +20 -15
  45. data/lib/pry/commands/jump_to.rb +25 -21
  46. data/lib/pry/commands/list_inspectors.rb +35 -28
  47. data/lib/pry/commands/ls/constants.rb +59 -31
  48. data/lib/pry/commands/ls/formatter.rb +42 -36
  49. data/lib/pry/commands/ls/globals.rb +38 -36
  50. data/lib/pry/commands/ls/grep.rb +17 -15
  51. data/lib/pry/commands/ls/instance_vars.rb +29 -28
  52. data/lib/pry/commands/ls/interrogatable.rb +18 -12
  53. data/lib/pry/commands/ls/jruby_hacks.rb +47 -41
  54. data/lib/pry/commands/ls/local_names.rb +26 -24
  55. data/lib/pry/commands/ls/local_vars.rb +38 -30
  56. data/lib/pry/commands/ls/ls_entity.rb +47 -52
  57. data/lib/pry/commands/ls/methods.rb +49 -51
  58. data/lib/pry/commands/ls/methods_helper.rb +46 -42
  59. data/lib/pry/commands/ls/self_methods.rb +23 -21
  60. data/lib/pry/commands/ls.rb +124 -103
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +92 -82
  63. data/lib/pry/commands/pry_backtrace.rb +24 -17
  64. data/lib/pry/commands/pry_version.rb +15 -11
  65. data/lib/pry/commands/raise_up.rb +33 -27
  66. data/lib/pry/commands/reload_code.rb +60 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -42
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +56 -29
  71. data/lib/pry/commands/shell_mode.rb +22 -18
  72. data/lib/pry/commands/show_doc.rb +81 -70
  73. data/lib/pry/commands/show_info.rb +193 -160
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +109 -42
  76. data/lib/pry/commands/stat.rb +35 -31
  77. data/lib/pry/commands/switch_to.rb +21 -15
  78. data/lib/pry/commands/toggle_color.rb +20 -16
  79. data/lib/pry/commands/watch_expression/expression.rb +32 -27
  80. data/lib/pry/commands/watch_expression.rb +89 -84
  81. data/lib/pry/commands/whereami.rb +155 -146
  82. data/lib/pry/commands/wtf.rb +78 -40
  83. data/lib/pry/config/attributable.rb +22 -0
  84. data/lib/pry/config/lazy_value.rb +29 -0
  85. data/lib/pry/config/memoized_value.rb +34 -0
  86. data/lib/pry/config/value.rb +24 -0
  87. data/lib/pry/config.rb +317 -20
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +22 -9
  90. data/lib/pry/editor.rb +53 -33
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +13 -18
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +20 -62
  96. data/lib/pry/helpers/command_helpers.rb +52 -62
  97. data/lib/pry/helpers/documentation_helpers.rb +20 -12
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +60 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -85
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +81 -55
  104. data/lib/pry/hooks.rb +60 -110
  105. data/lib/pry/indent.rb +72 -66
  106. data/lib/pry/input_completer.rb +199 -158
  107. data/lib/pry/input_lock.rb +7 -10
  108. data/lib/pry/inspector.rb +36 -24
  109. data/lib/pry/last_exception.rb +45 -45
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/method/patcher.rb +14 -8
  112. data/lib/pry/method/weird_method_locator.rb +79 -45
  113. data/lib/pry/method.rb +177 -124
  114. data/lib/pry/object_path.rb +37 -28
  115. data/lib/pry/output.rb +102 -16
  116. data/lib/pry/pager.rb +187 -177
  117. data/lib/pry/plugins.rb +49 -13
  118. data/lib/pry/prompt.rb +213 -25
  119. data/lib/pry/pry_class.rb +106 -93
  120. data/lib/pry/pry_instance.rb +261 -224
  121. data/lib/pry/repl.rb +82 -27
  122. data/lib/pry/repl_file_loader.rb +27 -22
  123. data/lib/pry/ring.rb +89 -0
  124. data/lib/pry/slop/LICENSE +20 -0
  125. data/lib/pry/slop/commands.rb +190 -0
  126. data/lib/pry/slop/option.rb +210 -0
  127. data/lib/pry/slop.rb +672 -0
  128. data/lib/pry/syntax_highlighter.rb +26 -0
  129. data/lib/pry/system_command_handler.rb +17 -0
  130. data/lib/pry/testable/evalable.rb +24 -0
  131. data/lib/pry/testable/mockable.rb +22 -0
  132. data/lib/pry/testable/pry_tester.rb +88 -0
  133. data/lib/pry/testable/utility.rb +34 -0
  134. data/lib/pry/testable/variables.rb +52 -0
  135. data/lib/pry/testable.rb +68 -0
  136. data/lib/pry/version.rb +3 -1
  137. data/lib/pry/warning.rb +27 -0
  138. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +28 -27
  139. data/lib/pry/wrapped_module.rb +66 -57
  140. data/lib/pry.rb +134 -149
  141. metadata +49 -59
  142. data/lib/pry/commands/disabled_commands.rb +0 -2
  143. data/lib/pry/commands/gem_cd.rb +0 -26
  144. data/lib/pry/commands/gem_install.rb +0 -32
  145. data/lib/pry/commands/gem_list.rb +0 -33
  146. data/lib/pry/commands/gem_open.rb +0 -29
  147. data/lib/pry/commands/gist.rb +0 -101
  148. data/lib/pry/commands/install_command.rb +0 -53
  149. data/lib/pry/commands/list_prompts.rb +0 -35
  150. data/lib/pry/commands/simple_prompt.rb +0 -22
  151. data/lib/pry/commands.rb +0 -6
  152. data/lib/pry/config/behavior.rb +0 -139
  153. data/lib/pry/config/convenience.rb +0 -25
  154. data/lib/pry/config/default.rb +0 -161
  155. data/lib/pry/history_array.rb +0 -121
  156. data/lib/pry/rbx_path.rb +0 -22
  157. data/lib/pry/rubygem.rb +0 -82
  158. data/lib/pry/terminal.rb +0 -79
  159. data/lib/pry/test/helper.rb +0 -170
data/lib/pry/config.rb CHANGED
@@ -1,24 +1,321 @@
1
- class Pry::Config
2
- require_relative 'config/behavior'
3
- require_relative 'config/default'
4
- require_relative 'config/convenience'
5
- include Pry::Config::Behavior
6
-
7
- def self.shortcuts
8
- Convenience::SHORTCUTS
9
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+
5
+ class Pry
6
+ # @api private
7
+ class Config
8
+ extend Attributable
9
+
10
+ # @return [IO, #readline] he object from which Pry retrieves its lines of
11
+ # input
12
+ attribute :input
13
+
14
+ # @return [IO, #puts] where Pry should output results provided by {input}
15
+ attribute :output
16
+
17
+ # @return [Pry::CommandSet]
18
+ attribute :commands
19
+
20
+ # @return [Proc] the printer for Ruby expressions (not commands)
21
+ attribute :print
22
+
23
+ # @return [Proc] the printer for exceptions
24
+ attribute :exception_handler
25
+
26
+ # @return [Array] Exception that Pry shouldn't rescue
27
+ attribute :unrescued_exceptions
28
+
29
+ # @deprecated
30
+ # @return [Array] Exception that Pry shouldn't rescue
31
+ attribute :exception_whitelist
32
+
33
+ # @return [Integer] The number of lines of context to show before and after
34
+ # exceptions
35
+ attribute :default_window_size
36
+
37
+ # @return [Pry::Hooks]
38
+ attribute :hooks
39
+
40
+ # @return [Pry::Prompt]
41
+ attribute :prompt
42
+
43
+ # @return [String] The display name that is part of the prompt
44
+ attribute :prompt_name
45
+
46
+ # @return [Array<Object>] the list of objects that are known to have a
47
+ # 1-line #inspect output suitable for prompt
48
+ attribute :prompt_safe_contexts
49
+
50
+ # If it is a String, then that String is used as the shell
51
+ # command to invoke the editor.
52
+ #
53
+ # If it responds to #call is callable then `file`, `line`, and `reloading`
54
+ # are passed to it. `reloading` indicates whether Pry will be reloading code
55
+ # after the shell command returns. All parameters are optional.
56
+ # @return [String, #call]
57
+ attribute :editor
58
+
59
+ # A string that must precede all commands. For example, if is is
60
+ # set to "%", the "cd" command must be invoked as "%cd").
61
+ # @return [String]
62
+ attribute :command_prefix
63
+
64
+ # @return [Boolean]
65
+ attribute :color
66
+
67
+ # @return [Boolean]
68
+ attribute :pager
69
+
70
+ # @return [Boolean] whether the global ~/.pryrc should be loaded
71
+ attribute :should_load_rc
72
+
73
+ # @return [Boolean] whether the local ./.pryrc should be loaded
74
+ attribute :should_load_local_rc
75
+
76
+ # @return [Boolean]
77
+ attribute :should_load_plugins
78
+
79
+ # @return [Boolean] whether to load files specified with the -r flag
80
+ attribute :should_load_requires
81
+
82
+ # @return [Boolean] whether to disable edit-method's auto-reloading behavior
83
+ attribute :disable_auto_reload
84
+
85
+ # Whether Pry should trap SIGINT and cause it to raise an Interrupt
86
+ # exception. This is only useful on JRuby, MRI does this for us.
87
+ # @return [Boolean]
88
+ attribute :should_trap_interrupts
89
+
90
+ # @return [Pry::History]
91
+ attribute :history
92
+
93
+ # @return [Boolean]
94
+ attribute :history_save
95
+
96
+ # @return [Boolean]
97
+ attribute :history_load
98
+
99
+ # @return [String]
100
+ attribute :history_file
101
+
102
+ # @return [Array<String,Regexp>]
103
+ attribute :history_ignorelist
104
+
105
+ # @return [Array<String>] Ruby files to be required
106
+ attribute :requires
107
+
108
+ # @return [Integer] how many input/output lines to keep in memory
109
+ attribute :memory_size
110
+
111
+ # @return [Proc] The proc that runs system commands
112
+ attribute :system
113
+
114
+ # @return [Boolean]
115
+ attribute :auto_indent
116
+
117
+ # @return [Boolean]
118
+ attribute :correct_indent
119
+
120
+ # @return [Boolean] whether or not display a warning when a command name
121
+ # collides with a method/local in the current context.
122
+ attribute :collision_warning
123
+
124
+ # @return [Hash{Symbol=>Proc}]
125
+ attribute :extra_sticky_locals
126
+
127
+ # @return [#build_completion_proc] a completer to use
128
+ attribute :completer
129
+
130
+ # @return [Boolean] suppresses whereami output on `binding.pry`
131
+ attribute :quiet
132
+
133
+ # @return [Boolean] displays a warning about experience improvement on
134
+ # Windows
135
+ attribute :windows_console_warning
136
+
137
+ # @return [Proc]
138
+ attribute :command_completions
139
+
140
+ # @return [Proc]
141
+ attribute :file_completions
142
+
143
+ # @return [Hash]
144
+ attribute :ls
145
+
146
+ # @return [String] a line of code to execute in context before the session
147
+ # starts
148
+ attribute :exec_string
149
+
150
+ # @return [String]
151
+ attribute :output_prefix
152
+
153
+ # @return [String]
154
+ # @since v0.13.0
155
+ attribute :rc_file
156
+
157
+ def initialize
158
+ merge!(
159
+ input: MemoizedValue.new { lazy_readline },
160
+ output: $stdout.tap { |out| out.sync = true },
161
+ commands: Pry::Commands,
162
+ prompt_name: 'pry',
163
+ prompt: Pry::Prompt[:default],
164
+ prompt_safe_contexts: [String, Numeric, Symbol, nil, true, false],
165
+ print: Pry::ColorPrinter.method(:default),
166
+ quiet: false,
167
+ exception_handler: Pry::ExceptionHandler.method(:handle_exception),
168
+
169
+ unrescued_exceptions: [
170
+ ::SystemExit, ::SignalException, Pry::TooSafeException
171
+ ],
172
+
173
+ exception_whitelist: MemoizedValue.new do
174
+ output.puts(
175
+ '[warning] Pry.config.exception_whitelist is deprecated, ' \
176
+ 'please use Pry.config.unrescued_exceptions instead.'
177
+ )
178
+ unrescued_exceptions
179
+ end,
180
+
181
+ hooks: Pry::Hooks.default,
182
+ pager: true,
183
+ system: Pry::SystemCommandHandler.method(:default),
184
+ color: Pry::Helpers::BaseHelpers.use_ansi_codes?,
185
+ default_window_size: 5,
186
+ editor: Pry::Editor.default,
187
+ rc_file: default_rc_file,
188
+ should_load_rc: true,
189
+ should_load_local_rc: true,
190
+ should_trap_interrupts: Pry::Helpers::Platform.jruby?,
191
+ disable_auto_reload: false,
192
+ command_prefix: '',
193
+ auto_indent: Pry::Helpers::BaseHelpers.use_ansi_codes?,
194
+ correct_indent: true,
195
+ collision_warning: false,
196
+ output_prefix: '=> ',
197
+ requires: [],
198
+ should_load_requires: true,
199
+ should_load_plugins: true,
200
+ windows_console_warning: true,
201
+ control_d_handler: Pry::ControlDHandler.method(:default),
202
+ memory_size: 100,
203
+ extra_sticky_locals: {},
204
+ command_completions: proc { commands.keys },
205
+ file_completions: proc { Dir['.'] },
206
+ ls: OpenStruct.new(Pry::Command::Ls::DEFAULT_OPTIONS),
207
+ completer: Pry::InputCompleter,
208
+ history_save: true,
209
+ history_load: true,
210
+ history_file: Pry::History.default_file,
211
+ history_ignorelist: [],
212
+ history: MemoizedValue.new do
213
+ if defined?(input::HISTORY)
214
+ Pry::History.new(history: input::HISTORY)
215
+ else
216
+ Pry::History.new
217
+ end
218
+ end,
219
+ exec_string: ''
220
+ )
221
+
222
+ @custom_attrs = {}
223
+ end
224
+
225
+ def merge!(config_hash)
226
+ config_hash.each_pair { |attr, value| __send__("#{attr}=", value) }
227
+ self
228
+ end
229
+
230
+ def merge(config_hash)
231
+ dup.merge!(config_hash)
232
+ end
233
+
234
+ def []=(attr, value)
235
+ @custom_attrs[attr.to_s] = Config::Value.new(value)
236
+ end
237
+
238
+ def [](attr)
239
+ @custom_attrs[attr.to_s].call
240
+ end
241
+
242
+ def method_missing(method_name, *args, &block)
243
+ name = method_name.to_s
244
+
245
+ if name.end_with?('=')
246
+ self[name[0..-2]] = args.first
247
+ elsif @custom_attrs.key?(name)
248
+ self[name]
249
+ else
250
+ super
251
+ end
252
+ end
253
+
254
+ def respond_to_missing?(method_name, include_all = false)
255
+ @custom_attrs.key?(method_name.to_s.tr('=', '')) || super
256
+ end
257
+
258
+ def initialize_dup(other)
259
+ super
260
+ @custom_attrs = @custom_attrs.dup
261
+ end
262
+
263
+ attr_reader :control_d_handler
264
+ def control_d_handler=(value)
265
+ proxy_proc =
266
+ if value.arity == 2
267
+ Pry::Warning.warn(
268
+ "control_d_handler's arity of 2 parameters was deprecated " \
269
+ '(eval_string, pry_instance). Now it gets passed just 1 ' \
270
+ 'parameter (pry_instance)'
271
+ )
272
+ proc do |*args|
273
+ if args.size == 2
274
+ value.call(args.first, args[1])
275
+ else
276
+ value.call(args.first.eval_string, args.first)
277
+ end
278
+ end
279
+ else
280
+ proc do |*args|
281
+ if args.size == 2
282
+ value.call(args[1])
283
+ else
284
+ value.call(args.first)
285
+ end
286
+ end
287
+ end
288
+ @control_d_handler = proxy_proc
289
+ end
290
+
291
+ private
292
+
293
+ def lazy_readline
294
+ require 'readline'
295
+ ::Readline
296
+ rescue LoadError
297
+ output.puts(
298
+ "Sorry, you can't use Pry without Readline or a compatible library. \n" \
299
+ "Possible solutions: \n" \
300
+ " * Rebuild Ruby with Readline support using `--with-readline` \n" \
301
+ " * Use the rb-readline gem, which is a pure-Ruby port of Readline \n" \
302
+ " * Use the pry-coolline gem, a pure-ruby alternative to Readline"
303
+ )
304
+ raise
305
+ end
10
306
 
11
- #
12
- # FIXME
13
- # @param [Pry::Hooks] hooks
14
- #
15
- def hooks=(hooks)
16
- if hooks.is_a?(Hash)
17
- warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object " \
18
- "instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
19
- self["hooks"] = Pry::Hooks.from_hash(hooks)
20
- else
21
- self["hooks"] = hooks
307
+ def default_rc_file
308
+ if (pryrc = Pry::Env['PRYRC'])
309
+ pryrc
310
+ elsif (xdg_home = Pry::Env['XDG_CONFIG_HOME'])
311
+ # See XDG Base Directory Specification at
312
+ # https://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
313
+ xdg_home + '/pry/pryrc'
314
+ elsif File.exist?(File.expand_path('~/.pryrc'))
315
+ '~/.pryrc'
316
+ else
317
+ '~/.config/pry/pryrc'
318
+ end
22
319
  end
23
320
  end
24
321
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # @api private
5
+ # @since v0.13.0
6
+ module ControlDHandler
7
+ # Deal with the ^D key being pressed. Different behaviour in different
8
+ # cases:
9
+ # 1. In an expression behave like `!` command.
10
+ # 2. At top-level session behave like `exit` command.
11
+ # 3. In a nested session behave like `cd ..`.
12
+ def self.default(pry_instance)
13
+ if !pry_instance.eval_string.empty?
14
+ # Clear input buffer.
15
+ pry_instance.eval_string = ''
16
+ elsif pry_instance.binding_stack.one?
17
+ pry_instance.binding_stack.clear
18
+ throw(:breakout)
19
+ else
20
+ # Otherwise, saves current binding stack as old stack and pops last
21
+ # binding out of binding stack (the old stack still has that binding).
22
+ cd_state = Pry::CommandState.default.state_for('cd')
23
+ cd_state.old_stack = pry_instance.binding_stack.dup
24
+ pry_instance.binding_stack.pop
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Pry
2
4
  # @return [Array] Code of the method used when implementing Pry's
3
5
  # __binding__, along with line indication to be used with instance_eval (and
4
6
  # friends).
5
7
  #
6
8
  # @see Object#__binding__
7
- BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1]
9
+ BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1].freeze
8
10
  # Get a binding with 'self' set to self, and no locals.
9
11
  #
10
12
  # The default definee is determined by the context in which the
@@ -38,8 +40,8 @@ class Object
38
40
  # end
39
41
  # my_method()
40
42
  # @see Pry.start
41
- def pry(object=nil, hash={})
42
- if object.nil? || Hash === object
43
+ def pry(object = nil, hash = {})
44
+ if object.nil? || Hash === object # rubocop:disable Style/CaseEquality
43
45
  Pry.start(self, object || {})
44
46
  else
45
47
  Pry.start(object, hash)
@@ -68,15 +70,26 @@ class Object
68
70
  def __binding__
69
71
  # If you ever feel like changing this method, be careful about variables
70
72
  # that you use. They shouldn't be inserted into the binding that will
71
- # eventually be returning.
73
+ # eventually be returned.
72
74
 
73
75
  # When you're cd'd into a class, methods you define should be added to it.
74
76
  if is_a?(Module)
77
+ # A special case, for JRuby.
78
+ # Module.new.class_eval("binding") has different behaviour than CRuby,
79
+ # where this is not needed: class_eval("binding") vs class_eval{binding}.
80
+ # Using a block works around the difference of behaviour on JRuby.
81
+ # The scope is clear of local variabless. Don't add any.
82
+ #
83
+ # This fixes the following two spec failures, at https://travis-ci.org/pry/pry/jobs/274470002
84
+ # 1) ./spec/pry_spec.rb:360:in `block in (root)'
85
+ # 2) ./spec/pry_spec.rb:366:in `block in (root)'
86
+ return class_eval { binding } if Pry::Helpers::Platform.jruby? && name.nil?
87
+
75
88
  # class_eval sets both self and the default definee to this class.
76
- return class_eval "binding"
89
+ return class_eval("binding", __FILE__, __LINE__)
77
90
  end
78
91
 
79
- unless respond_to?(:__pry__)
92
+ unless self.class.method_defined?(:__pry__)
80
93
  # The easiest way to check whether an object has a working singleton class
81
94
  # is to try and define a method on it. (just checking for the presence of
82
95
  # the singleton class gives false positives for `true` and `false`).
@@ -113,7 +126,7 @@ class BasicObject
113
126
  # BasicObjects don't have respond_to?, so we just define the method
114
127
  # every time. As they also don't have `.freeze`, this call won't
115
128
  # fail as it can for normal Objects.
116
- (class << self; self; end).class_eval <<-EOF, __FILE__, __LINE__ + 1
129
+ (class << self; self; end).class_eval(<<-METHOD, __FILE__, __LINE__ + 1)
117
130
  # Get a binding with 'self' set to self, and no locals.
118
131
  #
119
132
  # The default definee is determined by the context in which the
@@ -125,7 +138,7 @@ class BasicObject
125
138
  def __pry__
126
139
  ::Kernel.binding
127
140
  end
128
- EOF
129
- self.__pry__
141
+ METHOD
142
+ __pry__
130
143
  end
131
144
  end
data/lib/pry/editor.rb CHANGED
@@ -1,15 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shellwords'
4
+
1
5
  class Pry
2
6
  class Editor
3
- include Pry::Helpers::BaseHelpers
7
+ def self.default
8
+ if (visual = Pry::Env['VISUAL'])
9
+ return visual
10
+ end
11
+
12
+ if (editor = Pry::Env['EDITOR'])
13
+ return editor
14
+ end
15
+
16
+ return 'notepad' if Helpers::Platform.windows?
17
+
18
+ %w[editor nano vi].find do |editor_exe|
19
+ Kernel.system("which #{editor_exe} > /dev/null 2>&1")
20
+ end
21
+ end
22
+
4
23
  include Pry::Helpers::CommandHelpers
5
24
 
6
- attr_reader :_pry_
25
+ attr_reader :pry_instance
7
26
 
8
- def initialize(_pry_)
9
- @_pry_ = _pry_
27
+ def initialize(pry_instance)
28
+ @pry_instance = pry_instance
10
29
  end
11
30
 
12
- def edit_tempfile_with_content(initial_content, line=1)
31
+ def edit_tempfile_with_content(initial_content, line = 1)
13
32
  temp_file do |f|
14
33
  f.puts(initial_content)
15
34
  f.flush
@@ -19,58 +38,60 @@ class Pry
19
38
  end
20
39
  end
21
40
 
22
- def invoke_editor(file, line, blocking=true)
23
- raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless _pry_.config.editor
41
+ def invoke_editor(file, line, blocking = true)
42
+ unless pry_instance.config.editor
43
+ raise CommandError,
44
+ "Please set Pry.config.editor or export $VISUAL or $EDITOR"
45
+ end
24
46
 
25
47
  editor_invocation = build_editor_invocation_string(file, line, blocking)
26
48
  return nil unless editor_invocation
27
49
 
28
- if jruby?
50
+ if Helpers::Platform.jruby?
29
51
  open_editor_on_jruby(editor_invocation)
30
52
  else
31
53
  open_editor(editor_invocation)
32
54
  end
33
55
  end
34
56
 
35
- private
36
-
37
57
  # Generate the string that's used to start the editor. This includes
38
58
  # all the flags we want as well as the file and line number we
39
59
  # want to open at.
40
60
  def build_editor_invocation_string(file, line, blocking)
41
-
42
- if _pry_.config.editor.respond_to?(:call)
43
- args = [file, line, blocking][0...(_pry_.config.editor.arity)]
44
- _pry_.config.editor.call(*args)
61
+ if pry_instance.config.editor.respond_to?(:call)
62
+ args = [file, line, blocking][0...(pry_instance.config.editor.arity)]
63
+ pry_instance.config.editor.call(*args)
45
64
  else
46
- sanitized_file = if windows?
47
- file.gsub(/\//, '\\')
48
- else
49
- Shellwords.escape(file)
50
- end
51
-
52
- "#{_pry_.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
65
+ sanitized_file = Helpers::Platform.windows? ? file : Shellwords.escape(file)
66
+ editor = pry_instance.config.editor
67
+ flag = blocking_flag_for_editor(blocking)
68
+ start_line = start_line_syntax_for_editor(sanitized_file, line)
69
+ "#{editor} #{flag} #{start_line}"
53
70
  end
54
71
  end
55
72
 
73
+ private
74
+
56
75
  # Start the editor running, using the calculated invocation string
57
76
  def open_editor(editor_invocation)
58
77
  # Note we dont want to use Pry.config.system here as that
59
78
  # may be invoked non-interactively (i.e via Open4), whereas we want to
60
79
  # ensure the editor is always interactive
61
- system(*Shellwords.split(editor_invocation)) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
80
+ system(*Shellwords.split(editor_invocation)) ||
81
+ raise(
82
+ CommandError,
83
+ "`#{editor_invocation}` gave exit status: #{$CHILD_STATUS.exitstatus}"
84
+ )
62
85
  end
63
86
 
64
87
  # We need JRuby specific code here cos just shelling out using
65
88
  # system() appears to be pretty broken :/
66
89
  def open_editor_on_jruby(editor_invocation)
67
- begin
68
- require 'spoon'
69
- pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
70
- Process.waitpid(pid)
71
- rescue FFI::NotFoundError
72
- system(editor_invocation)
73
- end
90
+ require 'spoon'
91
+ pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
92
+ Process.waitpid(pid)
93
+ rescue FFI::NotFoundError
94
+ system(editor_invocation)
74
95
  end
75
96
 
76
97
  # Some editors that run outside the terminal allow you to control whether or
@@ -109,8 +130,8 @@ class Pry
109
130
  when /^redcar/
110
131
  "-l#{line_number} #{file_name}"
111
132
  else
112
- if windows?
113
- "#{file_name}"
133
+ if Helpers::Platform.windows?
134
+ file_name.to_s
114
135
  else
115
136
  "+#{line_number} #{file_name}"
116
137
  end
@@ -128,8 +149,7 @@ class Pry
128
149
  # # => textmate
129
150
  #
130
151
  def editor_name
131
- File.basename(_pry_.config.editor).split(" ").first
152
+ File.basename(pry_instance.config.editor).split(" ").first
132
153
  end
133
-
134
154
  end
135
155
  end
data/lib/pry/env.rb ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # Env is a helper module to work with environment variables.
5
+ #
6
+ # @since v0.13.0
7
+ # @api private
8
+ module Env
9
+ def self.[](key)
10
+ return unless ENV.key?(key)
11
+
12
+ value = ENV[key]
13
+ return if value == ''
14
+
15
+ value
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # @api private
5
+ # @since v0.13.0
6
+ module ExceptionHandler
7
+ class << self
8
+ # Will only show the first line of the backtrace.
9
+ def handle_exception(output, exception, _pry_instance)
10
+ if exception.is_a?(UserError) && exception.is_a?(SyntaxError)
11
+ output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}"
12
+ else
13
+ output.puts standard_error_text_for(exception)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def standard_error_text_for(exception)
20
+ text = exception_text(exception)
21
+ return text unless exception.respond_to?(:cause)
22
+
23
+ cause = exception.cause
24
+ while cause
25
+ text += cause_text(cause)
26
+ cause = cause.cause
27
+ end
28
+
29
+ text
30
+ end
31
+
32
+ def exception_text(exception)
33
+ "#{exception.class}: #{exception.message}\n" \
34
+ "from #{exception.backtrace.first}\n"
35
+ end
36
+
37
+ def cause_text(cause)
38
+ "Caused by #{cause.class}: #{cause}\n" \
39
+ "from #{cause.backtrace.first}\n"
40
+ end
41
+ end
42
+ end
43
+ end