pry 0.9.0pre3-java → 0.9.4pre2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG +84 -6
  3. data/CONTRIBUTORS +13 -0
  4. data/README.markdown +23 -183
  5. data/Rakefile +22 -19
  6. data/TODO +36 -6
  7. data/bin/pry +12 -1
  8. data/lib/pry.rb +60 -12
  9. data/lib/pry/command_context.rb +21 -0
  10. data/lib/pry/command_processor.rb +62 -16
  11. data/lib/pry/command_set.rb +25 -11
  12. data/lib/pry/commands.rb +0 -3
  13. data/lib/pry/completion.rb +6 -6
  14. data/lib/pry/config.rb +25 -5
  15. data/lib/pry/default_commands/basic.rb +27 -6
  16. data/lib/pry/default_commands/context.rb +84 -35
  17. data/lib/pry/default_commands/documentation.rb +69 -31
  18. data/lib/pry/default_commands/easter_eggs.rb +5 -0
  19. data/lib/pry/default_commands/input.rb +193 -56
  20. data/lib/pry/default_commands/introspection.rb +98 -50
  21. data/lib/pry/default_commands/ls.rb +51 -21
  22. data/lib/pry/default_commands/shell.rb +57 -13
  23. data/lib/pry/extended_commands/experimental.rb +0 -32
  24. data/lib/pry/extended_commands/user_command_api.rb +33 -2
  25. data/lib/pry/helpers/base_helpers.rb +30 -10
  26. data/lib/pry/helpers/command_helpers.rb +75 -16
  27. data/lib/pry/helpers/text.rb +12 -11
  28. data/lib/pry/history.rb +61 -0
  29. data/lib/pry/plugins.rb +23 -12
  30. data/lib/pry/pry_class.rb +51 -50
  31. data/lib/pry/pry_instance.rb +129 -119
  32. data/lib/pry/version.rb +1 -1
  33. data/pry.gemspec +46 -0
  34. data/test/helper.rb +37 -3
  35. data/test/test_command_processor.rb +62 -19
  36. data/test/test_command_set.rb +40 -2
  37. data/test/test_completion.rb +27 -0
  38. data/test/test_default_commands/test_context.rb +185 -1
  39. data/test/test_default_commands/test_documentation.rb +10 -0
  40. data/test/test_default_commands/test_input.rb +207 -11
  41. data/test/test_default_commands/test_introspection.rb +20 -1
  42. data/test/test_default_commands/test_shell.rb +18 -0
  43. data/test/test_pry.rb +261 -45
  44. data/test/test_pry_history.rb +82 -0
  45. data/test/test_pry_output.rb +44 -0
  46. data/test/test_special_locals.rb +35 -0
  47. metadata +185 -159
data/lib/pry/commands.rb CHANGED
@@ -22,8 +22,5 @@ class Pry
22
22
  import DefaultCommands::Shell
23
23
  import DefaultCommands::Introspection
24
24
  import DefaultCommands::EasterEggs
25
-
26
- # Helpers::CommandHelpers.try_to_load_pry_doc
27
-
28
25
  end
29
26
  end
@@ -94,7 +94,7 @@ class Pry
94
94
  begin
95
95
  candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
96
96
  candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
97
- rescue Exception
97
+ rescue RescuableException
98
98
  candidates = []
99
99
  end
100
100
  candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
@@ -114,7 +114,7 @@ class Pry
114
114
 
115
115
  begin
116
116
  candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
117
- rescue Exception
117
+ rescue RescuableException
118
118
  candidates = []
119
119
  end
120
120
  select_message(receiver, message, candidates)
@@ -126,7 +126,7 @@ class Pry
126
126
 
127
127
  begin
128
128
  candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
129
- rescue Exception
129
+ rescue RescuableException
130
130
  candidates = []
131
131
  end
132
132
  select_message(receiver, message, candidates)
@@ -149,7 +149,7 @@ class Pry
149
149
  # Foo::Bar.func
150
150
  begin
151
151
  candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
152
- rescue Exception
152
+ rescue RescuableException
153
153
  candidates = []
154
154
  end
155
155
  else
@@ -157,8 +157,8 @@ class Pry
157
157
  candidates = []
158
158
  ObjectSpace.each_object(Module){|m|
159
159
  begin
160
- name = m.name
161
- rescue Exception
160
+ name = m.name.to_s
161
+ rescue RescuableException
162
162
  name = ""
163
163
  end
164
164
  next if name != "IRB::Context" and
data/lib/pry/config.rb CHANGED
@@ -51,12 +51,17 @@ class Pry
51
51
  # return value of that callable invocation is used as the exact
52
52
  # shell command to invoke the editor.
53
53
  # @example String
54
- # Pry.editor = "emacsclient"
54
+ # Pry.config.editor = "emacsclient"
55
55
  # @example Callable
56
- # Pry.editor = proc { |file, line| "emacsclient #{file} +#{line}" }
56
+ # Pry.config.editor = proc { |file, line| "emacsclient #{file} +#{line}" }
57
57
  # @return [String, #call]
58
58
  attr_accessor :editor
59
59
 
60
+ # A string that must precede all Pry commands (e.g., if command_prefix is
61
+ # set to "%", the "cd" command must be invoked as "%cd").
62
+ # @return [String]
63
+ attr_accessor :command_prefix
64
+
60
65
  # @return [Boolean] Toggle Pry color on and off.
61
66
  attr_accessor :color
62
67
 
@@ -71,13 +76,21 @@ class Pry
71
76
  # @return [Boolean]
72
77
  attr_accessor :should_load_plugins
73
78
 
79
+ # Determines whether to load files specified with the -r flag.
80
+ # @return [Boolean]
81
+ attr_accessor :should_load_requires
82
+
83
+ # Determines whether to disable edit-method's auto-reloading behavior.
84
+ # @return [Boolean]
85
+ attr_accessor :disable_auto_reload
86
+
74
87
  # Config option for history.
75
88
  # sub-options include hist.file, hist.load, and hist.save
76
89
  # hist.file is the file to save/load history too, e.g
77
90
  # Pry.config.history.file = "~/.pry_history".
78
- # hist.load is a boolean that determines whether history will be
91
+ # hist.should_load is a boolean that determines whether history will be
79
92
  # loaded from hist.file at session start.
80
- # hist.save is a boolean that determines whether history will be
93
+ # hist.should_save is a boolean that determines whether history will be
81
94
  # saved to hist.file at session end.
82
95
  # @return [OpenStruct]
83
96
  attr_accessor :history
@@ -89,8 +102,15 @@ class Pry
89
102
  # @return [OpenStruct]
90
103
  attr_accessor :plugins
91
104
 
92
- # @return [Integer] Amount of results that will be stored into _out_
105
+ # @return [Array<String>] Ruby files to be required after loading any plugins.
106
+ attr_accessor :requires
107
+
108
+ # @return [Integer] Amount of results that will be stored into out
93
109
  attr_accessor :memory_size
110
+
111
+ # @return [Proc] The proc that manages ^D presses in the REPL.
112
+ # The proc is passed the current eval_string and the current pry instance.
113
+ attr_accessor :control_d_handler
94
114
  end
95
115
  end
96
116
 
@@ -8,23 +8,44 @@ class Pry
8
8
  end
9
9
 
10
10
  command "simple-prompt", "Toggle the simple prompt." do
11
- case Pry.active_instance.prompt
11
+ case _pry_.prompt
12
12
  when Pry::SIMPLE_PROMPT
13
- Pry.active_instance.pop_prompt
13
+ _pry_.pop_prompt
14
14
  else
15
- Pry.active_instance.push_prompt Pry::SIMPLE_PROMPT
15
+ _pry_.push_prompt Pry::SIMPLE_PROMPT
16
16
  end
17
17
  end
18
18
 
19
- command "version", "Show Pry version." do
19
+ command "pry-version", "Show Pry version." do
20
20
  output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
21
21
  end
22
22
 
23
- command "import", "Import a command set" do |command_set_name|
23
+ command "import-set", "Import a command set" do |command_set_name|
24
24
  next output.puts "Provide a command set name" if command_set.nil?
25
25
 
26
26
  set = target.eval(arg_string)
27
- Pry.active_instance.commands.import set
27
+ _pry_.commands.import set
28
+ end
29
+
30
+ command "reload-method", "Reload the source file that contains the specified method" do |meth_name|
31
+ if (meth = get_method_object(meth_name, target, {})).nil?
32
+ output.puts "Invalid method name: #{meth_name}."
33
+ next
34
+ end
35
+
36
+ if is_a_c_method?(meth)
37
+ output.puts "Error: Can't reload a C method."
38
+ elsif is_a_dynamically_defined_method?(meth)
39
+ output.puts "Error: Can't reload an eval method."
40
+ else
41
+ file_name = meth.source_location.first
42
+ load file_name
43
+ output.puts "Reloaded #{file_name}."
44
+ end
45
+ end
46
+
47
+ command "req", "Require file(s) and expand their paths." do |*args|
48
+ args.each { |file_name| load File.expand_path(file_name) }
28
49
  end
29
50
 
30
51
  command "reset", "Reset the REPL to a clean state." do
@@ -6,74 +6,122 @@ class Pry
6
6
  Context = Pry::CommandSet.new do
7
7
  import Ls
8
8
 
9
- command "cd", "Start a Pry session on VAR (use `cd ..` to go back and `cd /` to return to Pry top-level)", :keep_retval => true do |obj|
10
- case obj
11
- when nil
12
- output.puts "Must provide an object."
13
- next
14
- when ".."
15
- throw(:breakout, opts[:nesting].level)
16
- when "/"
17
- throw(:breakout, 1) if opts[:nesting].level > 0
18
- next
19
- when "::"
20
- TOPLEVEL_BINDING.pry
21
- next
9
+ command "cd", "Move into a new context (use `cd ..` to go back and `cd /` to return to Pry top-level). Complex syntax (e.g cd ../@x/y) also supported." do |obj|
10
+ path = arg_string.split(/\//)
11
+ stack = _pry_.binding_stack.dup
12
+
13
+ # special case when we only get a single "/", return to root
14
+ stack = [stack.first] if path.empty?
15
+
16
+ resolve_failure = false
17
+ path.each do |context|
18
+ begin
19
+ case context.chomp
20
+ when ""
21
+ stack = [stack.first]
22
+ when "::"
23
+ stack.push(TOPLEVEL_BINDING)
24
+ when "."
25
+ next
26
+ when ".."
27
+ if stack.one?
28
+ _pry_.binding_stack.clear
29
+ throw(:breakout)
30
+ else
31
+ stack.pop
32
+ end
33
+ else
34
+ stack.push(Pry.binding_for(stack.last.eval(context)))
35
+ end
36
+
37
+ rescue RescuableException
38
+ output.puts "Bad object path: #{arg_string}. Failed trying to resolve: #{context}"
39
+ resolve_failure = true
40
+ end
41
+ end
42
+
43
+ next if resolve_failure
44
+
45
+ _pry_.binding_stack = stack
46
+ end
47
+
48
+ command "switch-to", "Start a new sub-session on a binding in the current stack (numbered by nesting)." do |selection|
49
+ selection = selection.to_i
50
+
51
+ if selection < 0 || selection > _pry_.binding_stack.size - 1
52
+ output.puts "Invalid binding index #{selection} - use `nesting` command to view valid indices."
22
53
  else
23
- Pry.start target.eval(arg_string)
54
+ Pry.start(_pry_.binding_stack[selection])
24
55
  end
25
56
  end
26
57
 
27
58
  command "nesting", "Show nesting information." do
28
- nesting = opts[:nesting]
29
-
30
59
  output.puts "Nesting status:"
31
60
  output.puts "--"
32
- nesting.each do |level, obj|
61
+ _pry_.binding_stack.each_with_index do |obj, level|
33
62
  if level == 0
34
- output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
63
+ output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))} (Pry top level)"
35
64
  else
36
- output.puts "#{level}. #{Pry.view_clip(obj)}"
65
+ output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))}"
37
66
  end
38
67
  end
39
68
  end
40
69
 
41
- command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
70
+ command "jump-to", "Jump to a binding further up the stack, popping all bindings below." do |break_level|
42
71
  break_level = break_level.to_i
43
- nesting = opts[:nesting]
72
+ nesting_level = _pry_.binding_stack.size - 1
44
73
 
45
74
  case break_level
46
- when nesting.level
47
- output.puts "Already at nesting level #{nesting.level}"
48
- when (0...nesting.level)
49
- throw(:breakout, break_level + 1)
75
+ when nesting_level
76
+ output.puts "Already at nesting level #{nesting_level}"
77
+ when (0...nesting_level)
78
+ _pry_.binding_stack.slice!(break_level + 1, _pry_.binding_stack.size)
79
+
50
80
  else
51
- max_nest_level = nesting.level - 1
81
+ max_nest_level = nesting_level - 1
52
82
  output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
53
83
  end
54
84
  end
55
85
 
56
- command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
57
- throw(:breakout, [opts[:nesting].level, target.eval(arg_string)])
86
+ command "exit-all", "End the current Pry session (popping all bindings) and returning to caller. Accepts optional return value. Aliases: !!@" do
87
+ # clear the binding stack
88
+ _pry_.binding_stack.clear
89
+
90
+ # break out of the repl loop
91
+ throw(:breakout, target.eval(arg_string))
58
92
  end
59
93
 
60
- alias_command "quit", "exit", ""
61
- alias_command "back", "exit", ""
94
+ alias_command "!!@", "exit-all", ""
95
+
96
+ command "exit", "Pop the current binding and return to the one immediately prior. Note this does NOT exit the program. Aliases: quit", :keep_retval => true do
97
+ if _pry_.binding_stack.one?
98
+ # when breaking out of top-level then behave like `exit-all`
99
+ _pry_.binding_stack.clear
100
+ throw(:breakout, target.eval(arg_string))
101
+ else
102
+ # otherwise just pop a binding
103
+ popped_object = _pry_.binding_stack.pop.eval('self')
62
104
 
63
- command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !!@" do
64
- throw(:breakout, [0, target.eval(arg_string)])
105
+ # return a user-specified value if given
106
+ if !arg_string.empty?
107
+ target.eval(arg_string)
108
+ else
109
+ popped_object
110
+ end
111
+ end
65
112
  end
66
113
 
67
- alias_command "!!@", "exit-all", ""
114
+ alias_command "quit", "exit", ""
68
115
 
69
116
  command "exit-program", "End the current program. Aliases: quit-program, !!!" do
70
- exit
117
+ Pry.save_history if Pry.config.history.should_save
118
+ Kernel.exit target.eval(arg_string).to_i
71
119
  end
72
120
 
73
121
  alias_command "quit-program", "exit-program", ""
74
122
  alias_command "!!!", "exit-program", ""
75
123
 
76
- command "!pry", "Start a Pry session on current self; this even works mid-expression." do
124
+ command "!pry", "Start a Pry session on current self; this even works mid multi-line expression." do
77
125
  target.pry
78
126
  end
79
127
 
@@ -99,6 +147,7 @@ class Pry
99
147
  set_file_and_dir_locals(file)
100
148
  output.puts "\n#{text.bold('From:')} #{file} @ line #{line_num} in #{klass}##{meth_name}:\n\n"
101
149
 
150
+
102
151
  # This method inspired by http://rubygems.org/gems/ir_b
103
152
  File.open(file).each_with_index do |line, index|
104
153
  line_n = index + 1
@@ -11,7 +11,7 @@ class Pry
11
11
  target = target()
12
12
 
13
13
  opts = Slop.parse!(args) do |opt|
14
- opt.banner = "Usage: show-doc [OPTIONS] [METH]\n" \
14
+ opt.banner = "Usage: show-doc [OPTIONS] [METH 1] [METH 2] [METH N]\n" \
15
15
  "Show the comments above method METH. Tries instance methods first and then methods by default.\n" \
16
16
  "e.g show-doc hello_method"
17
17
 
@@ -28,25 +28,30 @@ class Pry
28
28
 
29
29
  next if opts.help?
30
30
 
31
- meth_name = args.shift
32
- if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
33
- output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
34
- next
35
- end
36
-
37
- doc, code_type = doc_and_code_type_for(meth)
38
- next if !doc
31
+ args = [nil] if args.empty?
32
+ args.each do |method_name|
33
+ meth_name = method_name
34
+ if (meth = get_method_object(meth_name, target, opts.to_hash(true))).nil?
35
+ output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
36
+ next
37
+ end
39
38
 
40
- next output.puts("No documentation found.") if doc.empty?
41
- doc = process_comment_markup(doc, code_type)
42
- output.puts make_header(meth, code_type, doc)
43
- render_output(opts.flood?, false, doc)
44
- doc
39
+ doc, code_type = doc_and_code_type_for(meth)
40
+ next if !doc
41
+
42
+ next output.puts("No documentation found.") if doc.empty?
43
+ doc = process_comment_markup(doc, code_type)
44
+ output.puts make_header(meth, code_type, doc)
45
+ output.puts "#{text.bold("visibility: ")} #{method_visibility(meth).to_s}"
46
+ output.puts "#{text.bold("signature: ")} #{signature_for(meth)}"
47
+ output.puts
48
+ render_output(opts.flood?, false, doc)
49
+ doc
50
+ end
45
51
  end
46
52
 
47
53
  alias_command "?", "show-doc", ""
48
54
 
49
-
50
55
  command "stat", "View method information and set _file_ and _dir_ locals. Type `stat --help` for more info." do |*args|
51
56
  target = target()
52
57
 
@@ -73,23 +78,20 @@ class Pry
73
78
  next
74
79
  end
75
80
 
76
- code, code_type = code_and_code_type_for(meth)
77
- next if !code
78
- doc, code_type = doc_and_code_type_for(meth)
79
-
80
- output.puts make_header(meth, code_type, code)
81
- output.puts text.bold("Method Name: ") + meth_name
82
- output.puts text.bold("Method Owner: ") + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
83
- output.puts text.bold("Method Language: ") + code_type.to_s.capitalize
84
- output.puts text.bold("Method Type: ") + (meth.is_a?(Method) ? "Bound" : "Unbound")
85
- output.puts text.bold("Method Arity: ") + meth.arity.to_s
86
-
87
- name_map = { :req => "Required:", :opt => "Optional:", :rest => "Rest:" }
88
- if meth.respond_to?(:parameters)
89
- output.puts text.bold("Method Parameters: ") + meth.parameters.group_by(&:first).
90
- map { |k, v| "#{name_map[k]} #{v.map { |kk, vv| vv ? vv.to_s : "noname" }.join(", ")}" }.join(". ")
81
+ if !is_a_c_method?(meth) && !is_a_dynamically_defined_method?(meth)
82
+ set_file_and_dir_locals(path_line_for(meth).first)
91
83
  end
92
- output.puts text.bold("Comment length: ") + (doc.empty? ? 'No comment.' : (doc.lines.count.to_s + ' lines.'))
84
+
85
+ output.puts "Method Information:"
86
+ output.puts "--"
87
+ output.puts "Name: " + meth_name
88
+ output.puts "Owner: " + (meth.owner.to_s ? meth.owner.to_s : "Unknown")
89
+ output.puts "Visibility: " + method_visibility(meth).to_s
90
+ output.puts "Type: " + (meth.is_a?(Method) ? "Bound" : "Unbound")
91
+ output.puts "Arity: " + meth.arity.to_s
92
+ output.puts "Method Signature: " + signature_for(meth)
93
+
94
+ output.puts "Source location: " + (meth.source_location ? meth.source_location.join(":") : "Not found.")
93
95
  end
94
96
 
95
97
  command "gist-method", "Gist a method to github. Type `gist-method --help` for more info.", :requires_gem => "gist" do |*args|
@@ -140,6 +142,42 @@ class Pry
140
142
  output.puts "Gist created at #{link}"
141
143
  end
142
144
 
145
+ helpers do
146
+
147
+ # paraphrased from awesome_print gem
148
+ def signature_for(method)
149
+ if method.respond_to?(:parameters)
150
+
151
+ args = method.parameters.inject([]) do |arr, (type, name)|
152
+ name ||= (type == :block ? 'block' : "arg#{arr.size + 1}")
153
+ arr << case type
154
+ when :req then name.to_s
155
+ when :opt, :rest then "*#{name}"
156
+ when :block then "&#{name}"
157
+ else '?'
158
+ end
159
+ end
160
+ else
161
+ args = (1..method.arity.abs).map { |i| "arg#{i}" }
162
+ args[-1] = "*#{args[-1]}" if method.arity < 0
163
+ end
164
+
165
+ "#{method.name}(#{args.join(', ')})"
166
+ end
167
+
168
+ def method_visibility(meth)
169
+ if meth.owner.public_instance_methods.include? meth.name
170
+ :public
171
+ elsif meth.owner.protected_instance_methods.include? meth.name
172
+ :protected
173
+ elsif meth.owner.private_instance_methods.include? meth.name
174
+ :private
175
+ else
176
+ :none
177
+ end
178
+ end
179
+ end
180
+
143
181
  end
144
182
 
145
183
  end