pry 0.10.4 → 0.11.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -18
  3. data/LICENSE +1 -1
  4. data/README.md +28 -26
  5. data/bin/pry +3 -7
  6. data/lib/pry.rb +3 -2
  7. data/lib/pry/basic_object.rb +6 -0
  8. data/lib/pry/cli.rb +39 -34
  9. data/lib/pry/code.rb +6 -1
  10. data/lib/pry/code/code_file.rb +8 -2
  11. data/lib/pry/code_object.rb +23 -0
  12. data/lib/pry/color_printer.rb +11 -8
  13. data/lib/pry/command.rb +40 -16
  14. data/lib/pry/command_set.rb +9 -2
  15. data/lib/pry/commands/cat/exception_formatter.rb +11 -10
  16. data/lib/pry/commands/cat/file_formatter.rb +7 -3
  17. data/lib/pry/commands/code_collector.rb +16 -14
  18. data/lib/pry/commands/easter_eggs.rb +9 -9
  19. data/lib/pry/commands/edit.rb +6 -2
  20. data/lib/pry/commands/edit/file_and_line_locator.rb +1 -1
  21. data/lib/pry/commands/find_method.rb +1 -1
  22. data/lib/pry/commands/gem_open.rb +1 -1
  23. data/lib/pry/commands/gem_readme.rb +25 -0
  24. data/lib/pry/commands/gem_search.rb +40 -0
  25. data/lib/pry/commands/hist.rb +2 -2
  26. data/lib/pry/commands/jump_to.rb +7 -7
  27. data/lib/pry/commands/ls/formatter.rb +1 -0
  28. data/lib/pry/commands/ls/jruby_hacks.rb +2 -2
  29. data/lib/pry/commands/ls/self_methods.rb +2 -0
  30. data/lib/pry/commands/play.rb +2 -2
  31. data/lib/pry/commands/reload_code.rb +2 -2
  32. data/lib/pry/commands/ri.rb +4 -0
  33. data/lib/pry/commands/shell_command.rb +34 -8
  34. data/lib/pry/commands/show_info.rb +10 -2
  35. data/lib/pry/commands/watch_expression/expression.rb +1 -1
  36. data/lib/pry/commands/whereami.rb +6 -6
  37. data/lib/pry/config.rb +3 -16
  38. data/lib/pry/config/behavior.rb +139 -49
  39. data/lib/pry/config/default.rb +21 -33
  40. data/lib/pry/config/lazy.rb +25 -0
  41. data/lib/pry/editor.rb +1 -1
  42. data/lib/pry/exceptions.rb +1 -1
  43. data/lib/pry/helpers/base_helpers.rb +6 -10
  44. data/lib/pry/helpers/documentation_helpers.rb +1 -0
  45. data/lib/pry/helpers/options_helpers.rb +1 -1
  46. data/lib/pry/helpers/text.rb +69 -76
  47. data/lib/pry/history.rb +22 -1
  48. data/lib/pry/history_array.rb +1 -1
  49. data/lib/pry/hooks.rb +48 -107
  50. data/lib/pry/indent.rb +6 -2
  51. data/lib/pry/input_completer.rb +118 -118
  52. data/lib/pry/method.rb +13 -13
  53. data/lib/pry/method/disowned.rb +1 -0
  54. data/lib/pry/method/patcher.rb +0 -3
  55. data/lib/pry/output.rb +37 -38
  56. data/lib/pry/pager.rb +11 -8
  57. data/lib/pry/plugins.rb +20 -5
  58. data/lib/pry/pry_class.rb +29 -3
  59. data/lib/pry/pry_instance.rb +8 -6
  60. data/lib/pry/repl.rb +37 -5
  61. data/lib/pry/repl_file_loader.rb +1 -1
  62. data/lib/pry/rubygem.rb +3 -1
  63. data/lib/pry/slop.rb +661 -0
  64. data/lib/pry/slop/LICENSE +20 -0
  65. data/lib/pry/slop/commands.rb +196 -0
  66. data/lib/pry/slop/option.rb +208 -0
  67. data/lib/pry/terminal.rb +16 -5
  68. data/lib/pry/test/helper.rb +11 -2
  69. data/lib/pry/version.rb +1 -1
  70. data/lib/pry/wrapped_module.rb +5 -5
  71. data/lib/pry/{module_candidate.rb → wrapped_module/candidate.rb} +2 -4
  72. metadata +14 -20
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Lee Jarvis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,196 @@
1
+ class Pry::Slop
2
+ class Commands
3
+ include Enumerable
4
+
5
+ attr_reader :config, :commands, :arguments
6
+ attr_writer :banner
7
+
8
+ # Create a new instance of Slop::Commands and optionally build
9
+ # Slop instances via a block. Any configuration options used in
10
+ # this method will be the default configuration options sent to
11
+ # each Slop object created.
12
+ #
13
+ # config - An optional configuration Hash.
14
+ # block - Optional block used to define commands.
15
+ #
16
+ # Examples:
17
+ #
18
+ # commands = Slop::Commands.new do
19
+ # on :new do
20
+ # on '-o', '--outdir=', 'The output directory'
21
+ # on '-v', '--verbose', 'Enable verbose mode'
22
+ # end
23
+ #
24
+ # on :generate do
25
+ # on '--assets', 'Generate assets', :default => true
26
+ # end
27
+ #
28
+ # global do
29
+ # on '-D', '--debug', 'Enable debug mode', :default => false
30
+ # end
31
+ # end
32
+ #
33
+ # commands[:new].class #=> Slop
34
+ # commands.parse
35
+ #
36
+ def initialize(config = {}, &block)
37
+ @config = config
38
+ @commands = {}
39
+ @banner = nil
40
+ @triggered_command = nil
41
+
42
+ warn "[DEPRECATED] Slop::Commands is deprecated and will be removed in "\
43
+ "Slop version 4. Check out http://injekt.github.com/slop/#commands for "\
44
+ "a new implementation of commands."
45
+
46
+ if block_given?
47
+ block.arity == 1 ? yield(self) : instance_eval(&block)
48
+ end
49
+ end
50
+
51
+ # Optionally set the banner for this command help output.
52
+ #
53
+ # banner - The String text to set the banner.
54
+ #
55
+ # Returns the String banner if one is set.
56
+ def banner(banner = nil)
57
+ @banner = banner if banner
58
+ @banner
59
+ end
60
+
61
+ # Add a Slop instance for a specific command.
62
+ #
63
+ # command - A String or Symbol key used to identify this command.
64
+ # config - A Hash of configuration options to pass to Slop.
65
+ # block - An optional block used to pass options to Slop.
66
+ #
67
+ # Returns the newly created Slop instance mapped to command.
68
+ def on(command, config = {}, &block)
69
+ commands[command.to_s] = Slop.new(@config.merge(config), &block)
70
+ end
71
+
72
+ # Add a Slop instance used when no other commands exist.
73
+ #
74
+ # config - A Hash of configuration options to pass to Slop.
75
+ # block - An optional block used to pass options to Slop.
76
+ #
77
+ # Returns the newly created Slop instance mapped to default.
78
+ def default(config = {}, &block)
79
+ on('default', config, &block)
80
+ end
81
+
82
+ # Add a global Slop instance.
83
+ #
84
+ # config - A Hash of configuration options to pass to Slop.
85
+ # block - An optional block used to pass options to Slop.
86
+ #
87
+ # Returns the newly created Slop instance mapped to global.
88
+ def global(config = {}, &block)
89
+ on('global', config, &block)
90
+ end
91
+
92
+ # Fetch the instance of Slop tied to a command.
93
+ #
94
+ # key - The String or Symbol key used to locate this command.
95
+ #
96
+ # Returns the Slop instance if this key is found, nil otherwise.
97
+ def [](key)
98
+ commands[key.to_s]
99
+ end
100
+ alias get []
101
+
102
+ # Check for a command presence.
103
+ #
104
+ # Examples:
105
+ #
106
+ # cmds.parse %w( foo )
107
+ # cmds.present?(:foo) #=> true
108
+ # cmds.present?(:bar) #=> false
109
+ #
110
+ # Returns true if the given key is present in the parsed arguments.
111
+ def present?(key)
112
+ key.to_s == @triggered_command
113
+ end
114
+
115
+ # Enumerable interface.
116
+ def each(&block)
117
+ @commands.each(&block)
118
+ end
119
+
120
+ # Parse a list of items.
121
+ #
122
+ # items - The Array of items to parse.
123
+ #
124
+ # Returns the original Array of items.
125
+ def parse(items = ARGV)
126
+ parse! items.dup
127
+ items
128
+ end
129
+
130
+ # Parse a list of items, removing any options or option arguments found.
131
+ #
132
+ # items - The Array of items to parse.
133
+ #
134
+ # Returns the original Array of items with options removed.
135
+ def parse!(items = ARGV)
136
+ if opts = commands[items[0].to_s]
137
+ @triggered_command = items.shift
138
+ execute_arguments! items
139
+ opts.parse! items
140
+ execute_global_opts! items
141
+ else
142
+ if opts = commands['default']
143
+ opts.parse! items
144
+ else
145
+ if config[:strict] && items[0]
146
+ raise InvalidCommandError, "Unknown command `#{items[0]}`"
147
+ end
148
+ end
149
+ execute_global_opts! items
150
+ end
151
+ items
152
+ end
153
+
154
+ # Returns a nested Hash with Slop options and values. See Slop#to_hash.
155
+ def to_hash
156
+ Hash[commands.map { |k, v| [k.to_sym, v.to_hash] }]
157
+ end
158
+
159
+ # Returns the help String.
160
+ def to_s
161
+ defaults = commands.delete('default')
162
+ globals = commands.delete('global')
163
+ helps = commands.reject { |_, v| v.options.none? }
164
+ if globals && globals.options.any?
165
+ helps.merge!('Global options' => globals.to_s)
166
+ end
167
+ if defaults && defaults.options.any?
168
+ helps.merge!('Other options' => defaults.to_s)
169
+ end
170
+ banner = @banner ? "#{@banner}\n" : ""
171
+ banner + helps.map { |key, opts| " #{key}\n#{opts}" }.join("\n\n")
172
+ end
173
+ alias help to_s
174
+
175
+ # Returns the inspection String.
176
+ def inspect
177
+ "#<Slop::Commands #{config.inspect} #{commands.values.map(&:inspect)}>"
178
+ end
179
+
180
+ private
181
+
182
+ # Returns nothing.
183
+ def execute_arguments!(items)
184
+ @arguments = items.take_while { |arg| !arg.start_with?('-') }
185
+ items.shift @arguments.size
186
+ end
187
+
188
+ # Returns nothing.
189
+ def execute_global_opts!(items)
190
+ if global_opts = commands['global']
191
+ global_opts.parse! items
192
+ end
193
+ end
194
+
195
+ end
196
+ end
@@ -0,0 +1,208 @@
1
+ class Pry::Slop
2
+ class Option
3
+
4
+ # The default Hash of configuration options this class uses.
5
+ DEFAULT_OPTIONS = {
6
+ :argument => false,
7
+ :optional_argument => false,
8
+ :tail => false,
9
+ :default => nil,
10
+ :callback => nil,
11
+ :delimiter => ',',
12
+ :limit => 0,
13
+ :match => nil,
14
+ :optional => true,
15
+ :required => false,
16
+ :as => String,
17
+ :autocreated => false
18
+ }
19
+
20
+ attr_reader :short, :long, :description, :config, :types
21
+ attr_accessor :count, :argument_in_value
22
+
23
+ # Incapsulate internal option information, mainly used to store
24
+ # option specific configuration data, most of the meat of this
25
+ # class is found in the #value method.
26
+ #
27
+ # slop - The instance of Slop tied to this Option.
28
+ # short - The String or Symbol short flag.
29
+ # long - The String or Symbol long flag.
30
+ # description - The String description text.
31
+ # config - A Hash of configuration options.
32
+ # block - An optional block used as a callback.
33
+ def initialize(slop, short, long, description, config = {}, &block)
34
+ @slop = slop
35
+ @short = short
36
+ @long = long
37
+ @description = description
38
+ @config = DEFAULT_OPTIONS.merge(config)
39
+ @count = 0
40
+ @callback = block_given? ? block : config[:callback]
41
+ @value = nil
42
+
43
+ @types = {
44
+ :string => proc { |v| v.to_s },
45
+ :symbol => proc { |v| v.to_sym },
46
+ :integer => proc { |v| value_to_integer(v) },
47
+ :float => proc { |v| value_to_float(v) },
48
+ :range => proc { |v| value_to_range(v) },
49
+ :count => proc { |v| @count }
50
+ }
51
+
52
+ if long && long.size > @slop.config[:longest_flag]
53
+ @slop.config[:longest_flag] = long.size
54
+ end
55
+
56
+ @config.each_key do |key|
57
+ predicate = :"#{key}?"
58
+ unless self.class.method_defined? predicate
59
+ self.class.__send__(:define_method, predicate) { !!@config[key] }
60
+ end
61
+ end
62
+ end
63
+
64
+ # Returns true if this option expects an argument.
65
+ def expects_argument?
66
+ config[:argument] && config[:argument] != :optional
67
+ end
68
+
69
+ # Returns true if this option accepts an optional argument.
70
+ def accepts_optional_argument?
71
+ config[:optional_argument] || config[:argument] == :optional
72
+ end
73
+
74
+ # Returns the String flag of this option. Preferring the long flag.
75
+ def key
76
+ long || short
77
+ end
78
+
79
+ # Call this options callback if one exists, and it responds to call().
80
+ #
81
+ # Returns nothing.
82
+ def call(*objects)
83
+ @callback.call(*objects) if @callback.respond_to?(:call)
84
+ end
85
+
86
+ # Set the new argument value for this option.
87
+ #
88
+ # We use this setter method to handle concatenating lists. That is,
89
+ # when an array type is specified and used more than once, values from
90
+ # both options will be grouped together and flattened into a single array.
91
+ def value=(new_value)
92
+ if config[:as].to_s.downcase == 'array'
93
+ @value ||= []
94
+
95
+ if new_value.respond_to?(:split)
96
+ @value.concat new_value.split(config[:delimiter], config[:limit])
97
+ end
98
+ else
99
+ @value = new_value
100
+ end
101
+ end
102
+
103
+ # Fetch the argument value for this option.
104
+ #
105
+ # Returns the Object once any type conversions have taken place.
106
+ def value
107
+ value = @value.nil? ? config[:default] : @value
108
+
109
+ if [true, false, nil].include?(value) && config[:as].to_s != 'count'
110
+ return value
111
+ end
112
+
113
+ type = config[:as]
114
+ if type.respond_to?(:call)
115
+ type.call(value)
116
+ else
117
+ if callable = types[type.to_s.downcase.to_sym]
118
+ callable.call(value)
119
+ else
120
+ value
121
+ end
122
+ end
123
+ end
124
+
125
+ # Returns the help String for this option.
126
+ def to_s
127
+ return config[:help] if config[:help].respond_to?(:to_str)
128
+
129
+ out = " #{short ? "-#{short}, " : ' ' * 4}"
130
+
131
+ if long
132
+ out << "--#{long}"
133
+ size = long.size
134
+ diff = @slop.config[:longest_flag] - size
135
+ out << (' ' * (diff + 6))
136
+ else
137
+ out << (' ' * (@slop.config[:longest_flag] + 8))
138
+ end
139
+
140
+ "#{out}#{description}"
141
+ end
142
+ alias help to_s
143
+
144
+ # Returns the String inspection text.
145
+ def inspect
146
+ "#<Slop::Option [-#{short} | --#{long}" +
147
+ "#{'=' if expects_argument?}#{'=?' if accepts_optional_argument?}]" +
148
+ " (#{description}) #{config.inspect}"
149
+ end
150
+
151
+ private
152
+
153
+ # Convert an object to an Integer if possible.
154
+ #
155
+ # value - The Object we want to convert to an integer.
156
+ #
157
+ # Returns the Integer value if possible to convert, else a zero.
158
+ def value_to_integer(value)
159
+ if @slop.strict?
160
+ begin
161
+ Integer(value.to_s, 10)
162
+ rescue ArgumentError
163
+ raise InvalidArgumentError, "#{value} could not be coerced into Integer"
164
+ end
165
+ else
166
+ value.to_s.to_i
167
+ end
168
+ end
169
+
170
+ # Convert an object to a Float if possible.
171
+ #
172
+ # value - The Object we want to convert to a float.
173
+ #
174
+ # Returns the Float value if possible to convert, else a zero.
175
+ def value_to_float(value)
176
+ if @slop.strict?
177
+ begin
178
+ Float(value.to_s)
179
+ rescue ArgumentError
180
+ raise InvalidArgumentError, "#{value} could not be coerced into Float"
181
+ end
182
+ else
183
+ value.to_s.to_f
184
+ end
185
+ end
186
+
187
+ # Convert an object to a Range if possible.
188
+ #
189
+ # value - The Object we want to convert to a range.
190
+ #
191
+ # Returns the Range value if one could be found, else the original object.
192
+ def value_to_range(value)
193
+ case value.to_s
194
+ when /\A(\-?\d+)\z/
195
+ Range.new($1.to_i, $1.to_i)
196
+ when /\A(-?\d+?)(\.\.\.?|-|,)(-?\d+)\z/
197
+ Range.new($1.to_i, $3.to_i, $2 == '...')
198
+ else
199
+ if @slop.strict?
200
+ raise InvalidArgumentError, "#{value} could not be coerced into Range"
201
+ else
202
+ value
203
+ end
204
+ end
205
+ end
206
+
207
+ end
208
+ end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  class Pry::Terminal
2
3
  class << self
3
4
  # Return a pair of [rows, columns] which gives the size of the window.
@@ -41,11 +42,21 @@ class Pry::Terminal
41
42
 
42
43
  def screen_size_according_to_io_console
43
44
  return if Pry::Helpers::BaseHelpers.jruby?
44
- require 'io/console'
45
- $stdout.winsize if $stdout.tty? and $stdout.respond_to?(:winsize)
46
- rescue LoadError
47
- # They probably don't have the io/console stdlib or the io-console gem.
48
- # We'll keep trying.
45
+
46
+ begin
47
+ require 'io/console'
48
+
49
+ begin
50
+ if $stdout.respond_to?(:tty?) && $stdout.tty? && $stdout.respond_to?(:winsize)
51
+ $stdout.winsize
52
+ end
53
+ rescue Errno::EOPNOTSUPP
54
+ # $stdout is probably a socket, which doesn't support #winsize.
55
+ end
56
+ rescue LoadError
57
+ # They probably don't have the io/console stdlib or the io-console gem.
58
+ # We'll keep trying.
59
+ end
49
60
  end
50
61
 
51
62
  def screen_size_according_to_env