pry 0.8.0pre9 → 0.8.0

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'
@@ -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,61 +9,46 @@ 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|
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
+ )
57
46
 
58
- # save the context name
59
- options[:context_string] = context
60
- end
61
-
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
@@ -76,14 +61,14 @@ class Pry::Commands
76
61
  end
77
62
 
78
63
  # load ~/.pryrc, if not suppressed with -f option
79
- Pry.should_load_rc = false if !options[:loadrc]
64
+ Pry.should_load_rc = !opts.f?
80
65
 
81
66
  # create the actual context
82
- context = Pry.binding_for(eval(options[:context_string]))
67
+ context = Pry.binding_for(eval(opts[:context]))
83
68
 
84
69
  # run code passed with `-e`, if there is any.
85
- if options[:code]
86
- 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)
87
72
  end
88
73
 
89
74
  # start the session
data/lib/pry.rb CHANGED
@@ -15,7 +15,7 @@ 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
@@ -31,3 +31,9 @@ require "#{direc}/pry/completion"
31
31
  require "#{direc}/pry/core_extensions"
32
32
  require "#{direc}/pry/pry_class"
33
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,4 +1,5 @@
1
1
  direc = File.dirname(__FILE__)
2
+ require 'rubygems/dependency_installer'
2
3
  require "#{direc}/command_base_helpers"
3
4
 
4
5
  class Pry
@@ -8,7 +9,7 @@ class Pry
8
9
  class CommandBase
9
10
  class << self
10
11
  include CommandBaseHelpers
11
-
12
+
12
13
  attr_accessor :commands
13
14
  attr_accessor :opts, :output, :target
14
15
 
@@ -16,7 +17,7 @@ class Pry
16
17
  # that the location where the block is defined has the `opts`
17
18
  # method in scope.
18
19
  private
19
-
20
+
20
21
  # Defines a new Pry command.
21
22
  # @param [String, Array] names The name of the command (or array of
22
23
  # command name aliases).
@@ -47,7 +48,7 @@ class Pry
47
48
  :keep_retval => false,
48
49
  :requires_gem => nil
49
50
  }.merge!(options)
50
-
51
+
51
52
  @commands ||= {}
52
53
 
53
54
  if command_dependencies_met?(options)
@@ -78,23 +79,23 @@ class Pry
78
79
  end
79
80
 
80
81
  # Execute a command (this enables commands to call other commands).
81
- # @param [Binding] target The current target object.
82
82
  # @param [String] name The command to execute
83
83
  # @param [Array] args The parameters to pass to the command.
84
84
  # @example Wrap one command with another
85
85
  # class MyCommands < Pry::Commands
86
86
  # command "ls2" do
87
87
  # output.puts "before ls"
88
- # run target, "ls"
88
+ # run "ls"
89
89
  # output.puts "after ls"
90
90
  # end
91
91
  # end
92
- def run(target, name, *args)
92
+ def run(name, *args)
93
93
  command_processor = CommandProcessor.new(target.eval('_pry_'))
94
-
94
+
95
95
  if command_processor.system_command?(name)
96
- command_processor.execute_system_command("#{name} #{args.join}", target)
96
+ command_processor.execute_system_command("#{name} #{args.join(' ')}", target)
97
97
  else
98
+ raise "#{name.inspect} is not a valid pry command." unless opts[:commands].include? name
98
99
  action = opts[:commands][name][:action]
99
100
  instance_exec(*args, &action)
100
101
  end
@@ -138,13 +139,13 @@ class Pry
138
139
  commands[name][:description] = description
139
140
  end
140
141
  end
141
-
142
+
142
143
  command "help", "This menu." do |cmd|
143
144
  command_info = opts[:commands]
144
145
 
145
146
  if !cmd
146
147
  output.puts
147
- help_text = heading("Command List:") + "\n"
148
+ help_text = heading("Command List:") + "\n"
148
149
  command_info.each do |k, data|
149
150
  if !data[:stub_info]
150
151
  help_text << ("#{k}".ljust(18) + data[:description] + "\n") if !data[:description].empty?
@@ -171,8 +172,6 @@ class Pry
171
172
  end
172
173
 
173
174
  output.puts "Attempting to install `#{name}` command..."
174
-
175
- require 'rubygems/dependency_installer'
176
175
  gems_to_install = Array(stub_info[:requires_gem])
177
176
 
178
177
  gem_install_failed = false
@@ -181,7 +180,7 @@ class Pry
181
180
  output.puts "Installing `#{g}` gem..."
182
181
 
183
182
  begin
184
- Gem::DependencyInstaller.new.install(g)
183
+ Gem::DependencyInstaller.new.install(g)
185
184
  rescue Gem::GemNotFoundException
186
185
  output.puts "Required Gem: `#{g}` not found. Aborting command installation."
187
186
  gem_install_failed = true
@@ -189,7 +188,7 @@ class Pry
189
188
  end
190
189
  end
191
190
  next if gem_install_failed
192
-
191
+
193
192
  Gem.refresh
194
193
  load "#{File.dirname(__FILE__)}/commands.rb"
195
194
  output.puts "Installation of `#{name}` successful! Type `help #{name}` for information"
@@ -199,6 +198,6 @@ class Pry
199
198
  def self.inherited(klass)
200
199
  klass.commands = commands.dup
201
200
  end
202
-
201
+
203
202
  end
204
203
  end
@@ -2,9 +2,9 @@ class Pry
2
2
  class CommandBase
3
3
  module CommandBaseHelpers
4
4
 
5
- private
6
-
7
- def gem_installed?(gem_name)
5
+ private
6
+
7
+ def gem_installed?(gem_name)
8
8
  require 'rubygems'
9
9
  !!Gem.source_index.find_name(gem_name).first
10
10
  end
@@ -36,10 +36,107 @@ class Pry
36
36
  end
37
37
  end
38
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
+
39
83
  def bold(text)
40
84
  Pry.color ? "\e[1m#{text}\e[0m" : text
41
85
  end
42
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
+
43
140
  # formatting
44
141
  def heading(text)
45
142
  text = "#{text}\n--"
@@ -49,7 +146,7 @@ class Pry
49
146
  def page_size
50
147
  27
51
148
  end
52
-
149
+
53
150
  # a simple pager for systems without `less`. A la windows.
54
151
  def simple_pager(text)
55
152
  text_array = text.lines.to_a
@@ -57,33 +154,67 @@ class Pry
57
154
  output.puts chunk.join
58
155
  break if chunk.size < page_size
59
156
  if text_array.size > page_size
60
- output.puts "\n<page break> --- Press enter to continue ( q<enter> to break ) --- <page break>"
157
+ output.puts "\n<page break> --- Press enter to continue ( q<enter> to break ) --- <page break>"
61
158
  break if $stdin.gets.chomp == "q"
62
159
  end
63
160
  end
64
161
  end
65
-
66
- # Try to use `less` for paging, if it fails then use simple_pager
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
67
166
  def stagger_output(text)
68
- if text.lines.count < page_size
167
+ if text.lines.count < page_size || !Pry.pager
69
168
  output.puts text
70
169
  return
71
170
  end
72
- lesspipe { |less| less.puts text }
73
- rescue Exception
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
74
179
  simple_pager(text)
180
+ rescue Errno::EPIPE
75
181
  end
76
182
 
77
- # thanks to epitron for this method
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
+ #
78
209
  def lesspipe(*args)
79
210
  if args.any? and args.last.is_a?(Hash)
80
211
  options = args.pop
81
212
  else
82
213
  options = {}
83
214
  end
84
-
215
+
85
216
  output = args.first if args.any?
86
-
217
+
87
218
  params = []
88
219
  params << "-R" unless options[:color] == false
89
220
  params << "-S" unless options[:wrap] == true
@@ -93,7 +224,7 @@ class Pry
93
224
  $stderr.puts "Seeking to end of stream..."
94
225
  end
95
226
  params << "-X"
96
-
227
+
97
228
  IO.popen("less #{params * ' '}", "w") do |less|
98
229
  if output
99
230
  less.puts output
@@ -101,10 +232,10 @@ class Pry
101
232
  yield less
102
233
  end
103
234
  end
104
- end
235
+ end
105
236
 
106
237
  end
107
238
  end
108
239
  end
109
240
 
110
-
241
+