pry 0.3.0 → 0.4.0pre1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pry.rb CHANGED
@@ -4,254 +4,17 @@
4
4
  direc = File.dirname(__FILE__)
5
5
 
6
6
  require "method_source"
7
+ require "readline"
7
8
  require "#{direc}/pry/version"
8
- require "#{direc}/pry/input"
9
- require "#{direc}/pry/output"
9
+ require "#{direc}/pry/hooks"
10
+ require "#{direc}/pry/print"
11
+ require "#{direc}/pry/command_base"
12
+ require "#{direc}/pry/commands"
13
+ require "#{direc}/pry/prompts"
14
+ require "#{direc}/pry/completion"
15
+ require "#{direc}/pry/core_extensions"
16
+ require "#{direc}/pry/pry_class"
17
+ require "#{direc}/pry/pry_instance"
10
18
 
11
- class Pry
12
- def self.start(target=TOPLEVEL_BINDING)
13
- new.repl(target)
14
- end
15
19
 
16
- def self.view(obj)
17
- case obj
18
- when String, Array, Hash, Symbol, nil
19
- obj.inspect
20
- else
21
- obj.to_s
22
- end
23
- end
24
20
 
25
- # class accessors
26
- class << self
27
- attr_reader :nesting
28
- attr_accessor :last_result
29
- attr_accessor :default_prompt, :wait_prompt
30
- end
31
-
32
- self.default_prompt = proc do |v, nest|
33
- if nest == 0
34
- "pry(#{Pry.view(v)})> "
35
- else
36
- "pry(#{Pry.view(v)}):#{Pry.view(nest)}> "
37
- end
38
- end
39
-
40
- self.wait_prompt = proc do |v, nest|
41
- if nest == 0
42
- "pry(#{Pry.view(v)})* "
43
- else
44
- "pry(#{Pry.view(v)}):#{Pry.view(nest)}* "
45
- end
46
- end
47
-
48
- attr_accessor :input, :output
49
- attr_accessor :default_prompt, :wait_prompt
50
- attr_reader :last_result
51
-
52
- def initialize(input = Input.new, output = Output.new)
53
- @input = input
54
- @output = output
55
-
56
- @default_prompt = Pry.default_prompt
57
- @wait_prompt = Pry.wait_prompt
58
- end
59
-
60
- @nesting = []
61
-
62
- def @nesting.level
63
- last.is_a?(Array) ? last.first : nil
64
- end
65
-
66
- def nesting
67
- self.class.nesting
68
- end
69
-
70
- def nesting=(v)
71
- self.class.nesting = v
72
- end
73
-
74
- # loop
75
- def repl(target=TOPLEVEL_BINDING)
76
- target = binding_for(target)
77
- target_self = target.eval('self')
78
- output.session_start(target_self)
79
-
80
- nesting_level = nesting.size
81
-
82
- # Make sure _ exists
83
- target.eval("_ = Pry.last_result")
84
-
85
- break_level = catch(:breakout) do
86
- nesting << [nesting.size, target_self]
87
- loop do
88
- rep(target)
89
- end
90
- end
91
-
92
- nesting.pop
93
- output.session_end(target_self)
94
-
95
- # we only enter here if :breakout has been thrown
96
- if nesting_level != break_level
97
- throw :breakout, break_level
98
- end
99
-
100
- target_self
101
- end
102
-
103
- # print
104
- def rep(target=TOPLEVEL_BINDING)
105
- target = binding_for(target)
106
- output.print re(target)
107
- end
108
-
109
- # eval
110
- def re(target=TOPLEVEL_BINDING)
111
- target = binding_for(target)
112
- Pry.last_result = target.eval r(target)
113
- target.eval("_ = Pry.last_result")
114
- rescue SystemExit => e
115
- exit
116
- rescue Exception => e
117
- e
118
- end
119
-
120
- # read
121
- def r(target=TOPLEVEL_BINDING)
122
- target = binding_for(target)
123
- eval_string = ""
124
- loop do
125
- val = input.read(prompt(eval_string, target, nesting.level))
126
- eval_string += "#{val.chomp}\n"
127
- process_commands(val, eval_string, target)
128
-
129
- break eval_string if valid_expression?(eval_string)
130
- end
131
- end
132
-
133
- def process_commands(val, eval_string, target)
134
- def eval_string.clear() replace("") end
135
-
136
- case val
137
- when "exit_program", "quit_program"
138
- output.exit_program
139
- exit
140
- when "!"
141
- output.refresh
142
- eval_string.clear
143
- when "help"
144
- output.show_help
145
- eval_string.clear
146
- when "nesting"
147
- output.show_nesting(nesting)
148
- eval_string.clear
149
- when "status"
150
- output.show_status(nesting, target)
151
- eval_string.clear
152
- when "exit_all"
153
- throw(:breakout, 0)
154
- when "exit", "quit", "back", /^cd\s*\.\./
155
- output.exit
156
- throw(:breakout, nesting.level)
157
- when "ls"
158
- output.ls(target)
159
- eval_string.clear
160
- when /^cat\s+(.+)/
161
- var = $~.captures.first
162
- output.cat(target, var)
163
- eval_string.clear
164
- when /^cd\s+(.+)/
165
- obj = $~.captures.first
166
- target.eval("#{obj}.pry")
167
- eval_string.clear
168
- when /^show_doc\s*(.+)/
169
- meth_name = ($~.captures).first
170
- doc = target.eval("method(:#{meth_name})").comment
171
- output.show_doc doc
172
- eval_string.clear
173
- when /^show_idoc\s*(.+)/
174
- meth_name = ($~.captures).first
175
- doc = target.eval("instance_method(:#{meth_name})").comment
176
- output.show_doc doc
177
- eval_string.clear
178
- when /^show_method\s*(.+)/
179
- meth_name = ($~.captures).first
180
- code = target.eval("method(:#{meth_name})").source
181
- output.show_method code
182
- eval_string.clear
183
- when /^show_instance_method\s*(.+)/, /^show_imethod\s*(.+)/
184
- meth_name = ($~.captures).first
185
- code = target.eval("instance_method(:#{meth_name})").source
186
- output.show_method code
187
- eval_string.clear
188
- when /^jump_to\s*(\d*)/
189
- break_level = ($~.captures).first.to_i
190
- output.jump_to(break_level)
191
-
192
- case break_level
193
- when nesting.level
194
- output.warn_already_at_level(nesting.level)
195
- eval_string.clear
196
- when (0...nesting.level)
197
- throw(:breakout, break_level + 1)
198
- else
199
- output.err_invalid_nest_level(break_level,
200
- nesting.level - 1)
201
- eval_string.clear
202
- end
203
- end
204
- end
205
-
206
- def prompt(eval_string, target, nest)
207
- target_self = target.eval('self')
208
-
209
- if eval_string.empty?
210
- default_prompt.call(target_self, nest)
211
- else
212
- wait_prompt.call(target_self, nest)
213
- end
214
- end
215
-
216
- if RUBY_VERSION =~ /1.9/
217
- require 'ripper'
218
-
219
- def valid_expression?(code)
220
- !!Ripper::SexpBuilder.new(code).parse
221
- end
222
-
223
- else
224
- require 'ruby_parser'
225
-
226
- def valid_expression?(code)
227
- RubyParser.new.parse(code)
228
- rescue Racc::ParseError, SyntaxError
229
- false
230
- else
231
- true
232
- end
233
-
234
- end
235
-
236
- def binding_for(target)
237
- if target.is_a?(Binding)
238
- target
239
- else
240
- if target == TOPLEVEL_BINDING.eval('self')
241
- TOPLEVEL_BINDING
242
- else
243
- target.instance_eval { binding }
244
- end
245
- end
246
- end
247
-
248
- module ObjectExtensions
249
- def pry(target=self)
250
- Pry.start(target)
251
- end
252
- end
253
- end
254
-
255
- class Object
256
- include Pry::ObjectExtensions
257
- end
@@ -0,0 +1,114 @@
1
+ class Pry
2
+
3
+ # Basic command functionality. All user-defined commands must
4
+ # inherit from this class. It provides the `command` method.
5
+ class CommandBase
6
+ class << self
7
+ attr_accessor :commands
8
+ attr_accessor :command_info
9
+ attr_accessor :opts, :output, :target
10
+
11
+ # private because we want to force function style invocation. We require
12
+ # that the location where the block is defined has the `opts`
13
+ # method in scope.
14
+ private
15
+
16
+ # Defines a new Pry command.
17
+ # @param [String, Array] names The name of the command (or array of
18
+ # command name aliases).
19
+ # @param [String] description A description of the command.
20
+ # @yield The action to perform. The parameters in the block
21
+ # determines the parameters the command will receive. All
22
+ # parameters passed into the block will be strings. Successive
23
+ # command parameters are separated by whitespace at the Pry prompt.
24
+ # @example
25
+ # class MyCommands < Pry::CommandBase
26
+ # command "greet", "Greet somebody" do |name|
27
+ # puts "Good afternoon #{name.capitalize}!"
28
+ # end
29
+ # end
30
+ #
31
+ # # From pry:
32
+ # # pry(main)> _pry_.commands = MyCommands
33
+ # # pry(main)> greet john
34
+ # # Good afternoon John!
35
+ # # pry(main)> help greet
36
+ # # Greet somebody
37
+ def command(names, description="No description.", &block)
38
+ @commands ||= {}
39
+
40
+ Array(names).each do |name|
41
+ commands[name] = { :description => description, :action => block }
42
+ end
43
+ end
44
+
45
+ # Delete a command or an array of commands.
46
+ # Useful when inheriting from another command set and pruning
47
+ # those commands down to the ones you want.
48
+ # @param [Array<String>] names The command name or array
49
+ # of command names you want to delete
50
+ # @example Deleteing inherited commands
51
+ # class MyCommands < Pry::Commands
52
+ # delete "show_method", "show_imethod", "show_doc", "show_idoc"
53
+ # end
54
+ # Pry.commands = MyCommands
55
+ def delete(*names)
56
+ names.each { |name| commands.delete(name) }
57
+ end
58
+
59
+ # Execute a command (this enables commands to call other commands).
60
+ # @param [String] name The command to execute
61
+ # @param [Array] args The parameters to pass to the command.
62
+ # @example Wrap one command with another
63
+ # class MyCommands < Pry::Commands
64
+ # command "ls2" do
65
+ # output.puts "before ls"
66
+ # run "ls"
67
+ # output.puts "after ls"
68
+ # end
69
+ # end
70
+ def run(name, *args)
71
+ action = opts[:commands][name][:action]
72
+ instance_exec(*args, &action)
73
+ end
74
+
75
+ # Import commands from another command object.
76
+ # @param [Pry::CommandBase] klass The class to import from (must
77
+ # be a subclass of `Pry::CommandBase`)
78
+ # @param [Array<String>] names The commands to import.
79
+ # @example
80
+ # class MyCommands < Pry::CommandBase
81
+ # import_from Pry::Commands, "ls", "show_method", "cd"
82
+ # end
83
+ def import_from(klass, *names)
84
+ imported_hash = Hash[klass.commands.select { |k, v| names.include?(k) }]
85
+ commands.merge!(imported_hash)
86
+ end
87
+ end
88
+
89
+ command "help", "This menu." do |cmd|
90
+ command_info = opts[:commands]
91
+ param = cmd
92
+
93
+ if !param
94
+ output.puts "Command list:"
95
+ output.puts "--"
96
+ command_info.each do |k, data|
97
+ output.puts "#{k}".ljust(18) + data[:description] if !data[:description].empty?
98
+ end
99
+ else
100
+ if command_info[param]
101
+ output.puts command_info[param][:description]
102
+ else
103
+ output.puts "No info for command: #{param}"
104
+ end
105
+ end
106
+ end
107
+
108
+ # Ensures that commands can be inherited
109
+ def self.inherited(klass)
110
+ klass.commands = commands.dup
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,115 @@
1
+ direc = File.dirname(__FILE__)
2
+ require "#{direc}/command_base"
3
+
4
+ class Pry
5
+
6
+ # Default commands used by Pry.
7
+ class Commands < CommandBase
8
+
9
+ command "!", "Refresh the REPL" do
10
+ output.puts "Refreshed REPL"
11
+ opts[:eval_string].clear
12
+ end
13
+
14
+ command "!pry", "Start a Pry session on current self; this even works mid-expression." do
15
+ Pry.start(target)
16
+ end
17
+
18
+ command ["exit_program", "quit_program"], "End the current program." do
19
+ exit
20
+ end
21
+
22
+ command "nesting", "Show nesting information." do
23
+ out = output
24
+ nesting = opts[:nesting]
25
+
26
+ out.puts "Nesting status:"
27
+ out.puts "--"
28
+ nesting.each do |level, obj|
29
+ if level == 0
30
+ out.puts "#{level}. #{Pry.view(obj)} (Pry top level)"
31
+ else
32
+ out.puts "#{level}. #{Pry.view(obj)}"
33
+ end
34
+ end
35
+ end
36
+
37
+ command "status", "Show status information." do
38
+ out = output
39
+ nesting = opts[:nesting]
40
+
41
+ out.puts "Status:"
42
+ out.puts "--"
43
+ out.puts "Receiver: #{Pry.view(target.eval('self'))}"
44
+ out.puts "Nesting level: #{nesting.level}"
45
+ out.puts "Local variables: #{Pry.view(target.eval('local_variables'))}"
46
+ out.puts "Pry instance: #{Pry.active_instance}"
47
+ out.puts "Last result: #{Pry.view(Pry.last_result)}"
48
+ end
49
+
50
+ command "exit_all", "End all nested Pry sessions." do
51
+ throw(:breakout, 0)
52
+ end
53
+
54
+ command "ls", "Show the list of vars in the current scope." do
55
+ output.puts "#{Pry.view(target.eval('local_variables + instance_variables'))}"
56
+ end
57
+
58
+ command "cat", "Show output of <var>.inspect." do |obj|
59
+ out = output
60
+ out.puts target.eval("#{obj}.inspect")
61
+ end
62
+
63
+ command "cd", "Start a Pry session on <var> (use `cd ..` to go back)" do |obj|
64
+ throw(:breakout, opts[:nesting].level) if obj == ".."
65
+ target.eval("#{obj}.pry")
66
+ end
67
+
68
+ command "show_doc", "Show the comments above <methname>" do |meth_name|
69
+ doc = target.eval("method(:#{meth_name})").comment
70
+ output.puts doc
71
+ end
72
+
73
+ command "show_idoc", "Show the comments above instance method <methname>" do |meth_name|
74
+ doc = target.eval("instance_method(:#{meth_name})").comment
75
+ output.puts doc
76
+ end
77
+
78
+ command "show_method", "Show sourcecode for method <methname>." do |meth_name|
79
+ doc = target.eval("method(:#{meth_name})").source
80
+ output.puts doc
81
+ end
82
+
83
+ command "show_imethod", "Show sourcecode for instance method <methname>." do |meth_name|
84
+ doc = target.eval("instance_method(:#{meth_name})").source
85
+ output.puts doc
86
+ end
87
+
88
+ command "jump_to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
89
+ break_level = break_level.to_i
90
+ nesting = opts[:nesting]
91
+
92
+ case break_level
93
+ when nesting.level
94
+ output.puts "Already at nesting level #{nesting.level}"
95
+ when (0...nesting.level)
96
+ throw(:breakout, break_level + 1)
97
+ else
98
+ max_nest_level = nesting.level - 1
99
+ output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
100
+ end
101
+ end
102
+
103
+ command "ls_methods", "List all methods defined on class of receiver." do
104
+ output.puts "#{Pry.view(target.eval('public_methods(false) + private_methods(false) + protected_methods(false)'))}"
105
+ end
106
+
107
+ command "ls_imethods", "List all instance methods defined on class of receiver." do
108
+ output.puts "#{Pry.view(target.eval('public_instance_methods(false) + private_instance_methods(false) + protected_instance_methods(false)'))}"
109
+ end
110
+
111
+ command ["exit", "quit", "back"], "End the current Pry session." do
112
+ throw(:breakout, opts[:nesting].level)
113
+ end
114
+ end
115
+ end