pry 0.9.11.4 → 0.9.12pre1

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 (41) hide show
  1. data/.travis.yml +2 -0
  2. data/Rakefile +4 -0
  3. data/lib/pry.rb +1 -1
  4. data/lib/pry/cli.rb +14 -8
  5. data/lib/pry/code.rb +3 -3
  6. data/lib/pry/command.rb +20 -5
  7. data/lib/pry/command_set.rb +3 -3
  8. data/lib/pry/commands.rb +1 -1
  9. data/lib/pry/commands/disabled_commands.rb +2 -0
  10. data/lib/pry/commands/ls.rb +1 -2
  11. data/lib/pry/commands/reload_code.rb +8 -1
  12. data/lib/pry/commands/show_info.rb +27 -4
  13. data/lib/pry/commands/show_source.rb +2 -1
  14. data/lib/pry/commands/whereami.rb +87 -19
  15. data/lib/pry/completion.rb +7 -4
  16. data/lib/pry/helpers/base_helpers.rb +5 -2
  17. data/lib/pry/helpers/command_helpers.rb +3 -1
  18. data/lib/pry/helpers/documentation_helpers.rb +18 -7
  19. data/lib/pry/helpers/table.rb +4 -4
  20. data/lib/pry/indent.rb +2 -7
  21. data/lib/pry/method.rb +89 -129
  22. data/lib/pry/method/disowned.rb +53 -0
  23. data/lib/pry/method/weird_method_locator.rb +186 -0
  24. data/lib/pry/module_candidate.rb +3 -3
  25. data/lib/pry/pager.rb +13 -11
  26. data/lib/pry/pry_class.rb +10 -3
  27. data/lib/pry/terminal.rb +73 -0
  28. data/lib/pry/version.rb +1 -1
  29. data/lib/pry/wrapped_module.rb +51 -1
  30. data/spec/command_helpers_spec.rb +21 -1
  31. data/spec/commands/ls_spec.rb +4 -0
  32. data/spec/commands/show_doc_spec.rb +28 -28
  33. data/spec/commands/show_source_spec.rb +70 -22
  34. data/spec/commands/whereami_spec.rb +60 -11
  35. data/spec/documentation_helper_spec.rb +73 -0
  36. data/spec/fixtures/whereami_helper.rb +6 -0
  37. data/spec/helpers/table_spec.rb +19 -0
  38. data/spec/method_spec.rb +24 -7
  39. metadata +13 -7
  40. data/lib/pry/commands/deprecated_commands.rb +0 -2
  41. data/lib/pry/terminal_info.rb +0 -48
@@ -2,6 +2,7 @@ rvm:
2
2
  - 1.8.7
3
3
  - 1.9.2
4
4
  - 1.9.3
5
+ - ruby-head
5
6
  - ree
6
7
  - rbx-18mode
7
8
  - rbx-19mode
@@ -17,3 +18,4 @@ notifications:
17
18
  branches:
18
19
  only:
19
20
  - master
21
+ - 0-9-11-stable
data/Rakefile CHANGED
@@ -119,6 +119,8 @@ task :gems => [:clean, :rmgems, 'ruby:gem', 'mswin32:gem', 'mingw32:gem', 'jruby
119
119
 
120
120
  desc "remove all platform gems"
121
121
  task :rmgems => ['ruby:clobber_package']
122
+ task :rm_gems => :rmgems
123
+ task :rm_pkgs => :rmgems
122
124
 
123
125
  desc "reinstall gem"
124
126
  task :reinstall => :gems do
@@ -126,6 +128,8 @@ task :reinstall => :gems do
126
128
  sh "gem install #{File.dirname(__FILE__)}/pkg/pry-#{Pry::VERSION}.gem"
127
129
  end
128
130
 
131
+ task :install => :reinstall
132
+
129
133
  desc "build and push latest gems"
130
134
  task :pushgems => :gems do
131
135
  chdir("#{File.dirname(__FILE__)}/pkg") do
data/lib/pry.rb CHANGED
@@ -266,6 +266,6 @@ require 'pry/pry_class'
266
266
  require 'pry/pry_instance'
267
267
  require 'pry/cli'
268
268
  require 'pry/pager'
269
- require 'pry/terminal_info'
269
+ require 'pry/terminal'
270
270
  require 'pry/editor'
271
271
  require 'pry/rubygem'
@@ -99,10 +99,10 @@ Pry::CLI.add_options do
99
99
  banner %{Usage: pry [OPTIONS]
100
100
  Start a Pry session.
101
101
  See: `https://github.com/pry` for more information.
102
- Copyright (c) 2011 John Mair (banisterfiend)
102
+ Copyright (c) 2013 John Mair (banisterfiend)
103
103
  --
104
104
  }
105
- on :e, :exec, "A line of code to execute in context before the session starts", :argument => true do |input|
105
+ on :e, :exec=, "A line of code to execute in context before the session starts" do |input|
106
106
  exec_string << input + "\n"
107
107
  end
108
108
 
@@ -123,12 +123,12 @@ Copyright (c) 2011 John Mair (banisterfiend)
123
123
  Pry.config.should_load_local_rc = false
124
124
  end
125
125
 
126
- on :s, "select-plugin", "Only load specified plugin (and no others).", :argument => true do |plugin_name|
126
+ on :s, "select-plugin=", "Only load specified plugin (and no others)." do |plugin_name|
127
127
  Pry.config.should_load_plugins = false
128
128
  Pry.plugins[plugin_name].activate!
129
129
  end
130
130
 
131
- on :d, "disable-plugin", "Disable a specific plugin.", :argument => true do |plugin_name|
131
+ on :d, "disable-plugin=", "Disable a specific plugin." do |plugin_name|
132
132
  Pry.plugins[plugin_name].disable!
133
133
  end
134
134
 
@@ -149,11 +149,11 @@ Copyright (c) 2011 John Mair (banisterfiend)
149
149
  Pry.config.prompt = Pry::SIMPLE_PROMPT
150
150
  end
151
151
 
152
- on :r, :require, "`require` a Ruby script at startup", :argument => true do |file|
152
+ on :r, :require=, "`require` a Ruby script at startup" do |file|
153
153
  Pry.config.requires << file
154
154
  end
155
155
 
156
- on :I, "Add a path to the $LOAD_PATH", :argument => true, :as => Array, :delimiter => ":" do |load_path|
156
+ on :I=, "Add a path to the $LOAD_PATH", :as => Array, :delimiter => ":" do |load_path|
157
157
  load_path.map! do |path|
158
158
  /\A\.\// =~ path ? path : File.expand_path(path)
159
159
  end
@@ -161,14 +161,20 @@ Copyright (c) 2011 John Mair (banisterfiend)
161
161
  $LOAD_PATH.unshift(*load_path)
162
162
  end
163
163
 
164
+ on "gem", "Shorthand for -I./lib -rgemname" do |load_path|
165
+ $LOAD_PATH.unshift("./lib")
166
+ Dir["./lib/*.rb"].each do |file|
167
+ Pry.config.requires << file
168
+ end
169
+ end
170
+
164
171
  on :v, :version, "Display the Pry version" do
165
172
  puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}"
166
173
  exit
167
174
  end
168
175
 
169
- on(:c, :context,
176
+ on(:c, :context=,
170
177
  "Start the session in the specified context. Equivalent to `context.pry` in a session.",
171
- :argument => true,
172
178
  :default => "Pry.toplevel_binding"
173
179
  )
174
180
  end.process_options do |opts|
@@ -84,12 +84,12 @@ class Pry
84
84
  # Attempt to extract the source code for module (or class) `mod`.
85
85
  #
86
86
  # @param [Module, Class] mod The module (or class) of interest.
87
- # @param [Integer, nil] start_line The line number to start on, or nil to
88
- # use the method's original line numbers.
89
87
  # @param [Integer] candidate_rank The module candidate (by rank)
90
88
  # to use (see `Pry::WrappedModule::Candidate` for more information).
89
+ # @param [Integer, nil] start_line The line number to start on, or nil to
90
+ # use the method's original line numbers.
91
91
  # @return [Code]
92
- def from_module(mod, start_line = nil, candidate_rank = 0)
92
+ def from_module(mod, candidate_rank = 0, start_line=nil)
93
93
  candidate = Pry::WrappedModule(mod).candidate(candidate_rank)
94
94
  start_line ||= candidate.line
95
95
  new(candidate.source, start_line, :ruby)
@@ -520,7 +520,7 @@ class Pry
520
520
  end
521
521
 
522
522
  def source
523
- Pry::WrappedModule(self).source
523
+ source_object.source
524
524
  end
525
525
 
526
526
  def doc
@@ -528,18 +528,33 @@ class Pry
528
528
  end
529
529
 
530
530
  def source_location
531
- Pry::WrappedModule(self).source_location
531
+ source_object.source_location
532
532
  end
533
533
 
534
534
  def source_file
535
- Pry::WrappedModule(self).source_file
535
+ source_object.source_file
536
536
  end
537
537
  alias_method :file, :source_file
538
538
 
539
539
  def source_line
540
- Pry::WrappedModule(self).source_line
540
+ source_object.source_line
541
541
  end
542
542
  alias_method :line, :source_line
543
+
544
+ private
545
+
546
+ # The object used to extract the source for the command.
547
+ #
548
+ # This should be a `Pry::Method(block)` for a command made with `create_command`
549
+ # and a `Pry::WrappedModule(self)` for a command that's a standard class.
550
+ # @return [Pry::WrappedModule, Pry::Method]
551
+ def source_object
552
+ @source_object ||= if name =~ /^[A-Z]/
553
+ Pry::WrappedModule(self)
554
+ else
555
+ Pry::Method(block)
556
+ end
557
+ end
543
558
  end
544
559
 
545
560
  attr_accessor :opts
@@ -573,7 +588,7 @@ class Pry
573
588
  # Return an instance of Slop that can parse either subcommands or the
574
589
  # options that this command accepts.
575
590
  def slop
576
- Slop.parse do |opt|
591
+ Slop.new do |opt|
577
592
  opt.banner(unindent(self.class.banner))
578
593
  subcommands(opt)
579
594
  options(opt)
@@ -263,13 +263,13 @@ class Pry
263
263
  commands.delete(cmd.match)
264
264
  end
265
265
 
266
- def deprecated_command(name_of_deprecated_command, deprecation_message, matcher=name_of_deprecated_command)
267
- create_command name_of_deprecated_command do
266
+ def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command)
267
+ create_command name_of_disabled_command do
268
268
  match matcher
269
269
  description ""
270
270
 
271
271
  define_method(:process) do
272
- output.puts "DEPRECATED: #{deprecation_message}"
272
+ output.puts "DISABLED: #{message}"
273
273
  end
274
274
  end
275
275
  end
@@ -1,6 +1,6 @@
1
1
  # Default commands used by Pry.
2
2
  Pry::Commands = Pry::CommandSet.new
3
3
 
4
- Dir[File.expand_path('../commands/*.rb', __FILE__)].each do |file|
4
+ Dir[File.expand_path('../commands', __FILE__) + '/*.rb'].each do |file|
5
5
  require file
6
6
  end
@@ -0,0 +1,2 @@
1
+ Pry::Commands.disabled_command("edit-method", "Use `edit` instead.")
2
+ Pry::Commands.disabled_command("show-command", "Use show-source [command_name] instead.")
@@ -189,8 +189,7 @@ class Pry
189
189
  return unless opts.present?(:constants) || (!has_user_specified_any_options && interrogating_a_module?)
190
190
 
191
191
  mod = interrogating_a_module? ? object_to_interrogate : Object
192
- constants = mod.constants
193
- constants -= (mod.ancestors - [mod]).map(&:constants).flatten unless opts.present?(:verbose)
192
+ constants = WrappedModule.new(mod).constants(opts.present?(:verbose))
194
193
  output_section("constants", grep[format_constants(mod, constants)])
195
194
  end
196
195
 
@@ -6,6 +6,12 @@ class Pry
6
6
 
7
7
  banner <<-'BANNER'
8
8
  Reload the source file that contains the specified code object.
9
+
10
+ e.g reload-code MyClass#my_method #=> reload a method
11
+ reload-code MyClass #=> reload a class
12
+ reload-code my-command #=> reload a pry command
13
+ reload-code self #=> reload the 'current' object
14
+ reload-code #=> identical to reload-code self
9
15
  BANNER
10
16
 
11
17
  def process
@@ -27,7 +33,7 @@ class Pry
27
33
  end
28
34
 
29
35
  def check_for_reloadability(code_object)
30
- if !code_object
36
+ if !code_object || !code_object.source_file
31
37
  raise CommandError, "Cannot locate #{obj_name}!"
32
38
  elsif !File.exists?(code_object.source_file)
33
39
  raise CommandError, "Cannot reload #{obj_name} as it has no associated file on disk. File found was: #{code_object.source_file}"
@@ -36,4 +42,5 @@ class Pry
36
42
  end
37
43
 
38
44
  Pry::Commands.add_command(Pry::Command::ReloadCode)
45
+ Pry::Commands.alias_command 'reload-method', 'reload-code'
39
46
  end
@@ -13,28 +13,47 @@ class Pry
13
13
  opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count
14
14
  opt.on :l, "line-numbers", "Show line numbers"
15
15
  opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)"
16
- opt.on :f, :flood, "Do not use a pager to view text longer than one screen"
17
16
  opt.on :a, :all, "Show all definitions and monkeypatches of the module/class"
18
17
  end
19
18
 
20
19
  def process
21
20
  code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super])
22
- raise Pry::CommandError, "Couldn't locate #{obj_name}!" if !code_object
21
+ cannot_locate_source_error if !code_object
23
22
 
24
23
  if show_all_modules?(code_object)
25
24
  # show all monkey patches for a module
25
+
26
26
  result = content_and_headers_for_all_module_candidates(code_object)
27
27
  else
28
28
  # show a specific code object
29
- result = content_and_header_for_code_object(code_object)
29
+
30
+ co = code_object_with_accessible_source(code_object)
31
+ result = content_and_header_for_code_object(co)
30
32
  end
31
33
 
32
34
  set_file_and_dir_locals(code_object.source_file)
33
35
  stagger_output result
34
36
  end
35
37
 
38
+ # This method checks whether the `code_object` is a WrappedModule,
39
+ # if it is, then it returns the first candidate (monkeypatch) with
40
+ # accessible source (or docs). If `code_object` is not a WrappedModule (i.e a
41
+ # method or a command) then the `code_object` itself is just
42
+ # returned.
43
+ #
44
+ # @return [Pry::WrappedModule, Pry::Method, Pry::Command]
45
+ def code_object_with_accessible_source(code_object)
46
+ if code_object.is_a?(WrappedModule)
47
+ code_object.candidates.find(&:source).tap do |candidate|
48
+ cannot_locate_source_error if !candidate
49
+ end
50
+ else
51
+ code_object
52
+ end
53
+ end
54
+
36
55
  def content_and_header_for_code_object(code_object)
37
- header(code_object) << content_for(code_object)
56
+ header(code_object) + content_for(code_object)
38
57
  end
39
58
 
40
59
  def content_and_headers_for_all_module_candidates(mod)
@@ -54,6 +73,10 @@ class Pry
54
73
  result
55
74
  end
56
75
 
76
+ def cannot_locate_source_error
77
+ raise CommandError, "Couldn't locate a definition for #{obj_name}!"
78
+ end
79
+
57
80
  # Generate a header (meta-data information) for all the code
58
81
  # object types: methods, modules, commands, procs...
59
82
  def header(code_object)
@@ -25,7 +25,8 @@ class Pry
25
25
 
26
26
  # The source for code_object prepared for display.
27
27
  def content_for(code_object)
28
- raise CommandError, "Cannot locate source!" if !code_object.source
28
+ cannot_locate_source_error if !code_object.source
29
+
29
30
  Code.new(code_object.source, start_line_for(code_object)).
30
31
  with_line_numbers(use_line_numbers?).to_s
31
32
  end
@@ -1,16 +1,23 @@
1
1
  class Pry
2
2
  class Command::Whereami < Pry::ClassCommand
3
+
4
+ class << self
5
+ attr_accessor :method_size_cutoff
6
+ end
7
+
8
+ @method_size_cutoff = 30
9
+
3
10
  match 'whereami'
4
11
  description 'Show code surrounding the current context.'
5
12
  group 'Context'
6
13
 
7
14
  banner <<-'BANNER'
8
- Usage: whereami [-qn] [N]
15
+ Usage: whereami [-qn] [LINES]
9
16
 
10
17
  Describe the current location. If you use `binding.pry` inside a method then
11
18
  whereami will print out the source for that method.
12
19
 
13
- If a number is passed, then N lines before and after the current line will be
20
+ If a number is passed, then LINES lines before and after the current line will be
14
21
  shown instead of the method itself.
15
22
 
16
23
  The `-q` flag can be used to suppress error messages in the case that there's
@@ -25,29 +32,53 @@ class Pry
25
32
  BANNER
26
33
 
27
34
  def setup
28
- @method = Pry::Method.from_binding(target)
29
- @file = target.eval('__FILE__')
35
+ @file = expand_path(target.eval('__FILE__'))
30
36
  @line = target.eval('__LINE__')
37
+ @method = Pry::Method.from_binding(target)
31
38
  end
32
39
 
33
40
  def options(opt)
34
41
  opt.on :q, :quiet, "Don't display anything in case of an error"
35
42
  opt.on :n, :"no-line-numbers", "Do not display line numbers"
43
+ opt.on :m, :"method", "Show the complete source for the current method."
44
+ opt.on :c, :"class", "Show the complete source for the current class or module."
45
+ opt.on :f, :"file", "Show the complete source for the current file."
36
46
  end
37
47
 
38
48
  def code
39
- @code ||= if show_method?
40
- Pry::Code.from_method(@method)
49
+ @code ||= if opts.present?(:m)
50
+ method_code or raise CommandError, "Cannot find method code."
51
+ elsif opts.present?(:c)
52
+ class_code or raise CommandError, "Cannot find class code."
53
+ elsif opts.present?(:f)
54
+ Pry::Code.from_file(@file)
55
+ elsif args.any?
56
+ code_window
41
57
  else
42
- Pry::Code.from_file(@file).around(@line, window_size)
58
+ default_code
43
59
  end
44
60
  end
45
61
 
62
+ def code?
63
+ !!code
64
+ rescue MethodSource::SourceNotFoundError
65
+ false
66
+ end
67
+
68
+ def bad_option_combination?
69
+ [opts.present?(:m), opts.present?(:f),
70
+ opts.present?(:c), args.any?].count(true) > 1
71
+ end
72
+
46
73
  def location
47
74
  "#{@file} @ line #{@line} #{@method && @method.name_with_owner}"
48
75
  end
49
76
 
50
77
  def process
78
+ if bad_option_combination?
79
+ raise CommandError, "Only one of -m, -c, -f, and LINES may be specified."
80
+ end
81
+
51
82
  if nothing_to_do?
52
83
  return
53
84
  elsif internal_binding?(target)
@@ -57,9 +88,10 @@ class Pry
57
88
 
58
89
  set_file_and_dir_locals(@file)
59
90
 
60
- output.puts "\n#{text.bold('From:')} #{location}:\n\n"
61
- output.puts code.with_line_numbers(use_line_numbers?).with_marker(marker)
62
- output.puts
91
+ out = "\n#{text.bold('From:')} #{location}:\n\n" +
92
+ code.with_line_numbers(use_line_numbers?).with_marker(marker).to_s + "\n"
93
+
94
+ stagger_output(out)
63
95
  end
64
96
 
65
97
  private
@@ -88,17 +120,53 @@ class Pry
88
120
  end
89
121
  end
90
122
 
91
- def show_method?
92
- args.empty? && @method && @method.source? && @method.source_range.count < 20 &&
93
- # These checks are needed in case of an eval with a binding and file/line
94
- # numbers set to outside the function. As in rails' use of ERB.
95
- @method.source_file == @file && @method.source_range.include?(@line)
123
+ def small_method?
124
+ @method.source_range.count < self.class.method_size_cutoff
96
125
  end
97
126
 
98
- def code?
99
- !!code
100
- rescue MethodSource::SourceNotFoundError
101
- false
127
+ def default_code
128
+ if method_code && small_method?
129
+ method_code
130
+ else
131
+ code_window
132
+ end
133
+ end
134
+
135
+ def code_window
136
+ Pry::Code.from_file(@file).around(@line, window_size)
137
+ end
138
+
139
+ def method_code
140
+ return @method_code if @method_code
141
+
142
+ if valid_method?
143
+ @method_code = Pry::Code.from_method(@method)
144
+ end
145
+ end
146
+
147
+ def class_code
148
+ return @class_code if @class_code
149
+
150
+ if valid_method?
151
+ mod = Pry::WrappedModule(@method.owner)
152
+ idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file }
153
+ @class_code = idx && Pry::Code.from_module(mod, idx)
154
+ end
155
+ end
156
+
157
+ def valid_method?
158
+ @method && @method.source? && expand_path(@method.source_file) == @file &&
159
+ @method.source_range.include?(@line)
160
+ end
161
+
162
+ def expand_path(f)
163
+ return if !f
164
+
165
+ if Pry.eval_path == f
166
+ f
167
+ else
168
+ File.expand_path(f)
169
+ end
102
170
  end
103
171
 
104
172
  def window_size