pry 0.9.12.2 → 0.14.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (237) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1141 -0
  3. data/LICENSE +2 -2
  4. data/README.md +466 -0
  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 +97 -92
  10. data/lib/pry/code/code_file.rb +114 -0
  11. data/lib/pry/code/code_range.rb +7 -4
  12. data/lib/pry/code/loc.rb +27 -14
  13. data/lib/pry/code.rb +62 -90
  14. data/lib/pry/code_object.rb +83 -39
  15. data/lib/pry/color_printer.rb +66 -0
  16. data/lib/pry/command.rb +202 -371
  17. data/lib/pry/command_set.rb +151 -133
  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 -73
  24. data/lib/pry/commands/cat/file_formatter.rb +56 -63
  25. data/lib/pry/commands/cat/input_expression_formatter.rb +35 -30
  26. data/lib/pry/commands/cat.rb +64 -47
  27. data/lib/pry/commands/cd.rb +42 -26
  28. data/lib/pry/commands/change_inspector.rb +34 -0
  29. data/lib/pry/commands/change_prompt.rb +51 -0
  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 +33 -24
  36. data/lib/pry/commands/edit.rb +183 -167
  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 -17
  40. data/lib/pry/commands/find_method.rb +167 -167
  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 +153 -132
  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 +42 -0
  47. data/lib/pry/commands/ls/constants.rb +75 -0
  48. data/lib/pry/commands/ls/formatter.rb +55 -0
  49. data/lib/pry/commands/ls/globals.rb +50 -0
  50. data/lib/pry/commands/ls/grep.rb +23 -0
  51. data/lib/pry/commands/ls/instance_vars.rb +40 -0
  52. data/lib/pry/commands/ls/interrogatable.rb +24 -0
  53. data/lib/pry/commands/ls/jruby_hacks.rb +55 -0
  54. data/lib/pry/commands/ls/local_names.rb +37 -0
  55. data/lib/pry/commands/ls/local_vars.rb +47 -0
  56. data/lib/pry/commands/ls/ls_entity.rb +65 -0
  57. data/lib/pry/commands/ls/methods.rb +55 -0
  58. data/lib/pry/commands/ls/methods_helper.rb +50 -0
  59. data/lib/pry/commands/ls/self_methods.rb +34 -0
  60. data/lib/pry/commands/ls.rb +100 -303
  61. data/lib/pry/commands/nesting.rb +21 -17
  62. data/lib/pry/commands/play.rb +93 -49
  63. data/lib/pry/commands/pry_backtrace.rb +22 -18
  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 +57 -48
  67. data/lib/pry/commands/reset.rb +16 -12
  68. data/lib/pry/commands/ri.rb +57 -38
  69. data/lib/pry/commands/save_file.rb +45 -43
  70. data/lib/pry/commands/shell_command.rb +66 -34
  71. data/lib/pry/commands/shell_mode.rb +22 -20
  72. data/lib/pry/commands/show_doc.rb +80 -65
  73. data/lib/pry/commands/show_info.rb +193 -159
  74. data/lib/pry/commands/show_input.rb +16 -11
  75. data/lib/pry/commands/show_source.rb +113 -33
  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 +21 -13
  79. data/lib/pry/commands/watch_expression/expression.rb +43 -0
  80. data/lib/pry/commands/watch_expression.rb +110 -0
  81. data/lib/pry/commands/whereami.rb +157 -134
  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 +290 -220
  88. data/lib/pry/control_d_handler.rb +28 -0
  89. data/lib/pry/core_extensions.rb +50 -27
  90. data/lib/pry/editor.rb +130 -102
  91. data/lib/pry/env.rb +18 -0
  92. data/lib/pry/exception_handler.rb +43 -0
  93. data/lib/pry/exceptions.rb +73 -0
  94. data/lib/pry/forwardable.rb +27 -0
  95. data/lib/pry/helpers/base_helpers.rb +22 -151
  96. data/lib/pry/helpers/command_helpers.rb +55 -63
  97. data/lib/pry/helpers/documentation_helpers.rb +21 -13
  98. data/lib/pry/helpers/options_helpers.rb +15 -8
  99. data/lib/pry/helpers/platform.rb +55 -0
  100. data/lib/pry/helpers/table.rb +44 -32
  101. data/lib/pry/helpers/text.rb +96 -86
  102. data/lib/pry/helpers.rb +3 -0
  103. data/lib/pry/history.rb +101 -70
  104. data/lib/pry/hooks.rb +67 -137
  105. data/lib/pry/indent.rb +79 -73
  106. data/lib/pry/input_completer.rb +283 -0
  107. data/lib/pry/input_lock.rb +129 -0
  108. data/lib/pry/inspector.rb +39 -0
  109. data/lib/pry/last_exception.rb +61 -0
  110. data/lib/pry/method/disowned.rb +19 -5
  111. data/lib/pry/{commands/edit/method_patcher.rb → method/patcher.rb} +51 -42
  112. data/lib/pry/method/weird_method_locator.rb +80 -44
  113. data/lib/pry/method.rb +225 -176
  114. data/lib/pry/object_path.rb +91 -0
  115. data/lib/pry/output.rb +136 -0
  116. data/lib/pry/pager.rb +227 -68
  117. data/lib/pry/prompt.rb +214 -0
  118. data/lib/pry/pry_class.rb +216 -289
  119. data/lib/pry/pry_instance.rb +438 -500
  120. data/lib/pry/repl.rb +256 -0
  121. data/lib/pry/repl_file_loader.rb +34 -35
  122. data/lib/pry/ring.rb +89 -0
  123. data/lib/pry/slop/LICENSE +20 -0
  124. data/lib/pry/slop/commands.rb +190 -0
  125. data/lib/pry/slop/option.rb +210 -0
  126. data/lib/pry/slop.rb +672 -0
  127. data/lib/pry/syntax_highlighter.rb +26 -0
  128. data/lib/pry/system_command_handler.rb +17 -0
  129. data/lib/pry/testable/evalable.rb +24 -0
  130. data/lib/pry/testable/mockable.rb +22 -0
  131. data/lib/pry/testable/pry_tester.rb +88 -0
  132. data/lib/pry/testable/utility.rb +34 -0
  133. data/lib/pry/testable/variables.rb +52 -0
  134. data/lib/pry/testable.rb +68 -0
  135. data/lib/pry/version.rb +3 -1
  136. data/lib/pry/warning.rb +20 -0
  137. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +36 -43
  138. data/lib/pry/wrapped_module.rb +102 -103
  139. data/lib/pry.rb +135 -261
  140. metadata +94 -283
  141. data/.document +0 -2
  142. data/.gitignore +0 -16
  143. data/.travis.yml +0 -21
  144. data/.yardopts +0 -1
  145. data/CHANGELOG +0 -534
  146. data/CONTRIBUTORS +0 -55
  147. data/Gemfile +0 -9
  148. data/Guardfile +0 -62
  149. data/README.markdown +0 -400
  150. data/Rakefile +0 -140
  151. data/TODO +0 -117
  152. data/lib/pry/commands/disabled_commands.rb +0 -2
  153. data/lib/pry/commands/gem_cd.rb +0 -26
  154. data/lib/pry/commands/gem_install.rb +0 -29
  155. data/lib/pry/commands/gem_list.rb +0 -33
  156. data/lib/pry/commands/gem_open.rb +0 -29
  157. data/lib/pry/commands/gist.rb +0 -102
  158. data/lib/pry/commands/install_command.rb +0 -51
  159. data/lib/pry/commands/simple_prompt.rb +0 -22
  160. data/lib/pry/commands.rb +0 -6
  161. data/lib/pry/completion.rb +0 -304
  162. data/lib/pry/custom_completions.rb +0 -6
  163. data/lib/pry/history_array.rb +0 -116
  164. data/lib/pry/plugins.rb +0 -103
  165. data/lib/pry/rbx_method.rb +0 -13
  166. data/lib/pry/rbx_path.rb +0 -22
  167. data/lib/pry/rubygem.rb +0 -74
  168. data/lib/pry/terminal.rb +0 -78
  169. data/lib/pry/test/helper.rb +0 -185
  170. data/man/pry.1 +0 -195
  171. data/man/pry.1.html +0 -204
  172. data/man/pry.1.ronn +0 -141
  173. data/pry.gemspec +0 -30
  174. data/spec/Procfile +0 -3
  175. data/spec/cli_spec.rb +0 -78
  176. data/spec/code_object_spec.rb +0 -277
  177. data/spec/code_spec.rb +0 -219
  178. data/spec/command_helpers_spec.rb +0 -29
  179. data/spec/command_integration_spec.rb +0 -644
  180. data/spec/command_set_spec.rb +0 -627
  181. data/spec/command_spec.rb +0 -821
  182. data/spec/commands/amend_line_spec.rb +0 -247
  183. data/spec/commands/bang_spec.rb +0 -19
  184. data/spec/commands/cat_spec.rb +0 -164
  185. data/spec/commands/cd_spec.rb +0 -250
  186. data/spec/commands/disable_pry_spec.rb +0 -25
  187. data/spec/commands/edit_spec.rb +0 -727
  188. data/spec/commands/exit_all_spec.rb +0 -34
  189. data/spec/commands/exit_program_spec.rb +0 -19
  190. data/spec/commands/exit_spec.rb +0 -34
  191. data/spec/commands/find_method_spec.rb +0 -70
  192. data/spec/commands/gem_list_spec.rb +0 -26
  193. data/spec/commands/gist_spec.rb +0 -79
  194. data/spec/commands/help_spec.rb +0 -56
  195. data/spec/commands/hist_spec.rb +0 -181
  196. data/spec/commands/jump_to_spec.rb +0 -15
  197. data/spec/commands/ls_spec.rb +0 -181
  198. data/spec/commands/play_spec.rb +0 -140
  199. data/spec/commands/raise_up_spec.rb +0 -56
  200. data/spec/commands/save_file_spec.rb +0 -177
  201. data/spec/commands/show_doc_spec.rb +0 -510
  202. data/spec/commands/show_input_spec.rb +0 -17
  203. data/spec/commands/show_source_spec.rb +0 -782
  204. data/spec/commands/whereami_spec.rb +0 -203
  205. data/spec/completion_spec.rb +0 -239
  206. data/spec/control_d_handler_spec.rb +0 -58
  207. data/spec/documentation_helper_spec.rb +0 -73
  208. data/spec/editor_spec.rb +0 -79
  209. data/spec/exception_whitelist_spec.rb +0 -21
  210. data/spec/fixtures/candidate_helper1.rb +0 -11
  211. data/spec/fixtures/candidate_helper2.rb +0 -8
  212. data/spec/fixtures/example.erb +0 -5
  213. data/spec/fixtures/example_nesting.rb +0 -33
  214. data/spec/fixtures/show_source_doc_examples.rb +0 -15
  215. data/spec/fixtures/testrc +0 -2
  216. data/spec/fixtures/testrcbad +0 -2
  217. data/spec/fixtures/whereami_helper.rb +0 -6
  218. data/spec/helper.rb +0 -34
  219. data/spec/helpers/bacon.rb +0 -86
  220. data/spec/helpers/mock_pry.rb +0 -43
  221. data/spec/helpers/table_spec.rb +0 -105
  222. data/spec/history_array_spec.rb +0 -67
  223. data/spec/hooks_spec.rb +0 -522
  224. data/spec/indent_spec.rb +0 -301
  225. data/spec/input_stack_spec.rb +0 -90
  226. data/spec/method_spec.rb +0 -482
  227. data/spec/prompt_spec.rb +0 -60
  228. data/spec/pry_defaults_spec.rb +0 -419
  229. data/spec/pry_history_spec.rb +0 -99
  230. data/spec/pry_output_spec.rb +0 -95
  231. data/spec/pry_spec.rb +0 -504
  232. data/spec/run_command_spec.rb +0 -25
  233. data/spec/sticky_locals_spec.rb +0 -157
  234. data/spec/syntax_checking_spec.rb +0 -81
  235. data/spec/wrapped_module_spec.rb +0 -261
  236. data/wiki/Customizing-pry.md +0 -397
  237. data/wiki/Home.md +0 -4
@@ -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 variables. 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`).
@@ -84,14 +97,14 @@ class Object
84
97
  # it has the nice property that we can memoize this check.
85
98
  begin
86
99
  # instance_eval sets the default definee to the object's singleton class
87
- instance_eval *Pry::BINDING_METHOD_IMPL
100
+ instance_eval(*Pry::BINDING_METHOD_IMPL)
88
101
 
89
102
  # If we can't define methods on the Object's singleton_class. Then we fall
90
103
  # back to setting the default definee to be the Object's class. That seems
91
104
  # nicer than having a REPL in which you can't define methods.
92
- rescue TypeError
105
+ rescue TypeError, Pry::FrozenObjectException
93
106
  # class_eval sets the default definee to self.class
94
- self.class.class_eval *Pry::BINDING_METHOD_IMPL
107
+ self.class.class_eval(*Pry::BINDING_METHOD_IMPL)
95
108
  end
96
109
  end
97
110
 
@@ -99,23 +112,33 @@ class Object
99
112
  end
100
113
  end
101
114
 
102
- # There's a splat bug on jruby in 1.9 emulation mode, which breaks the
103
- # pp library.
104
- #
105
- # * http://jira.codehaus.org/browse/JRUBY-6687
106
- # * https://github.com/pry/pry/issues/568
107
- #
108
- # Until that gets fixed upstream, let's monkey-patch here:
109
- if [[1, 2]].pretty_inspect == "[1]\n"
110
- class Array
111
- def pretty_print(q)
112
- q.group(1, '[', ']') {
113
- i = 0
114
- q.seplist(self) { |*|
115
- q.pp self[i]
116
- i += 1
117
- }
118
- }
119
- end
115
+ class BasicObject
116
+ # Return a binding object for the receiver.
117
+ #
118
+ # The `self` of the binding is set to the current object, and it contains no
119
+ # local variables.
120
+ #
121
+ # The default definee (http://yugui.jp/articles/846) is set such that new
122
+ # methods defined will be added to the singleton class of the BasicObject.
123
+ #
124
+ # @return [Binding]
125
+ def __binding__
126
+ # BasicObjects don't have respond_to?, so we just define the method
127
+ # every time. As they also don't have `.freeze`, this call won't
128
+ # fail as it can for normal Objects.
129
+ (class << self; self; end).class_eval(<<-METHOD, __FILE__, __LINE__ + 1)
130
+ # Get a binding with 'self' set to self, and no locals.
131
+ #
132
+ # The default definee is determined by the context in which the
133
+ # definition is eval'd.
134
+ #
135
+ # Please don't call this method directly, see {__binding__}.
136
+ #
137
+ # @return [Binding]
138
+ def __pry__
139
+ ::Kernel.binding
140
+ end
141
+ METHOD
142
+ __pry__
120
143
  end
121
144
  end
data/lib/pry/editor.rb CHANGED
@@ -1,129 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shellwords'
4
+
1
5
  class Pry
2
6
  class Editor
3
- extend Pry::Helpers::BaseHelpers
4
- extend Pry::Helpers::CommandHelpers
5
-
6
- class << self
7
- def edit_tempfile_with_content(initial_content, line=1)
8
- temp_file do |f|
9
- f.puts(initial_content)
10
- f.flush
11
- f.close(false)
12
- invoke_editor(f.path, line, true)
13
- File.read(f.path)
14
- end
7
+ def self.default
8
+ if (visual = Pry::Env['VISUAL'])
9
+ return visual
15
10
  end
16
11
 
17
- def invoke_editor(file, line, blocking=true)
18
- raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless Pry.config.editor
12
+ if (editor = Pry::Env['EDITOR'])
13
+ return editor
14
+ end
19
15
 
20
- editor_invocation = build_editor_invocation_string(file, line, blocking)
21
- return nil unless editor_invocation
16
+ return 'notepad' if Helpers::Platform.windows?
22
17
 
23
- if jruby?
24
- open_editor_on_jruby(editor_invocation)
25
- else
26
- open_editor(editor_invocation)
27
- end
18
+ %w[editor nano vi].find do |editor_exe|
19
+ Kernel.system("which #{editor_exe} > /dev/null 2>&1")
28
20
  end
21
+ end
29
22
 
30
- private
23
+ include Pry::Helpers::CommandHelpers
31
24
 
32
- # Generate the string that's used to start the editor. This includes
33
- # all the flags we want as well as the file and line number we
34
- # want to open at.
35
- def build_editor_invocation_string(file, line, blocking)
25
+ attr_reader :pry_instance
36
26
 
37
- if Pry.config.editor.respond_to?(:call)
38
- args = [file, line, blocking][0...(Pry.config.editor.arity)]
39
- Pry.config.editor.call(*args)
40
- else
41
- sanitized_file = if windows?
42
- file.gsub(/\//, '\\')
43
- else
44
- Shellwords.escape(file)
45
- end
27
+ def initialize(pry_instance)
28
+ @pry_instance = pry_instance
29
+ end
46
30
 
47
- "#{Pry.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
48
- end
31
+ def edit_tempfile_with_content(initial_content, line = 1)
32
+ temp_file do |f|
33
+ f.puts(initial_content)
34
+ f.flush
35
+ f.close(false)
36
+ invoke_editor(f.path, line, true)
37
+ File.read(f.path)
49
38
  end
39
+ end
50
40
 
51
- # Start the editor running, using the calculated invocation string
52
- def open_editor(editor_invocation)
53
- # Note we dont want to use Pry.config.system here as that
54
- # may be invoked non-interactively (i.e via Open4), whereas we want to
55
- # ensure the editor is always interactive
56
- system(editor_invocation) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
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"
57
45
  end
58
46
 
59
- # We need JRuby specific code here cos just shelling out using
60
- # system() appears to be pretty broken :/
61
- def open_editor_on_jruby(editor_invocation)
62
- begin
63
- require 'spoon'
64
- pid = Spoon.spawnp(*editor_invocation.split)
65
- Process.waitpid(pid)
66
- rescue FFI::NotFoundError
67
- system(editor_invocation)
68
- end
47
+ editor_invocation = build_editor_invocation_string(file, line, blocking)
48
+ return nil unless editor_invocation
49
+
50
+ if Helpers::Platform.jruby?
51
+ open_editor_on_jruby(editor_invocation)
52
+ else
53
+ open_editor(editor_invocation)
69
54
  end
55
+ end
70
56
 
71
- # Some editors that run outside the terminal allow you to control whether or
72
- # not to block the process from which they were launched (in this case, Pry).
73
- # For those editors, return the flag that produces the desired behavior.
74
- def blocking_flag_for_editor(blocking)
75
- case editor_name
76
- when /^emacsclient/
77
- '--no-wait' unless blocking
78
- when /^[gm]vim/
79
- '--nofork' if blocking
80
- when /^jedit/
81
- '-wait' if blocking
82
- when /^mate/, /^subl/
83
- '-w' if blocking
84
- end
57
+ # Generate the string that's used to start the editor. This includes
58
+ # all the flags we want as well as the file and line number we
59
+ # want to open at.
60
+ def build_editor_invocation_string(file, line, blocking)
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)
64
+ else
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}"
85
70
  end
71
+ end
86
72
 
87
- # Return the syntax for a given editor for starting the editor
88
- # and moving to a particular line within that file
89
- def start_line_syntax_for_editor(file_name, line_number)
90
- # special case for 1st line
91
- return file_name if line_number <= 1
73
+ private
92
74
 
93
- case editor_name
94
- when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
95
- "+#{line_number} #{file_name}"
96
- when /^mate/, /^geany/
97
- "-l #{line_number} #{file_name}"
98
- when /^subl/
99
- "#{file_name}:#{line_number}"
100
- when /^uedit32/
101
- "#{file_name}/#{line_number}"
102
- when /^jedit/
103
- "#{file_name} +line:#{line_number}"
104
- else
105
- if windows?
106
- "#{file_name}"
107
- else
108
- "+#{line_number} #{file_name}"
109
- end
110
- end
75
+ # Start the editor running, using the calculated invocation string
76
+ def open_editor(editor_invocation)
77
+ # Note we dont want to use Pry.config.system here as that
78
+ # may be invoked non-interactively (i.e via Open4), whereas we want to
79
+ # ensure the editor is always interactive
80
+ system(*Shellwords.split(editor_invocation)) ||
81
+ raise(
82
+ CommandError,
83
+ "`#{editor_invocation}` gave exit status: #{$CHILD_STATUS.exitstatus}"
84
+ )
85
+ end
86
+
87
+ # We need JRuby specific code here cos just shelling out using
88
+ # system() appears to be pretty broken :/
89
+ def open_editor_on_jruby(editor_invocation)
90
+ require 'spoon'
91
+ pid = Spoon.spawnp(*Shellwords.split(editor_invocation))
92
+ Process.waitpid(pid)
93
+ rescue FFI::NotFoundError
94
+ system(editor_invocation)
95
+ end
96
+
97
+ # Some editors that run outside the terminal allow you to control whether or
98
+ # not to block the process from which they were launched (in this case, Pry).
99
+ # For those editors, return the flag that produces the desired behavior.
100
+ def blocking_flag_for_editor(blocking)
101
+ case editor_name
102
+ when /^emacsclient/
103
+ '--no-wait' unless blocking
104
+ when /^[gm]vim/
105
+ '--nofork' if blocking
106
+ when /^jedit/
107
+ '-wait' if blocking
108
+ when /^mate/, /^subl/, /^redcar/, /^code/
109
+ '-w' if blocking
111
110
  end
111
+ end
112
112
 
113
- # Get the name of the binary that Pry.config.editor points to.
114
- #
115
- # This is useful for deciding which flags we pass to the editor as
116
- # we can just use the program's name and ignore any absolute paths.
117
- #
118
- # @example
119
- # Pry.config.editor="/home/conrad/bin/textmate -w"
120
- # editor_name
121
- # # => textmate
122
- #
123
- def editor_name
124
- File.basename(Pry.config.editor).split(" ").first
113
+ # Return the syntax for a given editor for starting the editor
114
+ # and moving to a particular line within that file
115
+ def start_line_syntax_for_editor(file_name, line_number)
116
+ # special case for 1st line
117
+ return file_name if line_number <= 1
118
+
119
+ case editor_name
120
+ when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/
121
+ "+#{line_number} #{file_name}"
122
+ when /^mate/, /^geany/
123
+ "-l #{line_number} #{file_name}"
124
+ when /^code/
125
+ "-g #{file_name}:#{line_number}"
126
+ when /^subl/
127
+ "#{file_name}:#{line_number}"
128
+ when /^uedit32/
129
+ "#{file_name}/#{line_number}"
130
+ when /^jedit/
131
+ "#{file_name} +line:#{line_number}"
132
+ when /^redcar/
133
+ "-l#{line_number} #{file_name}"
134
+ else
135
+ if Helpers::Platform.windows?
136
+ file_name.to_s
137
+ else
138
+ "+#{line_number} #{file_name}"
139
+ end
125
140
  end
141
+ end
126
142
 
143
+ # Get the name of the binary that Pry.config.editor points to.
144
+ #
145
+ # This is useful for deciding which flags we pass to the editor as
146
+ # we can just use the program's name and ignore any absolute paths.
147
+ #
148
+ # @example
149
+ # Pry.config.editor="/home/conrad/bin/textmate -w"
150
+ # editor_name
151
+ # # => textmate
152
+ #
153
+ def editor_name
154
+ File.basename(pry_instance.config.editor).split(" ").first
127
155
  end
128
156
  end
129
157
  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
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ # As a REPL, we often want to catch any unexpected exceptions that may have
5
+ # been raised; however we don't want to go overboard and prevent the user
6
+ # from exiting Pry when they want to.
7
+ module RescuableException
8
+ def self.===(exception)
9
+ case exception
10
+ # Catch when the user hits ^C (Interrupt < SignalException), and assume
11
+ # that they just wanted to stop the in-progress command (just like bash
12
+ # etc.)
13
+ when Interrupt
14
+ true
15
+ # Don't catch signals (particularly not SIGTERM) as these are unlikely
16
+ # to be intended for pry itself. We should also make sure that
17
+ # Kernel#exit works.
18
+ when *Pry.config.unrescued_exceptions
19
+ false
20
+ # All other exceptions will be caught.
21
+ else
22
+ true
23
+ end
24
+ end
25
+ end
26
+
27
+ # Catches SecurityErrors if $SAFE is set
28
+ module TooSafeException
29
+ def self.===(exception)
30
+ if Pry::HAS_SAFE_LEVEL
31
+ $SAFE > 0 && exception.is_a?(SecurityError)
32
+ else
33
+ exception.is_a?(SecurityError)
34
+ end
35
+ end
36
+ end
37
+
38
+ # An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error
39
+ # in a more user-friendly manner. This should be used when the exception
40
+ # happens within Pry itself as a direct consequence of the user typing
41
+ # something wrong.
42
+ #
43
+ # This allows us to distinguish between the user typing:
44
+ #
45
+ # pry(main)> def )
46
+ # SyntaxError: unexpected )
47
+ #
48
+ # pry(main)> method_that_evals("def )")
49
+ # SyntaxError: (eval):1: syntax error, unexpected ')'
50
+ # from ./a.rb:2 in `eval'
51
+ module UserError; end
52
+
53
+ # When we try to get a binding for an object, we try to define a method on
54
+ # that Object's singleton class. This doesn't work for "frozen" Object's, and
55
+ # the exception is just a vanilla RuntimeError.
56
+ module FrozenObjectException
57
+ def self.===(exception)
58
+ [
59
+ "can't modify frozen class/module",
60
+ "can't modify frozen Class",
61
+ "can't modify frozen object"
62
+ ].include?(exception.message)
63
+ end
64
+ end
65
+
66
+ # CommandErrors are caught by the REPL loop and displayed to the user. They
67
+ # indicate an exceptional condition that's fatal to the current command.
68
+ class CommandError < StandardError; end
69
+ class MethodNotFound < CommandError; end
70
+
71
+ # indicates obsolete API
72
+ class ObsoleteError < StandardError; end
73
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Pry
4
+ module Forwardable
5
+ require 'forwardable'
6
+ include ::Forwardable
7
+
8
+ #
9
+ # Since Ruby 2.4, Forwardable will print a warning when
10
+ # calling a method that is private on a delegate, and
11
+ # in the future it could be an error: https://bugs.ruby-lang.org/issues/12782#note-3
12
+ #
13
+ # That's why we revert to a custom implementation for delegating one
14
+ # private method to another.
15
+ #
16
+ def def_private_delegators(target, *private_delegates)
17
+ private_delegates.each do |private_delegate|
18
+ define_method(private_delegate) do |*a, &b|
19
+ instance_variable_get(target).__send__(private_delegate, *a, &b)
20
+ end
21
+ end
22
+ class_eval do
23
+ private(*private_delegates) # rubocop:disable Style/AccessModifierDeclarations
24
+ end
25
+ end
26
+ end
27
+ end