pry 0.9.10pre1-i386-mswin32 → 0.9.11-i386-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG +63 -2
  3. data/CONTRIBUTORS +43 -25
  4. data/Gemfile +7 -0
  5. data/Guardfile +62 -0
  6. data/README.markdown +4 -4
  7. data/Rakefile +34 -35
  8. data/lib/pry.rb +107 -54
  9. data/lib/pry/cli.rb +34 -11
  10. data/lib/pry/code.rb +165 -182
  11. data/lib/pry/code/code_range.rb +70 -0
  12. data/lib/pry/code/loc.rb +92 -0
  13. data/lib/pry/code_object.rb +153 -0
  14. data/lib/pry/command.rb +160 -22
  15. data/lib/pry/command_set.rb +37 -26
  16. data/lib/pry/commands.rb +4 -27
  17. data/lib/pry/commands/amend_line.rb +99 -0
  18. data/lib/pry/commands/bang.rb +20 -0
  19. data/lib/pry/commands/bang_pry.rb +17 -0
  20. data/lib/pry/commands/cat.rb +53 -0
  21. data/lib/pry/commands/cat/abstract_formatter.rb +27 -0
  22. data/lib/pry/commands/cat/exception_formatter.rb +78 -0
  23. data/lib/pry/commands/cat/file_formatter.rb +84 -0
  24. data/lib/pry/commands/cat/input_expression_formatter.rb +43 -0
  25. data/lib/pry/commands/cd.rb +30 -0
  26. data/lib/pry/commands/code_collector.rb +165 -0
  27. data/lib/pry/commands/deprecated_commands.rb +2 -0
  28. data/lib/pry/commands/disable_pry.rb +27 -0
  29. data/lib/pry/commands/easter_eggs.rb +112 -0
  30. data/lib/pry/commands/edit.rb +206 -0
  31. data/lib/pry/commands/edit/exception_patcher.rb +25 -0
  32. data/lib/pry/commands/edit/file_and_line_locator.rb +38 -0
  33. data/lib/pry/commands/edit/method_patcher.rb +122 -0
  34. data/lib/pry/commands/exit.rb +42 -0
  35. data/lib/pry/commands/exit_all.rb +29 -0
  36. data/lib/pry/commands/exit_program.rb +24 -0
  37. data/lib/pry/commands/find_method.rb +199 -0
  38. data/lib/pry/commands/fix_indent.rb +19 -0
  39. data/lib/pry/commands/gem_cd.rb +26 -0
  40. data/lib/pry/commands/gem_install.rb +29 -0
  41. data/lib/pry/commands/gem_list.rb +33 -0
  42. data/lib/pry/commands/gem_open.rb +29 -0
  43. data/lib/pry/commands/gist.rb +95 -0
  44. data/lib/pry/commands/help.rb +164 -0
  45. data/lib/pry/commands/hist.rb +161 -0
  46. data/lib/pry/commands/import_set.rb +22 -0
  47. data/lib/pry/commands/install_command.rb +51 -0
  48. data/lib/pry/commands/jump_to.rb +29 -0
  49. data/lib/pry/commands/ls.rb +339 -0
  50. data/lib/pry/commands/nesting.rb +25 -0
  51. data/lib/pry/commands/play.rb +69 -0
  52. data/lib/pry/commands/pry_backtrace.rb +26 -0
  53. data/lib/pry/commands/pry_version.rb +17 -0
  54. data/lib/pry/commands/raise_up.rb +32 -0
  55. data/lib/pry/commands/reload_code.rb +39 -0
  56. data/lib/pry/commands/reset.rb +18 -0
  57. data/lib/pry/commands/ri.rb +56 -0
  58. data/lib/pry/commands/save_file.rb +61 -0
  59. data/lib/pry/commands/shell_command.rb +43 -0
  60. data/lib/pry/commands/shell_mode.rb +27 -0
  61. data/lib/pry/commands/show_doc.rb +78 -0
  62. data/lib/pry/commands/show_info.rb +139 -0
  63. data/lib/pry/commands/show_input.rb +17 -0
  64. data/lib/pry/commands/show_source.rb +37 -0
  65. data/lib/pry/commands/simple_prompt.rb +22 -0
  66. data/lib/pry/commands/stat.rb +40 -0
  67. data/lib/pry/commands/switch_to.rb +23 -0
  68. data/lib/pry/commands/toggle_color.rb +20 -0
  69. data/lib/pry/commands/whereami.rb +114 -0
  70. data/lib/pry/commands/wtf.rb +57 -0
  71. data/lib/pry/completion.rb +120 -46
  72. data/lib/pry/config.rb +11 -0
  73. data/lib/pry/core_extensions.rb +30 -19
  74. data/lib/pry/editor.rb +129 -0
  75. data/lib/pry/helpers.rb +1 -0
  76. data/lib/pry/helpers/base_helpers.rb +89 -119
  77. data/lib/pry/helpers/command_helpers.rb +7 -122
  78. data/lib/pry/helpers/table.rb +100 -0
  79. data/lib/pry/helpers/text.rb +4 -4
  80. data/lib/pry/history_array.rb +5 -0
  81. data/lib/pry/hooks.rb +1 -3
  82. data/lib/pry/indent.rb +104 -30
  83. data/lib/pry/method.rb +66 -22
  84. data/lib/pry/module_candidate.rb +26 -15
  85. data/lib/pry/pager.rb +70 -0
  86. data/lib/pry/plugins.rb +1 -2
  87. data/lib/pry/pry_class.rb +63 -22
  88. data/lib/pry/pry_instance.rb +58 -37
  89. data/lib/pry/rubygem.rb +74 -0
  90. data/lib/pry/terminal_info.rb +43 -0
  91. data/lib/pry/test/helper.rb +185 -0
  92. data/lib/pry/version.rb +1 -1
  93. data/lib/pry/wrapped_module.rb +58 -24
  94. data/pry.gemspec +21 -37
  95. data/{test/test_cli.rb → spec/cli_spec.rb} +0 -0
  96. data/spec/code_object_spec.rb +277 -0
  97. data/{test/test_code.rb → spec/code_spec.rb} +19 -1
  98. data/{test/test_command_helpers.rb → spec/command_helpers_spec.rb} +0 -0
  99. data/{test/test_command_integration.rb → spec/command_integration_spec.rb} +38 -46
  100. data/{test/test_command_set.rb → spec/command_set_spec.rb} +18 -1
  101. data/{test/test_command.rb → spec/command_spec.rb} +250 -149
  102. data/spec/commands/amend_line_spec.rb +247 -0
  103. data/spec/commands/bang_spec.rb +19 -0
  104. data/spec/commands/cat_spec.rb +164 -0
  105. data/spec/commands/cd_spec.rb +250 -0
  106. data/spec/commands/disable_pry_spec.rb +25 -0
  107. data/spec/commands/edit_spec.rb +727 -0
  108. data/spec/commands/exit_all_spec.rb +34 -0
  109. data/spec/commands/exit_program_spec.rb +19 -0
  110. data/spec/commands/exit_spec.rb +34 -0
  111. data/{test/test_default_commands/test_find_method.rb → spec/commands/find_method_spec.rb} +27 -7
  112. data/spec/commands/gem_list_spec.rb +26 -0
  113. data/spec/commands/gist_spec.rb +75 -0
  114. data/{test/test_default_commands/test_help.rb → spec/commands/help_spec.rb} +8 -9
  115. data/spec/commands/hist_spec.rb +181 -0
  116. data/spec/commands/jump_to_spec.rb +15 -0
  117. data/spec/commands/ls_spec.rb +177 -0
  118. data/spec/commands/play_spec.rb +140 -0
  119. data/spec/commands/raise_up_spec.rb +56 -0
  120. data/spec/commands/save_file_spec.rb +177 -0
  121. data/spec/commands/show_doc_spec.rb +378 -0
  122. data/spec/commands/show_input_spec.rb +17 -0
  123. data/spec/commands/show_source_spec.rb +597 -0
  124. data/spec/commands/whereami_spec.rb +154 -0
  125. data/spec/completion_spec.rb +233 -0
  126. data/spec/control_d_handler_spec.rb +58 -0
  127. data/spec/editor_spec.rb +79 -0
  128. data/{test/test_exception_whitelist.rb → spec/exception_whitelist_spec.rb} +0 -0
  129. data/{test → spec/fixtures}/candidate_helper1.rb +0 -0
  130. data/{test → spec/fixtures}/candidate_helper2.rb +0 -0
  131. data/{test/test_default_commands → spec/fixtures}/example.erb +0 -0
  132. data/spec/fixtures/example_nesting.rb +33 -0
  133. data/spec/fixtures/show_source_doc_examples.rb +15 -0
  134. data/{test → spec/fixtures}/testrc +0 -0
  135. data/{test → spec/fixtures}/testrcbad +0 -0
  136. data/spec/helper.rb +34 -0
  137. data/spec/helpers/bacon.rb +86 -0
  138. data/spec/helpers/mock_pry.rb +43 -0
  139. data/spec/helpers/table_spec.rb +83 -0
  140. data/{test/test_history_array.rb → spec/history_array_spec.rb} +21 -19
  141. data/{test/test_hooks.rb → spec/hooks_spec.rb} +0 -0
  142. data/{test/test_indent.rb → spec/indent_spec.rb} +24 -0
  143. data/{test/test_input_stack.rb → spec/input_stack_spec.rb} +4 -0
  144. data/{test/test_method.rb → spec/method_spec.rb} +65 -1
  145. data/{test/test_prompt.rb → spec/prompt_spec.rb} +0 -0
  146. data/{test/test_pry_defaults.rb → spec/pry_defaults_spec.rb} +14 -14
  147. data/{test/test_pry_history.rb → spec/pry_history_spec.rb} +15 -0
  148. data/spec/pry_output_spec.rb +95 -0
  149. data/{test/test_pry.rb → spec/pry_spec.rb} +74 -32
  150. data/{test/test_sticky_locals.rb → spec/sticky_locals_spec.rb} +27 -25
  151. data/{test/test_syntax_checking.rb → spec/syntax_checking_spec.rb} +17 -1
  152. data/{test/test_wrapped_module.rb → spec/wrapped_module_spec.rb} +92 -5
  153. metadata +239 -115
  154. data/examples/example_basic.rb +0 -15
  155. data/examples/example_command_override.rb +0 -32
  156. data/examples/example_commands.rb +0 -36
  157. data/examples/example_hooks.rb +0 -9
  158. data/examples/example_image_edit.rb +0 -67
  159. data/examples/example_input.rb +0 -7
  160. data/examples/example_input2.rb +0 -29
  161. data/examples/example_output.rb +0 -11
  162. data/examples/example_print.rb +0 -6
  163. data/examples/example_prompt.rb +0 -9
  164. data/examples/helper.rb +0 -6
  165. data/lib/pry/default_commands/cd.rb +0 -81
  166. data/lib/pry/default_commands/commands.rb +0 -62
  167. data/lib/pry/default_commands/context.rb +0 -98
  168. data/lib/pry/default_commands/easter_eggs.rb +0 -95
  169. data/lib/pry/default_commands/editing.rb +0 -420
  170. data/lib/pry/default_commands/find_method.rb +0 -169
  171. data/lib/pry/default_commands/gems.rb +0 -84
  172. data/lib/pry/default_commands/gist.rb +0 -187
  173. data/lib/pry/default_commands/help.rb +0 -127
  174. data/lib/pry/default_commands/hist.rb +0 -120
  175. data/lib/pry/default_commands/input_and_output.rb +0 -306
  176. data/lib/pry/default_commands/introspection.rb +0 -410
  177. data/lib/pry/default_commands/ls.rb +0 -272
  178. data/lib/pry/default_commands/misc.rb +0 -38
  179. data/lib/pry/default_commands/navigating_pry.rb +0 -110
  180. data/lib/pry/default_commands/whereami.rb +0 -92
  181. data/lib/pry/extended_commands/experimental.rb +0 -7
  182. data/test/helper.rb +0 -223
  183. data/test/test_completion.rb +0 -62
  184. data/test/test_control_d_handler.rb +0 -45
  185. data/test/test_default_commands/test_cd.rb +0 -321
  186. data/test/test_default_commands/test_context.rb +0 -288
  187. data/test/test_default_commands/test_documentation.rb +0 -315
  188. data/test/test_default_commands/test_gems.rb +0 -18
  189. data/test/test_default_commands/test_input.rb +0 -428
  190. data/test/test_default_commands/test_introspection.rb +0 -511
  191. data/test/test_default_commands/test_ls.rb +0 -151
  192. data/test/test_default_commands/test_shell.rb +0 -343
  193. data/test/test_default_commands/test_show_source.rb +0 -432
  194. data/test/test_pry_output.rb +0 -41
@@ -1,9 +1,31 @@
1
1
  # taken from irb
2
2
 
3
- require "readline"
4
-
5
3
  class Pry
6
4
 
5
+ module BondCompleter
6
+
7
+ def self.build_completion_proc(target, pry=nil, commands=[""])
8
+ if !@started
9
+ @started = true
10
+ start
11
+ end
12
+
13
+ Pry.current[:pry] = pry
14
+ proc{ |*a| Bond.agent.call(*a) }
15
+ end
16
+
17
+ def self.start
18
+ Bond.start(:eval_binding => lambda{ Pry.current[:pry].current_context })
19
+ Bond.complete(:on => /\A/) do |input|
20
+ Pry.commands.complete(input.line,
21
+ :pry_instance => Pry.current[:pry],
22
+ :target => Pry.current[:pry].current_context,
23
+ :command_set => Pry.current[:pry].commands)
24
+ end
25
+ end
26
+
27
+ end
28
+
7
29
  # Implements tab completion for Readline in Pry
8
30
  module InputCompleter
9
31
 
@@ -41,36 +63,51 @@ class Pry
41
63
  # Return a new completion proc for use by Readline.
42
64
  # @param [Binding] target The current binding context.
43
65
  # @param [Array<String>] commands The array of Pry commands.
44
- def self.build_completion_proc(target, commands=[""])
66
+ def self.build_completion_proc(target, pry=nil, commands=[""])
67
+
45
68
  proc do |input|
69
+
70
+ # if there are multiple contexts e.g. cd 1/2/3
71
+ # get new target for 1/2 and find candidates for 3
72
+ path, input = build_path(input)
73
+
74
+ unless path.call.empty?
75
+ target, _ = Pry::Helpers::BaseHelpers.context_from_object_path(path.call, pry)
76
+ target = target.last
77
+ end
78
+
46
79
  begin
47
80
  bind = target
48
81
 
49
82
  case input
83
+
84
+
85
+ # Complete stdlib symbols
86
+
50
87
  when /^(\/[^\/]*\/)\.([^.]*)$/
51
88
  # Regexp
52
89
  receiver = $1
53
90
  message = Regexp.quote($2)
54
91
 
55
- candidates = Regexp.instance_methods.collect{|m| m.to_s}
56
- select_message(receiver, message, candidates)
92
+ candidates = Regexp.instance_methods.collect(&:to_s)
93
+ select_message(path, receiver, message, candidates)
57
94
 
58
95
  when /^([^\]]*\])\.([^.]*)$/
59
96
  # Array
60
97
  receiver = $1
61
98
  message = Regexp.quote($2)
62
99
 
63
- candidates = Array.instance_methods.collect{|m| m.to_s}
64
- select_message(receiver, message, candidates)
100
+ candidates = Array.instance_methods.collect(&:to_s)
101
+ select_message(path, receiver, message, candidates)
65
102
 
66
103
  when /^([^\}]*\})\.([^.]*)$/
67
104
  # Proc or Hash
68
105
  receiver = $1
69
106
  message = Regexp.quote($2)
70
107
 
71
- candidates = Proc.instance_methods.collect{|m| m.to_s}
72
- candidates |= Hash.instance_methods.collect{|m| m.to_s}
73
- select_message(receiver, message, candidates)
108
+ candidates = Proc.instance_methods.collect(&:to_s)
109
+ candidates |= Hash.instance_methods.collect(&:to_s)
110
+ select_message(path, receiver, message, candidates)
74
111
 
75
112
  when /^(:[^:.]*)$/
76
113
  # Symbol
@@ -86,16 +123,32 @@ class Pry
86
123
  when /^::([A-Z][^:\.\(]*)$/
87
124
  # Absolute Constant or class methods
88
125
  receiver = $1
89
- candidates = Object.constants.collect{|m| m.to_s}
126
+ candidates = Object.constants.collect(&:to_s)
90
127
  candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
91
128
 
129
+
130
+ # Complete target symbols
131
+
132
+ when /^([A-Z][A-Za-z0-9]*)$/
133
+ # Constant
134
+ message = $1
135
+
136
+ begin
137
+ context = target.eval("self")
138
+ context = context.class unless context.respond_to? :constants
139
+ candidates = context.constants.collect(&:to_s)
140
+ rescue
141
+ candidates = []
142
+ end
143
+ candidates = candidates.grep(/^#{message}/).collect(&path)
144
+
92
145
  when /^([A-Z].*)::([^:.]*)$/
93
146
  # Constant or class methods
94
147
  receiver = $1
95
148
  message = Regexp.quote($2)
96
149
  begin
97
- candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
98
- candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
150
+ candidates = eval("#{receiver}.constants.collect(&:to_s)", bind)
151
+ candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind)
99
152
  rescue RescuableException
100
153
  candidates = []
101
154
  end
@@ -106,8 +159,8 @@ class Pry
106
159
  receiver = $1
107
160
  message = Regexp.quote($2)
108
161
 
109
- candidates = Symbol.instance_methods.collect{|m| m.to_s}
110
- select_message(receiver, message, candidates)
162
+ candidates = Symbol.instance_methods.collect(&:to_s)
163
+ select_message(path, receiver, message, candidates)
111
164
 
112
165
  when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
113
166
  # Numeric
@@ -115,42 +168,43 @@ class Pry
115
168
  message = Regexp.quote($5)
116
169
 
117
170
  begin
118
- candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
171
+ candidates = eval(receiver, bind).methods.collect(&:to_s)
119
172
  rescue RescuableException
120
173
  candidates = []
121
174
  end
122
- select_message(receiver, message, candidates)
175
+ select_message(path, receiver, message, candidates)
123
176
 
124
- when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
177
+ when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/#
125
178
  # Numeric(0xFFFF)
126
179
  receiver = $1
127
180
  message = Regexp.quote($2)
128
181
 
129
182
  begin
130
- candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
183
+ candidates = eval(receiver, bind).methods.collect(&:to_s)
131
184
  rescue RescuableException
132
185
  candidates = []
133
186
  end
134
- select_message(receiver, message, candidates)
187
+ select_message(path, receiver, message, candidates)
135
188
 
136
189
  when /^(\$[^.]*)$/
190
+ # Global variables
137
191
  regmessage = Regexp.new(Regexp.quote($1))
138
- candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
192
+ candidates = global_variables.collect(&:to_s).grep(regmessage)
139
193
 
140
194
  when /^([^."].*)\.([^.]*)$/
141
- # variable
195
+ # Variable
142
196
  receiver = $1
143
197
  message = Regexp.quote($2)
144
198
 
145
- gv = eval("global_variables", bind).collect{|m| m.to_s}
146
- lv = eval("local_variables", bind).collect{|m| m.to_s}
147
- cv = eval("self.class.constants", bind).collect{|m| m.to_s}
199
+ gv = eval("global_variables", bind).collect(&:to_s)
200
+ lv = eval("local_variables", bind).collect(&:to_s)
201
+ cv = eval("self.class.constants", bind).collect(&:to_s)
148
202
 
149
203
  if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
150
204
  # foo.func and foo is local var. OR
151
205
  # Foo::Bar.func
152
206
  begin
153
- candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
207
+ candidates = eval("#{receiver}.methods", bind).collect(&:to_s)
154
208
  rescue RescuableException
155
209
  candidates = []
156
210
  end
@@ -169,35 +223,35 @@ class Pry
169
223
  # jruby doesn't always provide #instance_methods() on each
170
224
  # object.
171
225
  if m.respond_to?(:instance_methods)
172
- candidates.concat m.instance_methods(false).collect{|x| x.to_s}
226
+ candidates.concat m.instance_methods(false).collect(&:to_s)
173
227
  end
174
228
  }
175
229
  candidates.sort!
176
230
  candidates.uniq!
177
231
  end
178
- select_message(receiver, message, candidates)
232
+ select_message(path, receiver, message, candidates)
179
233
 
180
234
  when /^\.([^.]*)$/
181
- # unknown(maybe String)
182
-
235
+ # Unknown(maybe String)
183
236
  receiver = ""
184
237
  message = Regexp.quote($1)
185
238
 
186
- candidates = String.instance_methods(true).collect{|m| m.to_s}
187
- select_message(receiver, message, candidates)
239
+ candidates = String.instance_methods(true).collect(&:to_s)
240
+ select_message(path, receiver, message, candidates)
188
241
 
189
242
  else
243
+
190
244
  candidates = eval(
191
245
  "methods | private_methods | local_variables | " \
192
246
  "self.class.constants | instance_variables",
193
247
  bind
194
- ).collect{|m| m.to_s}
248
+ ).collect(&:to_s)
195
249
 
196
250
  if eval("respond_to?(:class_variables)", bind)
197
- candidates += eval("class_variables", bind).collect { |m| m.to_s }
251
+ candidates += eval("class_variables", bind).collect(&:to_s)
198
252
  end
199
-
200
- (candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
253
+ candidates = (candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
254
+ candidates.collect(&path)
201
255
  end
202
256
  rescue RescuableException
203
257
  []
@@ -205,17 +259,37 @@ class Pry
205
259
  end
206
260
  end
207
261
 
208
- def self.select_message(receiver, message, candidates)
209
- candidates.grep(/^#{message}/).collect do |e|
210
- case e
211
- when /^[a-zA-Z_]/
212
- receiver + "." + e
213
- when /^[0-9]/
214
- when *Operators
215
- #receiver + " " + e
216
- end
262
+ def self.select_message(path, receiver, message, candidates)
263
+ candidates.grep(/^#{message}/).collect { |e|
264
+ case e
265
+ when /^[a-zA-Z_]/
266
+ path.call(receiver + "." + e)
267
+ when /^[0-9]/
268
+ when *Operators
269
+ #receiver + " " + e
270
+ end
271
+ }.compact
272
+ end
273
+
274
+ # build_path seperates the input into two parts: path and input.
275
+ # input is the partial string that should be completed
276
+ # path is a proc that takes an input and builds a full path.
277
+ def self.build_path(input)
278
+
279
+ # check to see if the input is a regex
280
+ return proc {|input| input.to_s }, input if input[/\/\./]
281
+
282
+ trailing_slash = input.end_with?('/')
283
+ contexts = input.chomp('/').split(/\//)
284
+ input = contexts[-1]
285
+
286
+ path = proc do |input|
287
+ p = contexts[0..-2].push(input).join('/')
288
+ p += '/' if trailing_slash && !input.nil?
289
+ p
217
290
  end
291
+
292
+ return path, input
218
293
  end
219
294
  end
220
295
  end
221
-
@@ -112,6 +112,14 @@ class Pry
112
112
  # Pry.config.prompt = proc { |obj, nest_level, _pry_| "#{obj}:#{nest_level}> " }
113
113
  attr_accessor :prompt
114
114
 
115
+ # The display name that is part of the prompt. Default is 'pry'.
116
+ # You can set your own name so you can identify which project your current pry session
117
+ # is using. This is useful if you have a local pryrc file in a Rails project for example.
118
+ # @return [String]
119
+ # @example
120
+ # Pry.config.prompt_name = 'my_rails_project'
121
+ attr_accessor :prompt_name
122
+
115
123
  # The default editor to use. Defaults to $VISUAL, $EDITOR, or a sensible fallback
116
124
  # for the platform.
117
125
  # If `editor` is a String then that string is used as the shell
@@ -228,6 +236,9 @@ class Pry
228
236
  # Pry.config.extra_sticky_locals = { :random_number => proc {
229
237
  # rand(10) } }
230
238
  attr_accessor :extra_sticky_locals
239
+
240
+ # @return [#build_completion_proc] A completer to use.
241
+ attr_accessor :completer
231
242
  end
232
243
  end
233
244
 
@@ -1,3 +1,24 @@
1
+ class Pry
2
+ # @return [Array] Code of the method used when implementing Pry's
3
+ # __binding__, along with line indication to be used with instance_eval (and
4
+ # friends).
5
+ #
6
+ # @see Object#__binding__
7
+ BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1]
8
+ # Get a binding with 'self' set to self, and no locals.
9
+ #
10
+ # The default definee is determined by the context in which the
11
+ # definition is eval'd.
12
+ #
13
+ # Please don't call this method directly, see {__binding__}.
14
+ #
15
+ # @return [Binding]
16
+ def __pry__
17
+ binding
18
+ end
19
+ METHOD
20
+ end
21
+
1
22
  class Object
2
23
  # Start a Pry REPL on self.
3
24
  #
@@ -45,46 +66,36 @@ class Object
45
66
  #
46
67
  # @return [Binding]
47
68
  def __binding__
69
+ # If you ever feel like changing this method, be careful about variables
70
+ # that you use. They shouldn't be inserted into the binding that will
71
+ # eventually be returning.
72
+
48
73
  # When you're cd'd into a class, methods you define should be added to it.
49
74
  if is_a?(Module)
50
75
  # class_eval sets both self and the default definee to this class.
51
76
  return class_eval "binding"
52
77
  end
53
78
 
54
- unless respond_to?(:__binding_impl__)
55
- binding_impl_method = [<<-METHOD, __FILE__, __LINE__ + 1]
56
- # Get a binding with 'self' set to self, and no locals.
57
- #
58
- # The default definee is determined by the context in which the
59
- # definition is eval'd.
60
- #
61
- # Please don't call this method directly, see {__binding__}.
62
- #
63
- # @return [Binding]
64
- def __binding_impl__
65
- binding
66
- end
67
- METHOD
68
-
79
+ unless respond_to?(:__pry__)
69
80
  # The easiest way to check whether an object has a working singleton class
70
81
  # is to try and define a method on it. (just checking for the presence of
71
82
  # the singleton class gives false positives for `true` and `false`).
72
- # __binding_impl__ is just the closest method we have to hand, and using
83
+ # __pry__ is just the closest method we have to hand, and using
73
84
  # it has the nice property that we can memoize this check.
74
85
  begin
75
86
  # instance_eval sets the default definee to the object's singleton class
76
- instance_eval(*binding_impl_method)
87
+ instance_eval *Pry::BINDING_METHOD_IMPL
77
88
 
78
89
  # If we can't define methods on the Object's singleton_class. Then we fall
79
90
  # back to setting the default definee to be the Object's class. That seems
80
91
  # nicer than having a REPL in which you can't define methods.
81
92
  rescue TypeError
82
93
  # class_eval sets the default definee to self.class
83
- self.class.class_eval(*binding_impl_method)
94
+ self.class.class_eval *Pry::BINDING_METHOD_IMPL
84
95
  end
85
96
  end
86
97
 
87
- __binding_impl__
98
+ __pry__
88
99
  end
89
100
  end
90
101
 
@@ -0,0 +1,129 @@
1
+ class Pry
2
+ 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
15
+ end
16
+
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
19
+
20
+ editor_invocation = build_editor_invocation_string(file, line, blocking)
21
+ return nil unless editor_invocation
22
+
23
+ if jruby?
24
+ open_editor_on_jruby(editor_invocation)
25
+ else
26
+ open_editor(editor_invocation)
27
+ end
28
+ end
29
+
30
+ private
31
+
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)
36
+
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
46
+
47
+ "#{Pry.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}"
48
+ end
49
+ end
50
+
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}"
57
+ end
58
+
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
69
+ end
70
+
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
85
+ end
86
+
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
92
+
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
111
+ end
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
125
+ end
126
+
127
+ end
128
+ end
129
+ end