pry 0.7.7.2-java → 0.8.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -21,6 +21,7 @@ def apply_spec_defaults(s)
21
21
  s.require_path = 'lib'
22
22
  s.add_dependency("ruby_parser",">=2.0.5")
23
23
  s.add_dependency("coderay",">=0.9.7")
24
+ s.add_dependency("slop",">=1.5.2")
24
25
  s.add_development_dependency("bacon",">=1.1.0")
25
26
  s.homepage = "http://banisterfiend.wordpress.com"
26
27
  s.has_rdoc = 'yard'
@@ -30,13 +31,13 @@ def apply_spec_defaults(s)
30
31
  end
31
32
 
32
33
  task :test do
33
- sh "bacon -k #{direc}/test/test.rb"
34
+ sh "bacon #{direc}/test/test.rb"
34
35
  end
35
36
 
36
37
  desc "run pry"
37
38
  task :pry do
38
- require "#{direc}/lib/pry.rb"
39
- Pry.start
39
+ require "#{direc}/lib/pry"
40
+ binding.pry
40
41
  end
41
42
 
42
43
  desc "show pry version"
@@ -76,7 +77,7 @@ end
76
77
  namespace :jruby do
77
78
  spec = Gem::Specification.new do |s|
78
79
  apply_spec_defaults(s)
79
- s.add_dependency("method_source","=0.2.0")
80
+ s.add_dependency("method_source",">=0.4.0")
80
81
  s.platform = "java"
81
82
  end
82
83
 
data/bin/pry CHANGED
@@ -9,74 +9,66 @@ rescue LoadError
9
9
  require 'rubygems'
10
10
  require 'pry'
11
11
  end
12
- require 'optparse'
13
12
 
14
- # defaults
15
- options = {
16
- :context_string => "TOPLEVEL_BINDING",
17
- :loadrc => true
18
- }
19
-
20
- OptionParser.new do |opts|
21
- opts.banner = %{Usage: pry [OPTIONS]
13
+ opts = Slop.parse do
14
+ banner %{Usage: pry [OPTIONS]
22
15
  Start a Pry session.
23
16
  See: `https://github.com/banister` for more information.
24
17
  --
25
18
  }
26
- opts.on("-r", "--require FILE", "`require` a Ruby script at startup.") do |file|
27
- require file
28
- end
29
19
 
30
- opts.on("-e", "--exec CODE", "A line of Ruby code to execute in context before the session starts.") do |code|
31
- options[:code] = code
32
- end
33
-
34
- opts.on("-f", "Suppress loading of ~/.pryrc") do
35
- options[:loadrc] = false
36
- end
20
+ on :e, :exec, "A line of code to execute in context before the session starts", true
21
+ on :f, "Surpress loading of ~/.pryrc"
22
+ on "no-color", "Disable syntax highlighting for session"
37
23
 
38
- opts.on("--no-color", "Start session without syntax highlighting.") do
39
- Pry.color = false
24
+ on "simple-prompt", "Enable simple prompt mode" do
25
+ Pry.prompt = Pry::SIMPLE_PROMPT
40
26
  end
41
27
 
42
- opts.on("--simple-prompt", "Simple prompt mode.") do
43
- Pry.prompt = Pry::SIMPLE_PROMPT
28
+ on :r, :require, "`require` a Ruby script at startup", true do |file|
29
+ require file
44
30
  end
45
31
 
46
- opts.on("-I LOADPATH", "Specify $LOAD_PATH directory.") do |load_path|
47
- $LOAD_PATH << load_path
32
+ on :I, "Add a path to the $LOAD_PATH", true do |path|
33
+ $LOAD_PATH << path
48
34
  end
49
35
 
50
- opts.on("-v", "--version", "Display the Pry version.") do
36
+ on :v, :version, "Display the Pry version" do
51
37
  puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}"
52
38
  exit
53
39
  end
54
40
 
55
- opts.on("-c", "--context CONTEXT",
56
- "Start the session in the specified context. Equivalent to `context.pry` in a session.") do |context|
57
-
58
- # save the context name
59
- options[:context_string] = context
60
- end
41
+ on(:c, :context,
42
+ "Start the session in the specified context. Equivalent to `context.pry` in a session.",
43
+ true,
44
+ :default => "TOPLEVEL_BINDING"
45
+ )
61
46
 
62
- opts.on_tail("-h", "--help", "This message.") do
63
- puts opts
47
+ on :h, :help, "This message" do
48
+ puts help
64
49
  exit
65
50
  end
66
- end.parse!
51
+ end
67
52
 
68
53
  # invoked via cli
69
54
  Pry.cli = true
70
55
 
56
+ class Pry::Commands
57
+ command "reset", "Reset the REPL to a clean state." do
58
+ output.puts "Pry reset."
59
+ exec("pry")
60
+ end
61
+ end
62
+
71
63
  # load ~/.pryrc, if not suppressed with -f option
72
- Pry.should_load_rc = false if !options[:loadrc]
64
+ Pry.should_load_rc = !opts.f?
73
65
 
74
66
  # create the actual context
75
- context = Pry.binding_for(eval(options[:context_string]))
67
+ context = Pry.binding_for(eval(opts[:context]))
76
68
 
77
69
  # run code passed with `-e`, if there is any.
78
- if options[:code]
79
- Pry.new(:input => StringIO.new(options[:code]), :print => proc {}).rep(context)
70
+ if opts.exec?
71
+ Pry.new(:input => StringIO.new(opts[:exec]), :print => proc {}).rep(context)
80
72
  end
81
73
 
82
74
  # start the session
data/lib/pry.rb CHANGED
@@ -15,18 +15,25 @@ if RUBY_PLATFORM =~ /mswin/ || RUBY_PLATFORM =~ /mingw/
15
15
  begin
16
16
  require 'win32console'
17
17
  rescue LoadError
18
- $stderr.puts "Need to `gem install win32console`"
18
+ $stderr.puts "Need to `gem install win32console`"
19
19
  exit 1
20
20
  end
21
21
  end
22
22
 
23
- require "pry/version"
24
- require "pry/hooks"
25
- require "pry/print"
26
- require "pry/command_base"
27
- require "pry/commands"
28
- require "pry/prompts"
29
- require "pry/completion"
30
- require "pry/core_extensions"
31
- require "pry/pry_class"
32
- require "pry/pry_instance"
23
+ require "#{direc}/pry/version"
24
+ require "#{direc}/pry/hooks"
25
+ require "#{direc}/pry/print"
26
+ require "#{direc}/pry/command_base"
27
+ require "#{direc}/pry/commands"
28
+ require "#{direc}/pry/prompts"
29
+ require "#{direc}/pry/custom_completions"
30
+ require "#{direc}/pry/completion"
31
+ require "#{direc}/pry/core_extensions"
32
+ require "#{direc}/pry/pry_class"
33
+ require "#{direc}/pry/pry_instance"
34
+
35
+
36
+ # TEMPORARY HACK FOR BUG IN JRUBY 1.9 REGEX (which kills CodeRay)
37
+ if RUBY_VERSION =~ /1.9/ && RUBY_ENGINE =~ /jruby/
38
+ Pry.color = false
39
+ end
@@ -1,9 +1,15 @@
1
+ direc = File.dirname(__FILE__)
2
+ require 'rubygems/dependency_installer'
3
+ require "#{direc}/command_base_helpers"
4
+
1
5
  class Pry
2
6
 
3
7
  # Basic command functionality. All user-defined commands must
4
8
  # inherit from this class. It provides the `command` method.
5
9
  class CommandBase
6
10
  class << self
11
+ include CommandBaseHelpers
12
+
7
13
  attr_accessor :commands
8
14
  attr_accessor :opts, :output, :target
9
15
 
@@ -11,7 +17,7 @@ class Pry
11
17
  # that the location where the block is defined has the `opts`
12
18
  # method in scope.
13
19
  private
14
-
20
+
15
21
  # Defines a new Pry command.
16
22
  # @param [String, Array] names The name of the command (or array of
17
23
  # command name aliases).
@@ -39,17 +45,22 @@ class Pry
39
45
  # # Greet somebody
40
46
  def command(names, description="No description.", options={}, &block)
41
47
  options = {
42
- :keep_retval => false
48
+ :keep_retval => false,
49
+ :requires_gem => nil
43
50
  }.merge!(options)
44
-
51
+
45
52
  @commands ||= {}
46
53
 
47
- Array(names).each do |name|
48
- commands[name] = {
49
- :description => description,
50
- :action => block,
51
- :keep_retval => options[:keep_retval]
52
- }
54
+ if command_dependencies_met?(options)
55
+ Array(names).each do |name|
56
+ commands[name] = {
57
+ :description => description,
58
+ :action => block,
59
+ :keep_retval => options[:keep_retval]
60
+ }
61
+ end
62
+ else
63
+ create_command_stub(names, description, options, block)
53
64
  end
54
65
  end
55
66
 
@@ -79,8 +90,15 @@ class Pry
79
90
  # end
80
91
  # end
81
92
  def run(name, *args)
82
- action = opts[:commands][name][:action]
83
- instance_exec(*args, &action)
93
+ command_processor = CommandProcessor.new(target.eval('_pry_'))
94
+
95
+ if command_processor.system_command?(name)
96
+ command_processor.execute_system_command("#{name} #{args.join(' ')}", target)
97
+ else
98
+ raise "#{name.inspect} is not a valid pry command." unless opts[:commands].include? name
99
+ action = opts[:commands][name][:action]
100
+ instance_exec(*args, &action)
101
+ end
84
102
  end
85
103
 
86
104
  # Import commands from another command object.
@@ -121,30 +139,65 @@ class Pry
121
139
  commands[name][:description] = description
122
140
  end
123
141
  end
124
-
142
+
125
143
  command "help", "This menu." do |cmd|
126
144
  command_info = opts[:commands]
127
- param = cmd
128
145
 
129
- if !param
130
- output.puts "Command list:"
131
- output.puts "--"
146
+ if !cmd
147
+ output.puts
148
+ help_text = heading("Command List:") + "\n"
132
149
  command_info.each do |k, data|
133
- output.puts "#{k}".ljust(18) + data[:description] if !data[:description].empty?
150
+ if !data[:stub_info]
151
+ help_text << ("#{k}".ljust(18) + data[:description] + "\n") if !data[:description].empty?
152
+ else
153
+ help_text << (bold("#{k}".ljust(18) + data[:description] + "\n")) if !data[:description].empty?
154
+ end
134
155
  end
156
+ stagger_output(help_text)
135
157
  else
136
- if command_info[param]
137
- output.puts command_info[param][:description]
158
+ if command_info[cmd]
159
+ output.puts command_info[cmd][:description]
138
160
  else
139
- output.puts "No info for command: #{param}"
161
+ output.puts "No info for command: #{cmd}"
162
+ end
163
+ end
164
+ end
165
+
166
+ command "install", "Install a disabled command." do |name|
167
+ stub_info = commands[name][:stub_info]
168
+
169
+ if !stub_info
170
+ output.puts "Not a command stub. Nothing to do."
171
+ next
172
+ end
173
+
174
+ output.puts "Attempting to install `#{name}` command..."
175
+ gems_to_install = Array(stub_info[:requires_gem])
176
+
177
+ gem_install_failed = false
178
+ gems_to_install.each do |g|
179
+ next if gem_installed?(g)
180
+ output.puts "Installing `#{g}` gem..."
181
+
182
+ begin
183
+ Gem::DependencyInstaller.new.install(g)
184
+ rescue Gem::GemNotFoundException
185
+ output.puts "Required Gem: `#{g}` not found. Aborting command installation."
186
+ gem_install_failed = true
187
+ next
140
188
  end
141
189
  end
190
+ next if gem_install_failed
191
+
192
+ Gem.refresh
193
+ load "#{File.dirname(__FILE__)}/commands.rb"
194
+ output.puts "Installation of `#{name}` successful! Type `help #{name}` for information"
142
195
  end
143
196
 
144
197
  # Ensures that commands can be inherited
145
198
  def self.inherited(klass)
146
199
  klass.commands = commands.dup
147
200
  end
148
-
201
+
149
202
  end
150
203
  end
@@ -0,0 +1,241 @@
1
+ class Pry
2
+ class CommandBase
3
+ module CommandBaseHelpers
4
+
5
+ private
6
+
7
+ def gem_installed?(gem_name)
8
+ require 'rubygems'
9
+ !!Gem.source_index.find_name(gem_name).first
10
+ end
11
+
12
+ def command_dependencies_met?(options)
13
+ return true if !options[:requires_gem]
14
+ Array(options[:requires_gem]).all? do |g|
15
+ gem_installed?(g)
16
+ end
17
+ end
18
+
19
+ def stub_proc(name, options)
20
+ gems_needed = Array(options[:requires_gem])
21
+ gems_not_installed = gems_needed.select { |g| !gem_installed?(g) }
22
+ proc do
23
+ output.puts "\n`#{name}` requires the following gems to be installed: `#{gems_needed.join(", ")}`"
24
+ output.puts "Command not available due to dependency on gems: `#{gems_not_installed.join(", ")}` not being met."
25
+ output.puts "Type `install #{name}` to install the required gems and activate this command."
26
+ end
27
+ end
28
+
29
+ def create_command_stub(names, description, options, block)
30
+ Array(names).each do |name|
31
+ commands[name] = {
32
+ :description => "Not available. Execute `#{name}` command for more information.",
33
+ :action => stub_proc(name, options),
34
+ :stub_info => options
35
+ }
36
+ end
37
+ end
38
+
39
+ #
40
+ # Color helpers:
41
+ # gray, red, green, yellow, blue, purple, cyan, white,
42
+ # and bright_red, bright_green, etc...
43
+ #
44
+ # ANSI color codes:
45
+ # \033 => escape
46
+ # 30 => color base
47
+ # 1 => bright
48
+ # 0 => normal
49
+ #
50
+
51
+ COLORS = {
52
+ "black" => 0,
53
+ "red" => 1,
54
+ "green" => 2,
55
+ "yellow" => 3,
56
+ "blue" => 4,
57
+ "purple" => 5,
58
+ "magenta" => 5,
59
+ "cyan" => 6,
60
+ "white" => 7
61
+ }
62
+
63
+ COLORS.each do |color, i|
64
+ define_method color do |str|
65
+ Pry.color ? "\033[0;#{30+i}m#{str}\033[0m" : str
66
+ end
67
+
68
+ define_method "bright_#{color}" do |str|
69
+ Pry.color ? "\033[1;#{30+i}m#{str}\033[0m" : str
70
+ end
71
+ end
72
+
73
+ alias_method :grey, :bright_black
74
+ alias_method :gray, :bright_black
75
+
76
+ require 'set'
77
+ VALID_COLORS = Set.new(
78
+ COLORS.keys +
79
+ COLORS.keys.map{|k| "bright_#{k}" } +
80
+ ["grey", "gray"]
81
+ )
82
+
83
+ def bold(text)
84
+ Pry.color ? "\e[1m#{text}\e[0m" : text
85
+ end
86
+
87
+ #
88
+ # Colorize a string that has "color tags".
89
+ #
90
+ # Examples:
91
+ # puts colorize("<light_green><magenta>*</magenta> Hey mom! I am <light_blue>SO</light_blue> colored right now.</light_green>")
92
+ #
93
+ def colorize(string)
94
+ stack = []
95
+
96
+ # split the string into tags and literal strings
97
+ tokens = string.split(/(<\/?[\w\d_]+>)/)
98
+ tokens.delete_if { |token| token.size == 0 }
99
+
100
+ result = ""
101
+
102
+ tokens.each do |token|
103
+
104
+ # token is an opening tag!
105
+
106
+ if /<([\w\d_]+)>/ =~ token and VALID_COLORS.include?($1) #valid_tag?($1)
107
+ stack.push $1
108
+
109
+ # token is a closing tag!
110
+
111
+ elsif /<\/([\w\d_]+)>/ =~ token and VALID_COLORS.include?($1) # valid_tag?($1)
112
+
113
+ # if this color is on the stack somwehere...
114
+ if pos = stack.rindex($1)
115
+ # close the tag by removing it from the stack
116
+ stack.delete_at pos
117
+ else
118
+ raise "Error: tried to close an unopened color tag -- #{token}"
119
+ end
120
+
121
+ # token is a literal string!
122
+
123
+ else
124
+
125
+ color = (stack.last || "white")
126
+ #color = BBS_COLOR_TABLE[color.to_i] if color =~ /^\d+$/
127
+ result << send(color, token) # colorize the result
128
+
129
+ end
130
+
131
+ end
132
+
133
+ result
134
+ end
135
+
136
+ def highlight(string, regexp, highlight_color=:bright_yellow)
137
+ highlighted = string.gsub(regexp) { |match| "<#{highlight_color}>#{match}</#{highlight_color}>" }
138
+ end
139
+
140
+ # formatting
141
+ def heading(text)
142
+ text = "#{text}\n--"
143
+ Pry.color ? "\e[1m#{text}\e[0m": text
144
+ end
145
+
146
+ def page_size
147
+ 27
148
+ end
149
+
150
+ # a simple pager for systems without `less`. A la windows.
151
+ def simple_pager(text)
152
+ text_array = text.lines.to_a
153
+ text_array.each_slice(page_size) do |chunk|
154
+ output.puts chunk.join
155
+ break if chunk.size < page_size
156
+ if text_array.size > page_size
157
+ output.puts "\n<page break> --- Press enter to continue ( q<enter> to break ) --- <page break>"
158
+ break if $stdin.gets.chomp == "q"
159
+ end
160
+ end
161
+ end
162
+
163
+ # Try to use `less` for paging, if it fails then use
164
+ # simple_pager. Also do not page if Pry.pager is falsey
165
+ # FIXME! Another JRuby hack
166
+ def stagger_output(text)
167
+ if text.lines.count < page_size || !Pry.pager
168
+ output.puts text
169
+ return
170
+ end
171
+
172
+ # FIXME! Another JRuby hack
173
+ if Object.const_defined?(:RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/
174
+ simple_pager(text)
175
+ else
176
+ lesspipe { |less| less.puts text }
177
+ end
178
+ rescue Errno::ENOENT
179
+ simple_pager(text)
180
+ rescue Errno::EPIPE
181
+ end
182
+
183
+ #
184
+ # Create scrollable output via less!
185
+ #
186
+ # This command runs `less` in a subprocess, and gives you the IO to its STDIN pipe
187
+ # so that you can communicate with it.
188
+ #
189
+ # Example:
190
+ #
191
+ # lesspipe do |less|
192
+ # 50.times { less.puts "Hi mom!" }
193
+ # end
194
+ #
195
+ # The default less parameters are:
196
+ # * Allow colour
197
+ # * Don't wrap lines longer than the screen
198
+ # * Quit immediately (without paging) if there's less than one screen of text.
199
+ #
200
+ # You can change these options by passing a hash to `lesspipe`, like so:
201
+ #
202
+ # lesspipe(:wrap=>false) { |less| less.puts essay.to_s }
203
+ #
204
+ # It accepts the following boolean options:
205
+ # :color => Allow ANSI colour codes?
206
+ # :wrap => Wrap long lines?
207
+ # :always => Always page, even if there's less than one page of text?
208
+ #
209
+ def lesspipe(*args)
210
+ if args.any? and args.last.is_a?(Hash)
211
+ options = args.pop
212
+ else
213
+ options = {}
214
+ end
215
+
216
+ output = args.first if args.any?
217
+
218
+ params = []
219
+ params << "-R" unless options[:color] == false
220
+ params << "-S" unless options[:wrap] == true
221
+ params << "-F" unless options[:always] == true
222
+ if options[:tail] == true
223
+ params << "+\\>"
224
+ $stderr.puts "Seeking to end of stream..."
225
+ end
226
+ params << "-X"
227
+
228
+ IO.popen("less #{params * ' '}", "w") do |less|
229
+ if output
230
+ less.puts output
231
+ else
232
+ yield less
233
+ end
234
+ end
235
+ end
236
+
237
+ end
238
+ end
239
+ end
240
+
241
+