pry 0.7.7.2-i386-mingw32 → 0.8.0-i386-mingw32

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.
@@ -0,0 +1,303 @@
1
+ class Pry
2
+ class Commands < CommandBase
3
+ module CommandHelpers
4
+
5
+ private
6
+
7
+ def try_to_load_pry_doc
8
+
9
+ # YARD crashes on rbx, so do not require it
10
+ if !Object.const_defined?(:RUBY_ENGINE) || RUBY_ENGINE !~ /rbx/
11
+ require "pry-doc"
12
+ end
13
+ rescue LoadError
14
+ end
15
+
16
+ def meth_name_from_binding(b)
17
+ meth_name = b.eval('__method__')
18
+ if [:__script__, nil, :__binding__, :__binding_impl__].include?(meth_name)
19
+ nil
20
+ else
21
+ meth_name
22
+ end
23
+ end
24
+
25
+ def set_file_and_dir_locals(file_name)
26
+ return if !target
27
+ $_file_temp = File.expand_path(file_name)
28
+ $_dir_temp = File.dirname($_file_temp)
29
+ target.eval("_file_ = $_file_temp")
30
+ target.eval("_dir_ = $_dir_temp")
31
+ end
32
+
33
+ def add_line_numbers(lines, start_line)
34
+ line_array = lines.each_line.to_a
35
+ line_array.each_with_index.map do |line, idx|
36
+ adjusted_index = idx + start_line
37
+ if Pry.color
38
+ cindex = CodeRay.scan("#{adjusted_index}", :ruby).term
39
+ "#{cindex}: #{line}"
40
+ else
41
+ "#{idx}: #{line}"
42
+ end
43
+ end.join
44
+ end
45
+
46
+ # if start_line is not false then add line numbers starting with start_line
47
+ def render_output(should_flood, start_line, doc)
48
+ if start_line
49
+ doc = add_line_numbers(doc, start_line)
50
+ end
51
+
52
+ if should_flood
53
+ output.puts doc
54
+ else
55
+ stagger_output(doc)
56
+ end
57
+ end
58
+
59
+ def check_for_dynamically_defined_method(meth)
60
+ file, _ = meth.source_location
61
+ if file =~ /(\(.*\))|<.*>/
62
+ raise "Cannot retrieve source for dynamically defined method."
63
+ end
64
+ end
65
+
66
+ def remove_first_word(text)
67
+ text.split.drop(1).join(' ')
68
+ end
69
+
70
+ # turn off color for duration of block
71
+ def no_color(&block)
72
+ old_color_state = Pry.color
73
+ Pry.color = false
74
+ yield
75
+ ensure
76
+ Pry.color = old_color_state
77
+ end
78
+
79
+ def code_and_code_type_for(meth)
80
+ case code_type = code_type_for(meth)
81
+ when nil
82
+ return nil
83
+ when :c
84
+ code = Pry::MethodInfo.info_for(meth).source
85
+ code = strip_comments_from_c_code(code)
86
+ when :ruby
87
+ code = strip_leading_whitespace(meth.source)
88
+ set_file_and_dir_locals(meth.source_location.first)
89
+ end
90
+
91
+ [code, code_type]
92
+ end
93
+
94
+ def doc_and_code_type_for(meth)
95
+ case code_type = code_type_for(meth)
96
+ when nil
97
+ return nil
98
+ when :c
99
+ doc = Pry::MethodInfo.info_for(meth).docstring
100
+ when :ruby
101
+ doc = meth.comment
102
+ doc = strip_leading_hash_and_whitespace_from_ruby_comments(doc)
103
+ set_file_and_dir_locals(meth.source_location.first)
104
+ end
105
+
106
+ [doc, code_type]
107
+ end
108
+
109
+ def get_method_object(meth_name, target, options)
110
+ if !meth_name
111
+ return nil
112
+ end
113
+
114
+ if options[:M]
115
+ target.eval("instance_method(:#{meth_name})")
116
+ elsif options[:m]
117
+ target.eval("method(:#{meth_name})")
118
+ else
119
+ begin
120
+ target.eval("instance_method(:#{meth_name})")
121
+ rescue
122
+ begin
123
+ target.eval("method(:#{meth_name})")
124
+ rescue
125
+ return nil
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ def make_header(meth, code_type, content)
132
+ num_lines = "Number of lines: #{bold(content.each_line.count.to_s)}"
133
+ case code_type
134
+ when :ruby
135
+ file, line = meth.source_location
136
+ "\n#{bold('From:')} #{file} @ line #{line}:\n#{num_lines}\n\n"
137
+ else
138
+ file = Pry::MethodInfo.info_for(meth).file
139
+ "\n#{bold('From:')} #{file} in Ruby Core (C Method):\n#{num_lines}\n\n"
140
+ end
141
+ end
142
+
143
+ def is_a_c_method?(meth)
144
+ meth.source_location.nil?
145
+ end
146
+
147
+ def should_use_pry_doc?(meth)
148
+ Pry.has_pry_doc && is_a_c_method?(meth)
149
+ end
150
+
151
+ def code_type_for(meth)
152
+ # only C methods
153
+ if should_use_pry_doc?(meth)
154
+ info = Pry::MethodInfo.info_for(meth)
155
+ if info && info.source
156
+ code_type = :c
157
+ else
158
+ output.puts "Cannot find C method: #{meth.name}"
159
+ code_type = nil
160
+ end
161
+ else
162
+ if is_a_c_method?(meth)
163
+ output.puts "Cannot locate this method: #{meth.name}. Try `gem install pry-doc` to get access to Ruby Core documentation."
164
+ code_type = nil
165
+ else
166
+ check_for_dynamically_defined_method(meth)
167
+ code_type = :ruby
168
+ end
169
+ end
170
+ code_type
171
+ end
172
+
173
+ def file_map
174
+ {
175
+ [".c", ".h"] => :c,
176
+ [".cpp", ".hpp", ".cc", ".h", "cxx"] => :cpp,
177
+ [".rb", "Rakefile", ".irbrc", ".gemspec", ".pryrc"] => :ruby,
178
+ ".py" => :python,
179
+ ".diff" => :diff,
180
+ ".css" => :css,
181
+ ".html" => :html,
182
+ [".yaml", ".yml"] => :yaml,
183
+ ".xml" => :xml,
184
+ ".php" => :php,
185
+ ".js" => :javascript,
186
+ ".java" => :java,
187
+ ".rhtml" => :rhtml,
188
+ ".json" => :json
189
+ }
190
+ end
191
+
192
+ def syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
193
+ _, language_detected = file_map.find do |k, v|
194
+ Array(k).any? do |matcher|
195
+ matcher == File.extname(file_name) || matcher == File.basename(file_name)
196
+ end
197
+ end
198
+
199
+ language_detected = file_type if file_type
200
+ CodeRay.scan(contents, language_detected).term
201
+ end
202
+
203
+ # convert negative line numbers to positive by wrapping around
204
+ # last line (as per array indexing with negative numbers)
205
+ def normalized_line_number(line_number, total_lines)
206
+ line_number < 0 ? line_number + total_lines : line_number
207
+ end
208
+
209
+ # returns the file content between the lines and the normalized
210
+ # start and end line numbers.
211
+ def read_between_the_lines(file_name, start_line, end_line)
212
+ content = File.read(File.expand_path(file_name))
213
+ lines_array = content.each_line.to_a
214
+
215
+ [lines_array[start_line..end_line].join, normalized_line_number(start_line, lines_array.size),
216
+ normalized_line_number(end_line, lines_array.size)]
217
+ end
218
+
219
+ # documentation related helpers
220
+ def strip_color_codes(str)
221
+ str.gsub(/\e\[.*?(\d)+m/, '')
222
+ end
223
+
224
+ def process_rdoc(comment, code_type)
225
+ comment = comment.dup
226
+ comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
227
+ gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
228
+ gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[34m#{$1}\e[0m" : $1 }.
229
+ gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
230
+ gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
231
+ gsub(/`(?:\s*\n)?(.*?)\s*`/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }
232
+ end
233
+
234
+ def process_yardoc_tag(comment, tag)
235
+ in_tag_block = nil
236
+ output = comment.lines.map do |v|
237
+ if in_tag_block && v !~ /^\S/
238
+ strip_color_codes(strip_color_codes(v))
239
+ elsif in_tag_block
240
+ in_tag_block = false
241
+ v
242
+ else
243
+ in_tag_block = true if v =~ /^@#{tag}/
244
+ v
245
+ end
246
+ end.join
247
+ end
248
+
249
+ def process_yardoc(comment)
250
+ yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer",
251
+ "deprecate", "example"]
252
+ (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }.
253
+ gsub(/^@(#{yard_tags.join("|")})/) { Pry.color ? "\e[33m#{$1}\e[0m": $1 }
254
+ end
255
+
256
+ def process_comment_markup(comment, code_type)
257
+ process_yardoc process_rdoc(comment, code_type)
258
+ end
259
+
260
+ # strip leading whitespace but preserve indentation
261
+ def strip_leading_whitespace(text)
262
+ return text if text.empty?
263
+ leading_spaces = text.lines.first[/^(\s+)/, 1]
264
+ text.gsub(/^#{leading_spaces}/, '')
265
+ end
266
+
267
+ def strip_leading_hash_and_whitespace_from_ruby_comments(comment)
268
+ comment = comment.dup
269
+ comment.gsub!(/\A\#+?$/, '')
270
+ comment.gsub!(/^\s*#/, '')
271
+ strip_leading_whitespace(comment)
272
+ end
273
+
274
+ def strip_comments_from_c_code(code)
275
+ code.sub /\A\s*\/\*.*?\*\/\s*/m, ''
276
+ end
277
+
278
+ def prompt(message, options="Yn")
279
+ opts = options.scan(/./)
280
+ optstring = opts.join("/") # case maintained
281
+ defaults = opts.select{|o| o.upcase == o }
282
+ opts = opts.map{|o| o.downcase}
283
+
284
+ raise "Error: Too many default values for the prompt: #{default.inspect}" if defaults.size > 1
285
+
286
+ default = defaults.first
287
+
288
+ loop do
289
+ response = Pry.input.readline("#{message} (#{optstring}) ").downcase
290
+ case response
291
+ when *opts
292
+ return response
293
+ when ""
294
+ return default.downcase
295
+ else
296
+ output.puts " |_ Invalid option: #{response.inspect}. Try again."
297
+ end
298
+ end
299
+ end
300
+
301
+ end
302
+ end
303
+ end
@@ -0,0 +1,174 @@
1
+ require 'forwardable'
2
+
3
+ class Pry
4
+ class CommandProcessor
5
+ SYSTEM_COMMAND_DELIMITER = "."
6
+ SYSTEM_COMMAND_REGEX = /^#{Regexp.escape(SYSTEM_COMMAND_DELIMITER)}(.*)/
7
+
8
+ extend Forwardable
9
+
10
+ attr_accessor :pry_instance
11
+
12
+ def initialize(pry_instance)
13
+ @pry_instance = pry_instance
14
+ end
15
+
16
+ def_delegators :@pry_instance, :commands, :nesting, :output
17
+
18
+ # Is the string a command valid?
19
+ # @param [String] val The string passed in from the Pry prompt.
20
+ # @return [Boolean] Whether the string is a valid command.
21
+ def valid_command?(val)
22
+ system_command?(val) || pry_command?(val)
23
+ end
24
+
25
+ # Is the string a valid system command?
26
+ # @param [String] val The string passed in from the Pry prompt.
27
+ # @return [Boolean] Whether the string is a valid system command.
28
+ def system_command?(val)
29
+ !!(SYSTEM_COMMAND_REGEX =~ val)
30
+ end
31
+
32
+ # Is the string a valid pry command?
33
+ # A Pry command is a command that is not a system command.
34
+ # @param [String] val The string passed in from the Pry prompt.
35
+ # @return [Boolean] Whether the string is a valid Pry command.
36
+ def pry_command?(val)
37
+ !!command_matched(val).first
38
+ end
39
+
40
+ # Revaluate the string (str) and perform interpolation.
41
+ # @param [String] str The string to reevaluate with interpolation.
42
+ # @param [Binding] target The context where the string should be
43
+ # reevaluated in.
44
+ # @return [String] The reevaluated string with interpolations
45
+ # applied (if any).
46
+ def interpolate_string(str, target)
47
+ dumped_str = str.dump
48
+ dumped_str.gsub!(/\\\#\{/, '#{')
49
+ target.eval(dumped_str)
50
+ end
51
+
52
+ # Execute a given system command.
53
+ # The commands first have interpolation applied against the
54
+ # `target` context.
55
+ # All system command are forwarded to a shell. Note that the `cd`
56
+ # command is special-cased and is converted internallly to a `Dir.chdir`
57
+ # @param [String] val The system command to execute.
58
+ # @param [Binding] target The context in which to perform string interpolation.
59
+ def execute_system_command(val, target)
60
+ SYSTEM_COMMAND_REGEX =~ val
61
+ cmd = interpolate_string($1, target)
62
+
63
+ if cmd =~ /^cd\s+(.+)/i
64
+ begin
65
+ @@cd_history ||= []
66
+ if $1 == "-"
67
+ dest = @@cd_history.pop || Dir.pwd
68
+ else
69
+ dest = File.expand_path($1)
70
+ end
71
+
72
+ @@cd_history << Dir.pwd
73
+ Dir.chdir(dest)
74
+ rescue Errno::ENOENT
75
+ output.puts "No such directory: #{dest}"
76
+ end
77
+ else
78
+ if !system(cmd)
79
+ output.puts "Error: there was a problem executing system command: #{cmd}"
80
+ end
81
+ end
82
+
83
+ # Tick, tock, im getting rid of this shit soon.
84
+ val.replace("")
85
+ end
86
+
87
+ # Determine whether a Pry command was matched and return command data
88
+ # and argument string.
89
+ # This method should not need to be invoked directly.
90
+ # @param [String] val The line of input.
91
+ # @return [Array] The command data and arg string pair
92
+ def command_matched(val)
93
+ _, cmd_data = commands.commands.find do |name, cmd_data|
94
+ /^#{Regexp.escape(name)}(?!\S)(?:\s+(.+))?/ =~ val
95
+ end
96
+
97
+ [cmd_data, $1]
98
+ end
99
+
100
+ # Process Pry commands. Pry commands are not Ruby methods and are evaluated
101
+ # prior to Ruby expressions.
102
+ # Commands can be modified/configured by the user: see `Pry::Commands`
103
+ # This method should not need to be invoked directly - it is called
104
+ # by `Pry#r`.
105
+ # @param [String] val The current line of input.
106
+ # @param [String] eval_string The cumulative lines of input for
107
+ # multi-line input.
108
+ # @param [Binding] target The receiver of the commands.
109
+ def process_commands(val, eval_string, target)
110
+ def val.clear() replace("") end
111
+ def eval_string.clear() replace("") end
112
+
113
+ if system_command?(val)
114
+ execute_system_command(val, target)
115
+ return
116
+ end
117
+
118
+ # no command was matched, so return to caller
119
+ return if !pry_command?(val)
120
+
121
+ val.replace interpolate_string(val, target)
122
+ cmd_data, args_string = command_matched(val)
123
+
124
+ args = args_string ? Shellwords.shellwords(args_string) : []
125
+ action = cmd_data[:action]
126
+ keep_retval = cmd_data[:keep_retval]
127
+
128
+ options = {
129
+ :val => val,
130
+ :eval_string => eval_string,
131
+ :nesting => nesting,
132
+ :commands => commands.commands
133
+ }
134
+
135
+ ret_value = execute_command(target, action, options, *args)
136
+
137
+ # return value of block only if :keep_retval is true
138
+ ret_value if keep_retval
139
+ end
140
+
141
+ # Execute a Pry command.
142
+ # This method should not need to be invoked directly.
143
+ # @param [Binding] target The target of the Pry session.
144
+ # @param [Proc] action The proc that implements the command.
145
+ # @param [Hash] options The options to set on the Commands object.
146
+ # @param [Array] args The command arguments.
147
+ def execute_command(target, action, options, *args)
148
+
149
+ # set some useful methods to be used by the action blocks
150
+ commands.opts = options
151
+ commands.target = target
152
+ commands.output = output
153
+
154
+ case action.arity <=> 0
155
+ when -1
156
+
157
+ # Use instance_exec() to make the `opts` method, etc available
158
+ ret_val = commands.instance_exec(*args, &action)
159
+ when 1, 0
160
+
161
+ # ensure that we get the right number of parameters
162
+ # since 1.8.7 complains about incorrect arity (1.9.2
163
+ # doesn't care)
164
+ args_with_corrected_arity = args.values_at *0..(action.arity - 1)
165
+ ret_val = commands.instance_exec(*args_with_corrected_arity, &action)
166
+ end
167
+
168
+ # Tick, tock, im getting rid of this shit soon.
169
+ options[:val].clear
170
+
171
+ ret_val
172
+ end
173
+ end
174
+ end