pry 0.8.4pre1-java → 0.9.0pre1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +1 -0
  2. data/README.markdown +1 -1
  3. data/Rakefile +11 -5
  4. data/TODO +28 -2
  5. data/bin/pry +5 -9
  6. data/examples/example_basic.rb +2 -4
  7. data/examples/example_command_override.rb +2 -5
  8. data/examples/example_commands.rb +1 -4
  9. data/examples/example_hooks.rb +2 -5
  10. data/examples/example_image_edit.rb +4 -8
  11. data/examples/example_input.rb +1 -4
  12. data/examples/example_input2.rb +1 -4
  13. data/examples/example_output.rb +1 -4
  14. data/examples/example_print.rb +2 -5
  15. data/examples/example_prompt.rb +2 -5
  16. data/examples/helper.rb +6 -0
  17. data/lib/pry.rb +61 -4
  18. data/lib/pry/command_context.rb +10 -9
  19. data/lib/pry/command_processor.rb +29 -68
  20. data/lib/pry/command_set.rb +79 -28
  21. data/lib/pry/commands.rb +10 -121
  22. data/lib/pry/completion.rb +30 -29
  23. data/lib/pry/config.rb +93 -0
  24. data/lib/pry/default_commands/basic.rb +37 -0
  25. data/lib/pry/default_commands/context.rb +15 -15
  26. data/lib/pry/default_commands/documentation.rb +49 -48
  27. data/lib/pry/default_commands/easter_eggs.rb +1 -20
  28. data/lib/pry/default_commands/gems.rb +32 -41
  29. data/lib/pry/default_commands/input.rb +95 -19
  30. data/lib/pry/default_commands/introspection.rb +54 -60
  31. data/lib/pry/default_commands/ls.rb +2 -2
  32. data/lib/pry/default_commands/shell.rb +29 -39
  33. data/lib/pry/extended_commands/experimental.rb +48 -0
  34. data/lib/pry/extended_commands/user_command_api.rb +22 -0
  35. data/lib/pry/helpers.rb +1 -0
  36. data/lib/pry/helpers/base_helpers.rb +9 -106
  37. data/lib/pry/helpers/command_helpers.rb +96 -59
  38. data/lib/pry/helpers/text.rb +83 -0
  39. data/lib/pry/plugins.rb +79 -0
  40. data/lib/pry/pry_class.rb +96 -111
  41. data/lib/pry/pry_instance.rb +87 -55
  42. data/lib/pry/version.rb +1 -1
  43. data/test/helper.rb +56 -7
  44. data/test/test_command_processor.rb +99 -0
  45. data/test/{test_commandset.rb → test_command_set.rb} +18 -12
  46. data/test/test_default_commands.rb +59 -0
  47. data/test/test_default_commands/test_context.rb +64 -0
  48. data/test/test_default_commands/test_documentation.rb +31 -0
  49. data/test/test_default_commands/test_input.rb +157 -0
  50. data/test/test_default_commands/test_introspection.rb +146 -0
  51. data/test/test_pry.rb +430 -313
  52. metadata +25 -9
  53. data/lib/pry/hooks.rb +0 -17
  54. data/lib/pry/print.rb +0 -16
  55. data/lib/pry/prompts.rb +0 -31
@@ -5,15 +5,6 @@ class Pry
5
5
 
6
6
  module_function
7
7
 
8
- def try_to_load_pry_doc
9
-
10
- # YARD crashes on rbx, so do not require it
11
- if !Object.const_defined?(:RUBY_ENGINE) || RUBY_ENGINE !~ /rbx/
12
- require "pry-doc"
13
- end
14
- rescue LoadError
15
- end
16
-
17
8
  def meth_name_from_binding(b)
18
9
  meth_name = b.eval('__method__')
19
10
  if [:__script__, nil, :__binding__, :__binding_impl__].include?(meth_name)
@@ -23,29 +14,16 @@ class Pry
23
14
  end
24
15
  end
25
16
 
26
- def add_line_numbers(lines, start_line)
27
- line_array = lines.each_line.to_a
28
- line_array.each_with_index.map do |line, idx|
29
- adjusted_index = idx + start_line
30
- if Pry.color
31
- cindex = CodeRay.scan("#{adjusted_index}", :ruby).term
32
- "#{cindex}: #{line}"
33
- else
34
- "#{idx}: #{line}"
35
- end
36
- end.join
37
- end
38
-
39
17
  # if start_line is not false then add line numbers starting with start_line
40
- def render_output(should_flood, start_line, doc)
18
+ def render_output(should_flood, start_line, text)
41
19
  if start_line
42
- doc = add_line_numbers(doc, start_line)
20
+ text = Pry::Helpers::Text.with_line_numbers text, start_line
43
21
  end
44
22
 
45
23
  if should_flood
46
- output.puts doc
24
+ output.puts text
47
25
  else
48
- stagger_output(doc)
26
+ stagger_output(text)
49
27
  end
50
28
  end
51
29
 
@@ -55,31 +33,74 @@ class Pry
55
33
  end
56
34
 
57
35
  def check_for_dynamically_defined_method(meth)
58
- if is_a_dynamically_defined_method?(meth)
36
+ file, _ = meth.source_location
37
+ if file =~ /(\(.*\))|<.*>/ && file != Pry.eval_path
59
38
  raise "Cannot retrieve source for dynamically defined method."
60
39
  end
61
40
  end
62
41
 
63
- def check_for_dynamically_defined_method(meth)
64
- file, _ = meth.source_location
65
- if file =~ /(\(.*\))|<.*>/
66
- raise "Cannot retrieve source for dynamically defined method."
42
+ ########### RBX HELPERS #############
43
+ def rbx_core?(meth)
44
+ defined?(RUBY_ENGINE) &&
45
+ RUBY_ENGINE =~ /rbx/ &&
46
+ meth.source_location &&
47
+ meth.source_location.first.start_with?("kernel")
48
+ end
49
+
50
+ def rvm_ruby?(path)
51
+ !!(path =~ /\.rvm/)
52
+ end
53
+
54
+ def rbx_core_code_for(meth)
55
+ rbx_core_code_or_doc_for(meth, :code)
56
+ end
57
+
58
+ def rbx_core_doc_for(meth)
59
+ rbx_core_code_or_doc_for(meth, :doc)
60
+ end
61
+
62
+ def rbx_core_code_or_doc_for(meth, code_or_doc)
63
+ path_line = rbx_core_path_line_for(meth)
64
+
65
+ case code_or_doc
66
+ when :code
67
+ MethodSource.source_helper(path_line)
68
+ when :doc
69
+ MethodSource.comment_helper(path_line)
67
70
  end
68
71
  end
69
72
 
70
- def remove_first_word(text)
71
- text.split.drop(1).join(' ')
73
+ def rbx_core_path_line_for(meth)
74
+ if rvm_ruby?(Rubinius::BIN_PATH)
75
+ rvm_rbx_core_path_line_for(meth)
76
+ else
77
+ std_rbx_core_path_line_for(meth)
78
+ end
72
79
  end
73
80
 
74
- # turn off color for duration of block
75
- def no_color(&block)
76
- old_color_state = Pry.color
77
- Pry.color = false
78
- yield
79
- ensure
80
- Pry.color = old_color_state
81
+ def std_rbx_core_path_line_for(meth)
82
+ file_name = File.join(Rubinius::BIN_PATH, "..", meth.source_location.first)
83
+ raise "Cannot find rbx core source" if !File.exists?(file_name)
84
+
85
+ start_line = meth.source_location.last
86
+
87
+ [file_name, start_line]
81
88
  end
82
89
 
90
+ def rvm_rbx_core_path_line_for(meth)
91
+ ruby_name = File.dirname(Rubinius::BIN_PATH).split("/").last
92
+ source_path = File.join(File.dirname(File.dirname(File.dirname(Rubinius::BIN_PATH))), "src", ruby_name)
93
+
94
+ file_name = File.join(source_path, meth.source_location.first)
95
+ raise "Cannot find rbx core source" if !File.exists?(file_name)
96
+
97
+ start_line = meth.source_location.last
98
+
99
+ [file_name, start_line]
100
+ end
101
+
102
+ ######### END RBX HELPERS ###############
103
+
83
104
  def code_and_code_type_for(meth)
84
105
  case code_type = code_type_for(meth)
85
106
  when nil
@@ -88,8 +109,18 @@ class Pry
88
109
  code = Pry::MethodInfo.info_for(meth).source
89
110
  code = strip_comments_from_c_code(code)
90
111
  when :ruby
91
- code = strip_leading_whitespace(meth.source)
92
- set_file_and_dir_locals(meth.source_location.first)
112
+ if meth.source_location.first == Pry.eval_path
113
+ start_line = meth.source_location.last
114
+ p = Pry.new(:input => StringIO.new(Pry.line_buffer[start_line..-1].join)).r(target)
115
+ code = strip_leading_whitespace(p)
116
+ else
117
+ if rbx_core?(meth)
118
+ code = strip_leading_whitespace(rbx_core_code_for(meth))
119
+ else
120
+ code = strip_leading_whitespace(meth.source)
121
+ end
122
+ end
123
+ set_file_and_dir_locals(path_line_for(meth).first)
93
124
  end
94
125
 
95
126
  [code, code_type]
@@ -102,9 +133,12 @@ class Pry
102
133
  when :c
103
134
  doc = Pry::MethodInfo.info_for(meth).docstring
104
135
  when :ruby
105
- doc = meth.comment
106
- doc = strip_leading_hash_and_whitespace_from_ruby_comments(doc)
107
- set_file_and_dir_locals(meth.source_location.first)
136
+ if rbx_core?(meth)
137
+ doc = strip_leading_hash_and_whitespace_from_ruby_comments(rbx_core_doc_for(meth))
138
+ else
139
+ doc = strip_leading_hash_and_whitespace_from_ruby_comments(meth.comment)
140
+ end
141
+ set_file_and_dir_locals(path_line_for(meth).first)
108
142
  end
109
143
 
110
144
  [doc, code_type]
@@ -144,15 +178,23 @@ class Pry
144
178
  end
145
179
  end
146
180
 
181
+ def path_line_for(meth)
182
+ if rbx_core?(meth)
183
+ rbx_core_path_line_for(meth)
184
+ else
185
+ meth.source_location
186
+ end
187
+ end
188
+
147
189
  def make_header(meth, code_type, content)
148
- num_lines = "Number of lines: #{bold(content.each_line.count.to_s)}"
190
+ num_lines = "Number of lines: #{Pry::Helpers::Text.bold(content.each_line.count.to_s)}"
149
191
  case code_type
150
192
  when :ruby
151
- file, line = meth.source_location
152
- "\n#{bold('From:')} #{file} @ line #{line}:\n#{num_lines}\n\n"
193
+ file, line = path_line_for(meth)
194
+ "\n#{Pry::Helpers::Text.bold('From:')} #{file} @ line #{line}:\n#{num_lines}\n\n"
153
195
  else
154
196
  file = Pry::MethodInfo.info_for(meth).file
155
- "\n#{bold('From:')} #{file} in Ruby Core (C Method):\n#{num_lines}\n\n"
197
+ "\n#{Pry::Helpers::Text.bold('From:')} #{file} in Ruby Core (C Method):\n#{num_lines}\n\n"
156
198
  end
157
199
  end
158
200
 
@@ -161,7 +203,7 @@ class Pry
161
203
  end
162
204
 
163
205
  def should_use_pry_doc?(meth)
164
- Pry.has_pry_doc && is_a_c_method?(meth)
206
+ Pry.config.has_pry_doc && is_a_c_method?(meth)
165
207
  end
166
208
 
167
209
  def code_type_for(meth)
@@ -232,16 +274,11 @@ class Pry
232
274
  normalized_line_number(end_line, lines_array.size)]
233
275
  end
234
276
 
235
- # documentation related helpers
236
- def strip_color_codes(str)
237
- str.gsub(/\e\[.*?(\d)+m/, '')
238
- end
239
-
240
277
  def process_rdoc(comment, code_type)
241
278
  comment = comment.dup
242
279
  comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
243
- gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
244
- gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[34m#{$1}\e[0m" : $1 }.
280
+ gsub(/<em>(?:\s*\n)?(.*?)\s*<\/em>/m) { Pry.color ? "\e[1m#{$1}\e[0m": $1 }.
281
+ gsub(/<i>(?:\s*\n)?(.*?)\s*<\/i>/m) { Pry.color ? "\e[1m#{$1}\e[0m" : $1 }.
245
282
  gsub(/\B\+(\w*?)\+\B/) { Pry.color ? "\e[32m#{$1}\e[0m": $1 }.
246
283
  gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
247
284
  gsub(/`(?:\s*\n)?(.*?)\s*`/) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }
@@ -251,7 +288,7 @@ class Pry
251
288
  in_tag_block = nil
252
289
  output = comment.lines.map do |v|
253
290
  if in_tag_block && v !~ /^\S/
254
- strip_color_codes(strip_color_codes(v))
291
+ Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v)
255
292
  elsif in_tag_block
256
293
  in_tag_block = false
257
294
  v
@@ -288,7 +325,7 @@ class Pry
288
325
  end
289
326
 
290
327
  def strip_comments_from_c_code(code)
291
- code.sub /\A\s*\/\*.*?\*\/\s*/m, ''
328
+ code.sub(/\A\s*\/\*.*?\*\/\s*/m, '')
292
329
  end
293
330
 
294
331
  def prompt(message, options="Yn")
@@ -0,0 +1,83 @@
1
+ class Pry
2
+ module Helpers
3
+
4
+ # The methods defined on {Text} are available to custom commands via {Pry::CommandContext#text}.
5
+ module Text
6
+
7
+ COLORS =
8
+ {
9
+ "black" => 0,
10
+ "red" => 1,
11
+ "green" => 2,
12
+ "yellow" => 3,
13
+ "blue" => 4,
14
+ "purple" => 5,
15
+ "magenta" => 5,
16
+ "cyan" => 6,
17
+ "white" => 7
18
+ }
19
+
20
+ class << self
21
+
22
+ COLORS.each_pair do |color, value|
23
+ define_method color do |text|
24
+ Pry.color ? "\033[0;#{30+value}m#{text}\033[0m" : text.to_s
25
+ end
26
+
27
+ define_method "bright_#{color}" do |text|
28
+ Pry.color ? "\033[1;#{30+value}m#{text}\033[0m" : text.to_s
29
+ end
30
+ end
31
+
32
+ alias_method :grey, :bright_black
33
+ alias_method :gray, :bright_black
34
+
35
+
36
+ # Remove any color codes from _text_.
37
+ #
38
+ # @param [String, #to_s] text
39
+ # @return [String] _text_ stripped of any color codes.
40
+ def strip_color text
41
+ text.to_s.gsub(/\e\[.*?(\d)+m/ , '')
42
+ end
43
+
44
+ # Returns _text_ as bold text for use on a terminal.
45
+ # _Pry.color_ must be true for this method to perform any transformations.
46
+ #
47
+ # @param [String, #to_s] text
48
+ # @return [String] _text_
49
+ def bold text
50
+ Pry.color ? "\e[1m#{text}\e[0m" : text.to_s
51
+ end
52
+
53
+ # Executes _block_ with _Pry.color_ set to false.
54
+ #
55
+ # @param [Proc]
56
+ # @return [void]
57
+ def no_color &block
58
+ boolean = Pry.color
59
+ Pry.color = false
60
+ yield
61
+ ensure
62
+ Pry.color = boolean
63
+ end
64
+
65
+ # Returns _text_ in a numbered list, beginning at _offset_.
66
+ #
67
+ # @param [#each_line] text
68
+ # @param [Fixnum] offset
69
+ # @return [String]
70
+ def with_line_numbers text, offset
71
+ lines = text.each_line.to_a
72
+ lines.each_with_index.map do |line, index|
73
+ adjusted_index = index + offset
74
+ "#{self.blue adjusted_index}: #{line}"
75
+ end.join
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
83
+
@@ -0,0 +1,79 @@
1
+ class Pry
2
+ class PluginManager
3
+ PRY_PLUGIN_PREFIX = /^pry-/
4
+ PluginNotFound = Class.new(LoadError)
5
+
6
+ MessageSink = Object.new.tap { |o| def o.method_missing(*args) end }
7
+
8
+ class Plugin
9
+ attr_accessor :name, :gem_name, :enabled, :active
10
+
11
+ def initialize(name, gem_name, enabled)
12
+ @name, @gem_name, @enabled = name, gem_name, enabled
13
+ end
14
+
15
+ # Disable a plugin.
16
+ def disable!
17
+ self.enabled = false
18
+ end
19
+
20
+ # Enable a plugin.
21
+ def enable!
22
+ self.enabled = true
23
+ end
24
+
25
+ # Activate the plugin (require the gem).
26
+ def activate!
27
+ begin
28
+ require gem_name
29
+ rescue LoadError
30
+ raise PluginNotFound, "The plugin '#{gem_name}' was not found!"
31
+ end
32
+ self.active = true
33
+ self.enabled = true
34
+ end
35
+
36
+ alias active? active
37
+ alias enabled? enabled
38
+ end
39
+
40
+ def initialize
41
+ @plugins = []
42
+ end
43
+
44
+ # Find all installed Pry plugins and store them in an internal array.
45
+ def locate_plugins
46
+ Gem.refresh
47
+ (Gem::Specification.respond_to?(:each) ? Gem::Specification : Gem.source_index.find_name('')).each do |gem|
48
+ next if gem.name !~ PRY_PLUGIN_PREFIX
49
+ plugin_name = gem.name.split('-', 2).last
50
+ @plugins << Plugin.new(plugin_name, gem.name, true) if !gem_located?(gem.name)
51
+ end
52
+ @plugins
53
+ end
54
+
55
+ # @return [Hash] A hash with all plugin names (minus the 'pry-') as
56
+ # keys and Plugin objects as values.
57
+ def plugins
58
+ h = Pry.config.plugins.strict_loading ? {} : Hash.new { MessageSink }
59
+ @plugins.each do |plugin|
60
+ h[plugin.name] = plugin
61
+ end
62
+ h
63
+ end
64
+
65
+ # Require all enabled plugins, disabled plugins are skipped.
66
+ def load_plugins
67
+ @plugins.each do |plugin|
68
+ plugin.activate! if plugin.enabled?
69
+ end
70
+ end
71
+
72
+ private
73
+ def gem_located?(gem_name)
74
+ @plugins.any? { |plugin| plugin.gem_name == gem_name }
75
+ end
76
+ end
77
+
78
+ end
79
+
@@ -1,3 +1,7 @@
1
+ require 'ostruct'
2
+ require 'forwardable'
3
+ require 'pry/config'
4
+
1
5
  # @author John Mair (banisterfiend)
2
6
  class Pry
3
7
 
@@ -6,6 +10,13 @@ class Pry
6
10
 
7
11
  # class accessors
8
12
  class << self
13
+ extend Forwardable
14
+
15
+ # convenience method
16
+ def self.delegate_accessors(delagatee, *names)
17
+ def_delegators delagatee, *names
18
+ def_delegators delagatee, *names.map { |v| "#{v}=" }
19
+ end
9
20
 
10
21
  # Get nesting data.
11
22
  # This method should not need to be accessed directly.
@@ -27,41 +38,6 @@ class Pry
27
38
  # @return [Pry] The active Pry instance.
28
39
  attr_accessor :active_instance
29
40
 
30
- # Get/Set the object to use for input by default by all Pry instances.
31
- # @return [#readline] The object to use for input by default by all
32
- # Pry instances.
33
- attr_accessor :input
34
-
35
- # Get/Set the object to use for output by default by all Pry instances.
36
- # @return [#puts] The object to use for output by default by all
37
- # Pry instances.
38
- attr_accessor :output
39
-
40
- # Get/Set the object to use for commands by default by all Pry instances.
41
- # @return [Pry::CommandBase] The object to use for commands by default by all
42
- # Pry instances.
43
- attr_accessor :commands
44
-
45
- # Get/Set the Proc to use for printing by default by all Pry
46
- # instances.
47
- # This is the 'print' component of the REPL.
48
- # @return [Proc] The Proc to use for printing by default by all
49
- # Pry instances.
50
- attr_accessor :print
51
-
52
- # @return [Proc] The Proc to use for printing exceptions by default by all
53
- # Pry instances.
54
- attr_accessor :exception_handler
55
-
56
- # Get/Set the Hash that defines Pry hooks used by default by all Pry
57
- # instances.
58
- # @return [Hash] The hooks used by default by all Pry instances.
59
- # @example
60
- # Pry.hooks :before_session => proc { puts "hello" },
61
- # :after_session => proc { puts "goodbye" }
62
- attr_accessor :hooks
63
-
64
-
65
41
  # Get/Set the Proc that defines extra Readline completions (on top
66
42
  # of the ones defined for IRB).
67
43
  # @return [Proc] The Proc that defines extra Readline completions (on top
@@ -69,49 +45,31 @@ class Pry
69
45
  # Pry.custom_completions = proc { Dir.entries('.') }
70
46
  attr_accessor :custom_completions
71
47
 
72
- # Get the array of Procs to be used for the prompts by default by
73
- # all Pry instances.
74
- # @return [Array<Proc>] The array of Procs to be used for the
75
- # prompts by default by all Pry instances.
76
- attr_accessor :prompt
77
-
78
48
  # Value returned by last executed Pry command.
79
49
  # @return [Object] The command value
80
50
  attr_accessor :cmd_ret_value
81
51
 
82
- # Determines whether colored output is enabled.
83
- # @return [Boolean]
84
- attr_accessor :color
52
+ # @return [Fixnum] The current input line.
53
+ attr_accessor :current_line
85
54
 
86
- # Determines whether paging (of long blocks of text) is enabled.
87
- # @return [Boolean]
88
- attr_accessor :pager
55
+ # @return [Array] The Array of evaluated expressions.
56
+ attr_accessor :line_buffer
89
57
 
90
- # Determines whether the rc file (~/.pryrc) should be loaded.
91
- # @return [Boolean]
92
- attr_accessor :should_load_rc
58
+ # @return [String] The __FILE__ for the `eval()`. Should be "(pry)"
59
+ # by default.
60
+ attr_accessor :eval_path
93
61
 
94
- # Set to true if Pry is invoked from command line using `pry` executable
95
- # @return [Boolean]
62
+ # @return [OpenStruct] Return Pry's config object.
63
+ attr_accessor :config
64
+
65
+ # @return [Boolean] Whether Pry was activated from the command line.
96
66
  attr_accessor :cli
97
67
 
98
- # Set to true if the pry-doc extension is loaded.
99
- # @return [Boolean]
100
- attr_accessor :has_pry_doc
101
-
102
- # The default editor to use. Defaults to $EDITOR or nano if
103
- # $EDITOR is not defined.
104
- # If `editor` is a String then that string is used as the shell
105
- # command to invoke the editor. If `editor` is callable (e.g a
106
- # Proc) then `file` and `line` are passed in as parameters and the
107
- # return value of that callable invocation is used as the exact
108
- # shell command to invoke the editor.
109
- # @example String
110
- # Pry.editor = "emacsclient"
111
- # @example Callable
112
- # Pry.editor = proc { |file, line| "emacsclient #{file} +#{line}" }
113
- # @return [String, #call]
114
- attr_accessor :editor
68
+ # plugin forwardables
69
+ def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
70
+
71
+ delegate_accessors :@config, :input, :output, :commands, :prompt, :print, :exception_handler,
72
+ :hooks, :color, :pager, :editor
115
73
  end
116
74
 
117
75
  # Load the rc files given in the `Pry::RC_FILES` array.
@@ -133,9 +91,15 @@ class Pry
133
91
  # @example
134
92
  # Pry.start(Object.new, :input => MyInput.new)
135
93
  def self.start(target=TOPLEVEL_BINDING, options={})
136
- if should_load_rc && !@rc_loaded
137
- load_rc
138
- @rc_loaded = true
94
+ if initial_session?
95
+ # note these have to be loaded here rather than in pry_instance as
96
+ # we only want them loaded once per entire Pry lifetime, not
97
+ # multiple times per each new session (i.e in debugging)
98
+ load_rc if Pry.config.should_load_rc
99
+ load_plugins if Pry.config.plugins.enabled
100
+ load_history if Pry.config.history.load
101
+
102
+ @initial_session = false
139
103
  end
140
104
 
141
105
  new(options).repl(target)
@@ -146,12 +110,7 @@ class Pry
146
110
  # @param obj The object to view.
147
111
  # @return [String] The string representation of `obj`.
148
112
  def self.view(obj)
149
- case obj
150
- when String, Hash, Array, Symbol, Exception, nil
151
- obj.inspect
152
- else
153
- obj.to_s
154
- end
113
+ obj.inspect
155
114
 
156
115
  rescue NoMethodError
157
116
  "unknown"
@@ -170,10 +129,20 @@ class Pry
170
129
  end
171
130
  end
172
131
 
132
+ # Load Readline history if required.
133
+ def self.load_history
134
+ history_file = File.expand_path(Pry.config.history.file)
135
+ Readline::HISTORY.push(*File.readlines(history_file).map(&:chomp)) if File.exists?(history_file)
136
+ end
137
+
138
+ # @return [Boolean] Whether this is the first time a Pry session has
139
+ # been started since loading the Pry class.
140
+ def self.initial_session?
141
+ @initial_session
142
+ end
143
+
173
144
  # Run a Pry command from outside a session. The commands available are
174
145
  # those referenced by `Pry.commands` (the default command set).
175
- # Command output is suppresed by default, this is because the return
176
- # value (if there is one) is likely to be more useful.
177
146
  # @param [String] arg_string The Pry command (including arguments,
178
147
  # if any).
179
148
  # @param [Hash] options Optional named parameters.
@@ -181,35 +150,24 @@ class Pry
181
150
  # @option options [Object, Binding] :context The object context to run the
182
151
  # command under. Defaults to `TOPLEVEL_BINDING` (main).
183
152
  # @option options [Boolean] :show_output Whether to show command
184
- # output. Defaults to false.
153
+ # output. Defaults to true.
185
154
  # @example Run at top-level with no output.
186
155
  # Pry.run_command "ls"
187
156
  # @example Run under Pry class, returning only public methods.
188
157
  # Pry.run_command "ls -m", :context => Pry
189
158
  # @example Display command output.
190
159
  # Pry.run_command "ls -av", :show_output => true
191
- def self.run_command(arg_string, options={})
192
- name, arg_string = arg_string.split(/\s+/, 2)
193
- arg_string = "" if !arg_string
194
-
160
+ def self.run_command(command_string, options={})
195
161
  options = {
196
162
  :context => TOPLEVEL_BINDING,
197
- :show_output => false,
163
+ :show_output => true,
198
164
  :output => Pry.output,
199
165
  :commands => Pry.commands
200
166
  }.merge!(options)
201
167
 
202
- null_output = StringIO.new
168
+ output = options[:show_output] ? options[:output] : StringIO.new
203
169
 
204
- context = CommandContext.new
205
- commands = options[:commands]
206
-
207
- context.opts = {}
208
- context.output = options[:show_output] ? options[:output] : null_output
209
- context.target = Pry.binding_for(options[:context])
210
- context.command_set = commands
211
-
212
- commands.run_command(context, name, *Shellwords.shellwords(arg_string))
170
+ Pry.new(:output => output, :input => StringIO.new(command_string), :commands => options[:commands]).rep(options[:context])
213
171
  end
214
172
 
215
173
  def self.default_editor_for_platform
@@ -220,25 +178,50 @@ class Pry
220
178
  end
221
179
  end
222
180
 
181
+ def self.set_config_defaults
182
+ config.input = Readline
183
+ config.output = $stdout
184
+ config.commands = Pry::Commands
185
+ config.prompt = DEFAULT_PROMPT
186
+ config.print = DEFAULT_PRINT
187
+ config.exception_handler = DEFAULT_EXCEPTION_HANDLER
188
+ config.hooks = DEFAULT_HOOKS
189
+ config.color = true
190
+ config.pager = true
191
+ config.editor = default_editor_for_platform
192
+ config.should_load_rc = true
193
+
194
+ config.plugins ||= OpenStruct.new
195
+ config.plugins.enabled = true
196
+ config.plugins.strict_loading = true
197
+
198
+ config.history ||= OpenStruct.new
199
+ config.history.save = true
200
+ config.history.load = true
201
+ config.history.file = File.expand_path("~/.pry_history")
202
+ end
203
+
223
204
  # Set all the configurable options back to their default values
224
205
  def self.reset_defaults
225
- @input = Readline
226
- @output = $stdout
227
- @commands = Pry::Commands
228
- @prompt = DEFAULT_PROMPT
229
- @print = DEFAULT_PRINT
230
- @exception_handler = DEFAULT_EXCEPTION_HANDLER
231
- @hooks = DEFAULT_HOOKS
232
- @custom_completions = DEFAULT_CUSTOM_COMPLETIONS
233
- @color = true
234
- @pager = true
235
- @should_load_rc = true
236
- @rc_loaded = false
237
- @cli = false
238
- @editor = default_editor_for_platform
206
+ set_config_defaults
207
+
208
+ @initial_session = true
209
+
210
+ self.custom_completions = DEFAULT_CUSTOM_COMPLETIONS
211
+ self.cli = false
212
+ self.current_line = 0
213
+ self.line_buffer = []
214
+ self.eval_path = "(pry)"
239
215
  end
240
216
 
241
- self.reset_defaults
217
+ # Basic initialization.
218
+ def self.init
219
+ @plugin_manager ||= PluginManager.new
220
+
221
+ self.config ||= Config.new
222
+ reset_defaults
223
+ locate_plugins
224
+ end
242
225
 
243
226
  @nesting = []
244
227
  def @nesting.level
@@ -269,3 +252,5 @@ class Pry
269
252
  end
270
253
  end
271
254
  end
255
+
256
+ Pry.init