pry 0.8.4pre1-java → 0.9.0pre1-java

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 (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