mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Merge branch 'master' into FixCommandPrefix
This commit is contained in:
commit
80e3881c67
82 changed files with 2411 additions and 2194 deletions
10
.travis.yml
10
.travis.yml
|
@ -1,15 +1,17 @@
|
|||
rvm:
|
||||
- 1.8.7
|
||||
- 1.9.2
|
||||
- 1.9.3
|
||||
- 2.0.0
|
||||
- 2.1.0
|
||||
- ruby-head
|
||||
- ree
|
||||
- rbx
|
||||
- jruby-18mode
|
||||
- jruby-19mode
|
||||
- jruby
|
||||
- jruby-head
|
||||
|
||||
script:
|
||||
- rake spec
|
||||
- bundle exec bacon spec/isolation/readline_spec.rb
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
|
|
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -1,8 +1,11 @@
|
|||
### 1.0.0 (2013/??/??)
|
||||
#### Dependency changes
|
||||
|
||||
* 1.8 support discontinued from 0.10/1.0 up. 0.9 branch continues 1.8 support.
|
||||
* Require Coderay `>= 1.1.0`
|
||||
|
||||
#### Features
|
||||
* Added a `watch` command that lets you see how values change over time.
|
||||
* Added an experimental `Pry.auto_resize!` method
|
||||
* Makes Pry notice that your window has resized and tell Readline about it
|
||||
* Fixes various bugs with command history after a window resize
|
||||
|
@ -17,8 +20,12 @@
|
|||
* User can whitelist objects whose inspect output should appear in prompt (#885)
|
||||
* See `Pry.config.prompt_safe_objects`
|
||||
* `whereami` is now aliased to `@`
|
||||
* default configuration(Pry.config) lazy loads its values. (#1096)
|
||||
* require of 'readline' is delayed until Pry.start() has been called for the first time. (#1117)
|
||||
* add option to disable input completer through `_pry_.config.completer = nil`
|
||||
|
||||
#### Bug fixes, etc.
|
||||
* `binding.pry` inside `.pryrc` file now works, with some limitations (@richo / #1118)
|
||||
* Add support for BasicObjects to `ls` (#984)
|
||||
* Allow `ls -c <anything>` (#891)
|
||||
* Fix indentation not working if the `mathn` stdlib was loaded (#872)
|
||||
|
@ -36,8 +43,16 @@
|
|||
being inferred from context (#877)
|
||||
* Rename `--installed-plugins` flag to `--plugins`
|
||||
* Strip ANSI codes from prompt before measuring length for indentation (#493)
|
||||
* Fix bug in `edit` regarding recognition of file names without suffix.
|
||||
|
||||
#### Dev-facing changes
|
||||
* CommandSet#commands, sometimes referenced through Pry.commands.commands, renamed as 'CommandSet#to_hash'.
|
||||
it returns a duplicate of the internal hash a CommandSet uses.
|
||||
* CommandSet#keys is now an alias of CommandSet#list_commands.
|
||||
* through changes to configuration, all commands should reference configuration values
|
||||
via `_pry_.config` and not `Pry.config`. (#1096)
|
||||
* improve configuration(Pry::Config) for easier support of concurrent environments
|
||||
through a 'pry-local' config who, at times, acts as a 'pry-local store'. (#1096)
|
||||
* `rake pry` now accepts switches prefixed with `_` (e.g., `rake pry _v`)
|
||||
* Pagers now act like `IO`s and accept streaming output
|
||||
* See `Pager.page` and `Pager.with_pager`
|
||||
|
@ -58,6 +73,15 @@
|
|||
methods of determining the terminal's dimensions
|
||||
* Add `ReplTester` class for high-level simulation of Pry sessions in tests
|
||||
|
||||
### 0.9.12.6 (2014/01/28)
|
||||
* Don't fail if Bond is not installed (#1106)
|
||||
|
||||
### 0.9.12.5 (2014/01/27)
|
||||
* Fix early readline errors by deferring require of readline (#1081, #1095)
|
||||
|
||||
### 0.9.12.4 (2013/11/23)
|
||||
* Fix issue with Coderay colors being black, even when on a black background (#1016)
|
||||
|
||||
### 0.9.12.3 (2013/09/11)
|
||||
* Bump Coderay dependency (#987)
|
||||
* Fix consecutive newlines in heredocs being collapsed (#962)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
372 Conrad Irwin
|
||||
215 Ryan Fitzgerald
|
||||
108 Kyrylo Silin
|
||||
yui-knk
|
||||
92 Rob Gleeson
|
||||
54 Mon ouïe
|
||||
51 Lee Jarvis
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -8,7 +8,7 @@ group :development do
|
|||
gem 'rb-fsevent', :require => 'false'
|
||||
end
|
||||
|
||||
if RbConfig::CONFIG['ruby_install_name'] == 'rbx'
|
||||
platform :rbx do
|
||||
gem 'rubysl-singleton'
|
||||
gem 'rubysl-prettyprint'
|
||||
gem 'rb-readline'
|
||||
|
|
|
@ -37,7 +37,6 @@ including:
|
|||
* Exotic object support (BasicObject instances, IClasses, ...)
|
||||
* A Powerful and flexible command system
|
||||
* Ability to view and replay history
|
||||
|
||||
* Many convenience commands inspired by IPython, Smalltalk and other advanced REPLs
|
||||
* A wide-range number of [plugins](https://github.com/pry/pry/wiki/Available-plugins) that provide remote sessions, full debugging functionality, and more.
|
||||
|
||||
|
@ -66,13 +65,6 @@ methods. The additional docs are accessed through the `show-doc` and
|
|||
* Read the [YARD API documentation](http://rdoc.info/github/pry/pry/master/file/README.markdown)
|
||||
* See the [source code](http://github.com/pry/pry)
|
||||
|
||||
Pry also has `rubygems-test` support; to participate, first install
|
||||
Pry, then:
|
||||
|
||||
1. Install rubygems-test: `gem install rubygems-test`
|
||||
2. Run the test: `gem test pry`
|
||||
3. Finally choose 'Yes' to upload the results.
|
||||
|
||||
### Commands
|
||||
|
||||
Nearly every piece of functionality in a Pry session is implemented as
|
||||
|
@ -103,9 +95,9 @@ an instance variable inside that class:
|
|||
pry(Hello):1> ls -i
|
||||
instance variables: @x
|
||||
pry(Hello):1> cd @x
|
||||
pry(20:2)> self + 10
|
||||
pry(20):2> self + 10
|
||||
=> 30
|
||||
pry(20:2)> cd ..
|
||||
pry(20):2> cd ..
|
||||
pry(Hello):1> cd ..
|
||||
pry(main)> cd ..
|
||||
|
||||
|
@ -113,7 +105,7 @@ The number after the `:` in the pry prompt indicates the nesting
|
|||
level. To display more information about nesting, use the `nesting`
|
||||
command. E.g
|
||||
|
||||
pry("friend":3)> nesting
|
||||
pry("friend"):3> nesting
|
||||
Nesting status:
|
||||
0. main (Pry top level)
|
||||
1. Hello
|
||||
|
@ -124,7 +116,7 @@ command. E.g
|
|||
We can then jump back to any of the previous nesting levels by using
|
||||
the `jump-to` command:
|
||||
|
||||
pry("friend":3)> jump-to 1
|
||||
pry("friend"):3> jump-to 1
|
||||
=> 100
|
||||
pry(Hello):1>
|
||||
|
||||
|
@ -225,7 +217,7 @@ In the following example we will enter the `Pry` class, list the
|
|||
instance methods beginning with 're' and display the source code for the `rep` method:
|
||||
|
||||
pry(main)> cd Pry
|
||||
pry(Pry)> ls -M --grep re
|
||||
pry(Pry):1> ls -M --grep re
|
||||
Pry#methods: re readline refresh rep repl repl_epilogue repl_prologue retrieve_line
|
||||
pry(Pry):1> show-method rep -l
|
||||
|
||||
|
@ -257,9 +249,9 @@ Note that we can also view C methods (from Ruby Core) using the
|
|||
RETURN_ENUMERATOR(ary, 0, 0);
|
||||
result = rb_ary_new2(RARRAY_LEN(ary));
|
||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
|
||||
rb_ary_push(result, rb_ary_elt(ary, i));
|
||||
}
|
||||
if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
|
||||
rb_ary_push(result, rb_ary_elt(ary, i));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
11
Rakefile
11
Rakefile
|
@ -21,15 +21,6 @@ end
|
|||
desc "Set up and run tests"
|
||||
task :default => [:test]
|
||||
|
||||
unless [].respond_to? :shuffle!
|
||||
class Array
|
||||
def shuffle!
|
||||
# TODO: fill this in if anyone cares
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_specs paths
|
||||
quiet = ENV['VERBOSE'] ? '' : '-q'
|
||||
exec "bacon -Ispec -rubygems #{quiet} #{paths.join ' '}"
|
||||
|
@ -42,7 +33,7 @@ task :test do
|
|||
if explicit_list = ENV['run']
|
||||
explicit_list.split(',')
|
||||
else
|
||||
Dir['spec/**/*_spec.rb'].shuffle!
|
||||
(Dir['spec/**/*_spec.rb'] - Dir["spec/isolation/*_spec.rb"]).shuffle!
|
||||
end
|
||||
run_specs paths
|
||||
end
|
||||
|
|
85
lib/pry.rb
85
lib/pry.rb
|
@ -12,7 +12,6 @@ require 'securerandom'
|
|||
require 'forwardable'
|
||||
|
||||
class Pry
|
||||
|
||||
# The default hooks - display messages when beginning and ending Pry sessions.
|
||||
DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session, :default) do |out, target, _pry_|
|
||||
next if _pry_.quiet?
|
||||
|
@ -20,9 +19,9 @@ class Pry
|
|||
end
|
||||
|
||||
# The default print
|
||||
DEFAULT_PRINT = proc do |output, value|
|
||||
DEFAULT_PRINT = proc do |output, value, _pry_|
|
||||
Pry::Pager.with_pager(output) do |pager|
|
||||
pager.print "=> "
|
||||
pager.print _pry_.config.output_prefix
|
||||
Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1)
|
||||
end
|
||||
end
|
||||
|
@ -103,7 +102,7 @@ class Pry
|
|||
else
|
||||
# Otherwise, saves current binding stack as old stack and pops last
|
||||
# binding out of binding stack (the old stack still has that binding).
|
||||
_pry_.command_state["cd"] ||= OpenStruct.new # FIXME
|
||||
_pry_.command_state["cd"] ||= Pry::Config.from_hash({}) # FIXME
|
||||
_pry_.command_state['cd'].old_stack = _pry_.binding_stack.dup
|
||||
_pry_.binding_stack.pop
|
||||
end
|
||||
|
@ -122,65 +121,6 @@ class Pry
|
|||
# This is to keep from breaking under Rails 3.2 for people who are doing that
|
||||
# IRB = Pry thing.
|
||||
module ExtendCommandBundle; end
|
||||
|
||||
# class accessors
|
||||
# define class attributes before pry library is required
|
||||
# fix initialize step of Pry (#1037)
|
||||
class << self
|
||||
extend Forwardable
|
||||
|
||||
# convenience method
|
||||
def self.delegate_accessors(delagatee, *names)
|
||||
def_delegators delagatee, *names
|
||||
def_delegators delagatee, *names.map { |v| "#{v}=" }
|
||||
end
|
||||
|
||||
# Get/Set the Proc that defines extra Readline completions (on top
|
||||
# of the ones defined for IRB).
|
||||
# @return [Proc] The Proc that defines extra Readline completions (on top
|
||||
# @example Add file names to completion list
|
||||
# Pry.custom_completions = proc { Dir.entries('.') }
|
||||
attr_accessor :custom_completions
|
||||
|
||||
# @return [Fixnum] The current input line.
|
||||
attr_accessor :current_line
|
||||
|
||||
# @return [Array] The Array of evaluated expressions.
|
||||
attr_accessor :line_buffer
|
||||
|
||||
# @return [String] The __FILE__ for the `eval()`. Should be "(pry)"
|
||||
# by default.
|
||||
attr_accessor :eval_path
|
||||
|
||||
# @return [OpenStruct] Return Pry's config object.
|
||||
attr_accessor :config
|
||||
|
||||
# @return [History] Return Pry's line history object.
|
||||
attr_accessor :history
|
||||
|
||||
# @return [Boolean] Whether Pry was activated from the command line.
|
||||
attr_accessor :cli
|
||||
|
||||
# @return [Boolean] Whether Pry sessions are quiet by default.
|
||||
attr_accessor :quiet
|
||||
|
||||
# @return [Exception, nil] The last pry internal error.
|
||||
# (a CommandError in most cases)
|
||||
attr_accessor :last_internal_error
|
||||
|
||||
# plugin forwardables
|
||||
def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
|
||||
|
||||
delegate_accessors :@config, :input, :output, :commands, :prompt, :print, :exception_handler,
|
||||
:hooks, :color, :pager, :editor, :memory_size, :extra_sticky_locals
|
||||
end
|
||||
end
|
||||
|
||||
if Pry::Helpers::BaseHelpers.mri_18?
|
||||
begin
|
||||
require 'ruby18_source_location'
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
|
||||
require 'method_source'
|
||||
|
@ -192,23 +132,13 @@ require 'rbconfig'
|
|||
require 'tempfile'
|
||||
require 'pathname'
|
||||
|
||||
begin
|
||||
begin
|
||||
require 'readline'
|
||||
rescue LoadError
|
||||
require 'rb-readline'
|
||||
end
|
||||
rescue LoadError
|
||||
warn "You're running a version of ruby with no Readline support"
|
||||
warn "Please `gem install rb-readline` or recompile ruby --with-readline."
|
||||
exit!
|
||||
end
|
||||
|
||||
if Pry::Helpers::BaseHelpers.jruby?
|
||||
begin
|
||||
require 'ffi'
|
||||
rescue LoadError
|
||||
warn "Need to `gem install ffi`"
|
||||
# TODO: Why do we need this?
|
||||
warn "For a better Pry experience on JRuby, please `gem install ffi`."
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -219,7 +149,8 @@ if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi
|
|||
# only fail on jruby (where win32console doesn't work).
|
||||
# Instead we'll recommend ansicon, which does.
|
||||
rescue LoadError
|
||||
warn "For a better pry experience, please use ansicon: http://adoxa.3eeweb.com/ansicon/"
|
||||
warn "For a better Pry experience on Windows, please use ansicon:"
|
||||
warn " http://adoxa.3eeweb.com/ansicon/"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -241,7 +172,6 @@ require 'pry/history'
|
|||
require 'pry/command'
|
||||
require 'pry/command_set'
|
||||
require 'pry/commands'
|
||||
require 'pry/custom_completions'
|
||||
require 'pry/completion'
|
||||
require 'pry/plugins'
|
||||
require 'pry/core_extensions'
|
||||
|
@ -253,3 +183,4 @@ require 'pry/pager'
|
|||
require 'pry/terminal'
|
||||
require 'pry/editor'
|
||||
require 'pry/rubygem'
|
||||
require "pry/indent"
|
||||
|
|
|
@ -44,7 +44,7 @@ class Pry
|
|||
end
|
||||
|
||||
# Add a block responsible for processing parsed options.
|
||||
def process_options(&block)
|
||||
def add_option_processor(&block)
|
||||
self.option_processors ||= []
|
||||
option_processors << block
|
||||
|
||||
|
@ -198,7 +198,7 @@ Copyright (c) 2013 John Mair (banisterfiend)
|
|||
"Start the session in the specified context. Equivalent to `context.pry` in a session.",
|
||||
:default => "Pry.toplevel_binding"
|
||||
)
|
||||
end.process_options do |opts|
|
||||
end.add_option_processor do |opts|
|
||||
|
||||
exit if opts.help?
|
||||
|
||||
|
|
|
@ -112,12 +112,6 @@ class Pry
|
|||
end
|
||||
|
||||
def method_or_class_lookup
|
||||
# we need this here because stupid Pry::Method.from_str() does a
|
||||
# Pry::Method.from_binding when str is nil.
|
||||
# Once we refactor Pry::Method.from_str() so it doesnt lookup
|
||||
# from bindings, we can get rid of this check
|
||||
return nil if str.to_s.empty?
|
||||
|
||||
obj = case str
|
||||
when /\S+\(\)\z/
|
||||
Pry::Method.from_str(str.sub(/\(\)\z/, ''),target) || Pry::WrappedModule.from_str(str, target)
|
||||
|
|
|
@ -37,8 +37,9 @@ class Pry
|
|||
|
||||
# Read the class name off of the singleton class to provide a default
|
||||
# inspect.
|
||||
eig = class << obj; self; end
|
||||
klass = Pry::Method.safe_send(eig, :ancestors).first
|
||||
singleton = class << obj; self; end
|
||||
ancestors = Pry::Method.safe_send(singleton, :ancestors)
|
||||
klass = ancestors.reject { |k| k == singleton }.first
|
||||
obj_id = obj.__id__.to_s(16) rescue 0
|
||||
str = "#<#{klass}:0x#{obj_id}>"
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ class Pry
|
|||
end
|
||||
|
||||
def command_regex
|
||||
pr = defined?(Pry.config.command_prefix) ? Pry.config.command_prefix : ""
|
||||
pr = Pry.respond_to?(:config) ? Pry.config.command_prefix : ""
|
||||
prefix = convert_to_regex(pr)
|
||||
prefix = "(?:#{prefix})?" unless options[:use_prefix]
|
||||
|
||||
|
@ -194,6 +194,7 @@ class Pry
|
|||
# The group in which the command should be displayed in "help" output.
|
||||
# This is usually auto-generated from directory naming, but it can be
|
||||
# manually overridden if necessary.
|
||||
# Group should not be changed once it is initialized.
|
||||
def group(name=nil)
|
||||
@group ||= if name
|
||||
name
|
||||
|
@ -248,7 +249,7 @@ class Pry
|
|||
end
|
||||
|
||||
def commands
|
||||
command_set.commands
|
||||
command_set.to_hash
|
||||
end
|
||||
|
||||
def text
|
||||
|
@ -284,7 +285,7 @@ class Pry
|
|||
# state.my_state = "my state" # this will not conflict with any
|
||||
# # `state.my_state` used in another command.
|
||||
def state
|
||||
_pry_.command_state[match] ||= OpenStruct.new
|
||||
_pry_.command_state[match] ||= Pry::Config.from_hash({})
|
||||
end
|
||||
|
||||
# Revaluate the string (str) and perform interpolation.
|
||||
|
|
|
@ -10,19 +10,15 @@ class Pry
|
|||
class CommandSet
|
||||
include Enumerable
|
||||
include Pry::Helpers::BaseHelpers
|
||||
|
||||
attr_reader :commands
|
||||
attr_reader :helper_module
|
||||
|
||||
# @param [Array<CommandSet>] imported_sets Sets which will be imported
|
||||
# automatically
|
||||
# @param [Array<Commandset>] imported_sets
|
||||
# Sets which will be imported automatically
|
||||
# @yield Optional block run to define commands
|
||||
def initialize(*imported_sets, &block)
|
||||
@commands = {}
|
||||
@helper_module = Module.new
|
||||
|
||||
import(*imported_sets)
|
||||
|
||||
instance_eval(&block) if block
|
||||
end
|
||||
|
||||
|
@ -83,7 +79,7 @@ class Pry
|
|||
description, options = ["No description.", description] if description.is_a?(Hash)
|
||||
options = Pry::Command.default_options(match).merge!(options)
|
||||
|
||||
commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block)
|
||||
@commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block)
|
||||
end
|
||||
alias_method :command, :block_command
|
||||
|
||||
|
@ -115,9 +111,9 @@ class Pry
|
|||
description, options = ["No description.", description] if description.is_a?(Hash)
|
||||
options = Pry::Command.default_options(match).merge!(options)
|
||||
|
||||
commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block)
|
||||
commands[match].class_eval(&block)
|
||||
commands[match]
|
||||
@commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block)
|
||||
@commands[match].class_eval(&block)
|
||||
@commands[match]
|
||||
end
|
||||
|
||||
# Execute a block of code before a command is invoked. The block also
|
||||
|
@ -157,7 +153,7 @@ class Pry
|
|||
def delete(*searches)
|
||||
searches.each do |search|
|
||||
cmd = find_command_by_match_or_listing(search)
|
||||
commands.delete cmd.match
|
||||
@commands.delete cmd.match
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -167,7 +163,7 @@ class Pry
|
|||
# @return [Pry::CommandSet] Returns the reciever (a command set).
|
||||
def import(*sets)
|
||||
sets.each do |set|
|
||||
commands.merge! set.commands
|
||||
@commands.merge! set.to_hash
|
||||
helper_module.send :include, set.helper_module
|
||||
end
|
||||
self
|
||||
|
@ -181,7 +177,7 @@ class Pry
|
|||
helper_module.send :include, set.helper_module
|
||||
matches.each do |match|
|
||||
cmd = set.find_command_by_match_or_listing(match)
|
||||
commands[cmd.match] = cmd
|
||||
@commands[cmd.match] = cmd
|
||||
end
|
||||
self
|
||||
end
|
||||
|
@ -190,8 +186,8 @@ class Pry
|
|||
# of the command to retrieve.
|
||||
# @return [Command] The command object matched.
|
||||
def find_command_by_match_or_listing(match_or_listing)
|
||||
cmd = (commands[match_or_listing] ||
|
||||
Pry::Helpers::BaseHelpers.find_command(match_or_listing, commands))
|
||||
cmd = (@commands[match_or_listing] ||
|
||||
Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands))
|
||||
cmd or raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!"
|
||||
end
|
||||
|
||||
|
@ -250,11 +246,11 @@ class Pry
|
|||
:description => cmd.description
|
||||
}.merge!(options)
|
||||
|
||||
commands[new_match] = cmd.dup
|
||||
commands[new_match].match = new_match
|
||||
commands[new_match].description = options.delete(:description)
|
||||
commands[new_match].options.merge!(options)
|
||||
commands.delete(cmd.match)
|
||||
@commands[new_match] = cmd.dup
|
||||
@commands[new_match].match = new_match
|
||||
@commands[new_match].description = options.delete(:description)
|
||||
@commands[new_match].options.merge!(options)
|
||||
@commands.delete(cmd.match)
|
||||
end
|
||||
|
||||
def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command)
|
||||
|
@ -303,16 +299,23 @@ class Pry
|
|||
end
|
||||
|
||||
|
||||
# @return [Array] The list of commands provided by the command set.
|
||||
# @return [Array]
|
||||
# The list of commands provided by the command set.
|
||||
def list_commands
|
||||
commands.keys
|
||||
@commands.keys
|
||||
end
|
||||
alias_method :keys, :list_commands
|
||||
|
||||
def to_hash
|
||||
@commands.dup
|
||||
end
|
||||
alias_method :to_h, :to_hash
|
||||
|
||||
# Find a command that matches the given line
|
||||
# @param [String] val The line that might be a command invocation
|
||||
# @return [Pry::Command, nil]
|
||||
def [](pattern)
|
||||
commands.values.select do |command|
|
||||
@commands.values.select do |command|
|
||||
command.matches?(pattern)
|
||||
end.sort_by do |command|
|
||||
command.match_score(pattern)
|
||||
|
@ -337,7 +340,7 @@ class Pry
|
|||
#
|
||||
def []=(pattern, command)
|
||||
if command.equal?(nil)
|
||||
return commands.delete(pattern)
|
||||
return @commands.delete(pattern)
|
||||
end
|
||||
unless Class === command && command < Pry::Command
|
||||
raise TypeError, "command is not a subclass of Pry::Command"
|
||||
|
@ -396,7 +399,7 @@ class Pry
|
|||
|
||||
# @private (used for testing)
|
||||
def run_command(context, match, *args)
|
||||
command = commands[match] or raise NoCommandError.new(match, self)
|
||||
command = @commands[match] or raise NoCommandError.new(match, self)
|
||||
command.new(context).call_safely(*args)
|
||||
end
|
||||
|
||||
|
@ -408,7 +411,7 @@ class Pry
|
|||
if command = find_command(search)
|
||||
command.new(context).complete(search)
|
||||
else
|
||||
commands.keys.select do |key|
|
||||
@commands.keys.select do |key|
|
||||
String === key && key.start_with?(search)
|
||||
end.map{ |key| key + " " } + Bond::DefaultMission.completions
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class Pry
|
||||
class Command::Cat
|
||||
class ExceptionFormatter < AbstractFormatter
|
||||
attr_accessor :ex
|
||||
attr_accessor :opts
|
||||
attr_accessor :_pry_
|
||||
attr_reader :ex
|
||||
attr_reader :opts
|
||||
attr_reader :_pry_
|
||||
|
||||
def initialize(exception, _pry_, opts)
|
||||
@ex = exception
|
||||
|
@ -23,7 +23,7 @@ class Pry
|
|||
private
|
||||
|
||||
def code_window_size
|
||||
Pry.config.default_window_size || 5
|
||||
_pry_.config.default_window_size || 5
|
||||
end
|
||||
|
||||
def backtrace_level
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class Pry
|
||||
class Command::Cat
|
||||
class FileFormatter < AbstractFormatter
|
||||
attr_accessor :file_with_embedded_line
|
||||
attr_accessor :opts
|
||||
attr_accessor :_pry_
|
||||
attr_reader :file_with_embedded_line
|
||||
attr_reader :opts
|
||||
attr_reader :_pry_
|
||||
|
||||
def initialize(file_with_embedded_line, _pry_, opts)
|
||||
@file_with_embedded_line = file_with_embedded_line
|
||||
|
@ -36,7 +36,7 @@ class Pry
|
|||
end
|
||||
|
||||
def code_window_size
|
||||
Pry.config.default_window_size || 7
|
||||
_pry_.config.default_window_size || 7
|
||||
end
|
||||
|
||||
def decorate(content)
|
||||
|
@ -49,7 +49,7 @@ class Pry
|
|||
|
||||
def detect_code_type_from_file(file_name)
|
||||
code_type = @code_from_file.code_type
|
||||
|
||||
|
||||
if code_type == :unknown
|
||||
name, ext = File.basename(file_name).split('.', 2)
|
||||
case name
|
||||
|
|
|
@ -9,7 +9,7 @@ class Pry
|
|||
|
||||
Move into new context (object or scope). As in UNIX shells use `cd ..` to go
|
||||
back, `cd /` to return to Pry top-level and `cd -` to toggle between last two
|
||||
scopes. Complex syntax (e.g `cd ../@x/y`) also supported.
|
||||
scopes. Complex syntax (e.g `cd ../@x/@y`) also supported.
|
||||
|
||||
cd @x
|
||||
cd ..
|
||||
|
|
|
@ -2,9 +2,9 @@ class Pry
|
|||
class Command::CodeCollector
|
||||
include Helpers::CommandHelpers
|
||||
|
||||
attr_accessor :args
|
||||
attr_accessor :opts
|
||||
attr_accessor :_pry_
|
||||
attr_reader :args
|
||||
attr_reader :opts
|
||||
attr_reader :_pry_
|
||||
|
||||
# The name of the explicitly given file (if any).
|
||||
attr_accessor :file
|
||||
|
@ -91,7 +91,7 @@ class Pry
|
|||
# @return [String]
|
||||
def pry_output_content
|
||||
pry_array_content_as_string(_pry_.output_array, self.class.output_result_ranges) do |v|
|
||||
Pry.config.gist.inspecter.call(v)
|
||||
_pry_.config.gist.inspecter.call(v)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ class Pry
|
|||
|
||||
Open a text editor. When no FILE is given, edits the pry input buffer.
|
||||
When a method/module/command is given, the code is opened in an editor.
|
||||
Ensure `Pry.config.editor` is set to your editor of choice.
|
||||
Ensure `Pry.config.editor` or `_pry_.config.editor` is set to your editor of choice.
|
||||
|
||||
edit sample.rb edit -p MyClass#my_method
|
||||
edit sample.rb --line 105 edit MyClass
|
||||
|
@ -165,7 +165,7 @@ class Pry
|
|||
end
|
||||
|
||||
def never_reload?
|
||||
opts.present?(:'no-reload') || Pry.config.disable_auto_reload
|
||||
opts.present?(:'no-reload') || _pry_.config.disable_auto_reload
|
||||
end
|
||||
|
||||
def reload?(file_name="")
|
||||
|
@ -186,7 +186,7 @@ class Pry
|
|||
end
|
||||
|
||||
def probably_a_file?(str)
|
||||
[".rb", ".c", ".py", ".yml", ".gemspec"].include? File.extname(str) ||
|
||||
[".rb", ".c", ".py", ".yml", ".gemspec"].include?(File.extname(str)) ||
|
||||
str =~ /\/|\\/
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ class Pry
|
|||
group 'Context'
|
||||
description 'Recursively search for a method within a Class/Module or the current namespace.'
|
||||
command_options :shellwords => false
|
||||
command_options :requires_gem => 'ruby18_source_location' if mri_18?
|
||||
|
||||
|
||||
banner <<-'BANNER'
|
||||
Usage: find-method [-n|-c] METHOD [NAMESPACE]
|
||||
|
@ -26,10 +24,6 @@ class Pry
|
|||
find-method -c 'output.puts' Pry
|
||||
BANNER
|
||||
|
||||
def setup
|
||||
require 'ruby18_source_location' if mri_18?
|
||||
end
|
||||
|
||||
def options(opti)
|
||||
opti.on :n, :name, "Search for a method by name"
|
||||
opti.on :c, :content, "Search for a method based on content in Regex form"
|
||||
|
|
|
@ -58,7 +58,7 @@ class Pry
|
|||
if code && code != ""
|
||||
content << code
|
||||
if code !~ /;\Z/
|
||||
content << "#{comment_expression_result_for_gist(Pry.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}"
|
||||
content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ class Pry
|
|||
|
||||
def options(opt)
|
||||
opt.on :m, :methods, "Show public methods defined on the Object"
|
||||
opt.on :M, "instance-methods", "Show methods defined in a Module or Class"
|
||||
opt.on :M, "instance-methods", "Show public methods defined in a Module or Class"
|
||||
opt.on :p, :ppp, "Show public, protected (in yellow) and private (in green) methods"
|
||||
opt.on :q, :quiet, "Show only methods defined on object.singleton_class and object.class"
|
||||
opt.on :v, :verbose, "Show methods and constants on all super-classes (ignores Pry.config.ls.ceiling)"
|
||||
|
@ -59,11 +59,10 @@ class Pry
|
|||
|
||||
ls_entity = LsEntity.new({
|
||||
:interrogatee => @interrogatee,
|
||||
:target => target,
|
||||
:no_user_opts => no_user_opts?,
|
||||
:opts => opts,
|
||||
:sticky_locals => _pry_.sticky_locals,
|
||||
:args => args
|
||||
:args => args,
|
||||
:_pry_ => _pry_
|
||||
})
|
||||
|
||||
stagger_output(ls_entity.entities_table)
|
||||
|
@ -73,7 +72,7 @@ class Pry
|
|||
|
||||
def error_list
|
||||
any_args = args.any?
|
||||
non_mod_interrogatee = !Module === @interrogatee
|
||||
non_mod_interrogatee = !(Module === @interrogatee)
|
||||
[
|
||||
['-l does not make sense with a specified Object', :locals, any_args],
|
||||
['-g does not make sense with a specified Object', :globals, any_args],
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
require 'pry/commands/ls/interrogateable'
|
||||
require 'pry/commands/ls/interrogatable'
|
||||
|
||||
class Pry
|
||||
class Command::Ls < Pry::ClassCommand
|
||||
class Constants < Pry::Command::Ls::Formatter
|
||||
include Pry::Command::Ls::Interrogatable
|
||||
|
||||
include Pry::Command::Ls::Interrogateable
|
||||
|
||||
def initialize(interrogatee, target, no_user_opts, opts)
|
||||
super(target)
|
||||
def initialize(interrogatee, no_user_opts, opts, _pry_)
|
||||
super(_pry_)
|
||||
@interrogatee = interrogatee
|
||||
@no_user_opts = no_user_opts
|
||||
@default_switch = opts[:constants]
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
class Pry
|
||||
class Command::Ls < Pry::ClassCommand
|
||||
class Formatter
|
||||
|
||||
attr_accessor :grep
|
||||
attr_reader :_pry_
|
||||
|
||||
def initialize(target)
|
||||
@target = target
|
||||
def initialize(_pry_)
|
||||
@_pry_ = _pry_
|
||||
@target = _pry_.current_context
|
||||
end
|
||||
|
||||
def write_out
|
||||
|
@ -16,7 +17,7 @@ class Pry
|
|||
private
|
||||
|
||||
def color(type, str)
|
||||
Pry::Helpers::Text.send(Pry.config.ls.send(:"#{type}_color"), str)
|
||||
Pry::Helpers::Text.send _pry_.config.ls["#{type}_color"], str
|
||||
end
|
||||
|
||||
# Add a new section to the output.
|
||||
|
|
|
@ -19,8 +19,8 @@ class Pry
|
|||
$CHILD_STATUS $SAFE $ERROR_INFO $ERROR_POSITION $LAST_MATCH_INFO
|
||||
$LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH)
|
||||
|
||||
def initialize(target, opts)
|
||||
super(target)
|
||||
def initialize(opts, _pry_)
|
||||
super(_pry_)
|
||||
@default_switch = opts[:globals]
|
||||
end
|
||||
|
||||
|
@ -32,7 +32,7 @@ class Pry
|
|||
private
|
||||
|
||||
def format(globals)
|
||||
globals.sort_by(&:downcase).map do |name|
|
||||
globals.map(&:to_s).sort_by(&:downcase).map do |name|
|
||||
if PSEUDO_GLOBALS.include?(name)
|
||||
color(:pseudo_global, name)
|
||||
elsif BUILTIN_GLOBALS.include?(name)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
require 'pry/commands/ls/interrogateable'
|
||||
require 'pry/commands/ls/interrogatable'
|
||||
|
||||
class Pry
|
||||
class Command::Ls < Pry::ClassCommand
|
||||
class InstanceVars < Pry::Command::Ls::Formatter
|
||||
include Pry::Command::Ls::Interrogatable
|
||||
|
||||
include Pry::Command::Ls::Interrogateable
|
||||
|
||||
def initialize(interrogatee, no_user_opts, opts)
|
||||
def initialize(interrogatee, no_user_opts, opts, _pry_)
|
||||
super(_pry_)
|
||||
@interrogatee = interrogatee
|
||||
@no_user_opts = no_user_opts
|
||||
@default_switch = opts[:ivars]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module Pry::Command::Ls::Interrogateable
|
||||
module Pry::Command::Ls::Interrogatable
|
||||
|
||||
private
|
||||
|
||||
|
@ -10,9 +10,8 @@ module Pry::Command::Ls::Interrogateable
|
|||
if interrogating_a_module?
|
||||
@interrogatee
|
||||
else
|
||||
class << @interrogatee
|
||||
ancestors.grep(::Class).reject { |c| c == self }.first
|
||||
end
|
||||
singleton = Pry::Method.singleton_class_of(@interrogatee)
|
||||
singleton.ancestors.grep(::Class).reject { |c| c == singleton }.first
|
||||
end
|
||||
end
|
||||
|
|
@ -2,11 +2,11 @@ class Pry
|
|||
class Command::Ls < Pry::ClassCommand
|
||||
class LocalNames < Pry::Command::Ls::Formatter
|
||||
|
||||
def initialize(target, no_user_opts, sticky_locals, args)
|
||||
super(target)
|
||||
def initialize(no_user_opts, args, _pry_)
|
||||
super(_pry_)
|
||||
@no_user_opts = no_user_opts
|
||||
@sticky_locals = sticky_locals
|
||||
@args = args
|
||||
@sticky_locals = _pry_.sticky_locals
|
||||
end
|
||||
|
||||
def correct_opts?
|
||||
|
|
|
@ -2,10 +2,10 @@ class Pry
|
|||
class Command::Ls < Pry::ClassCommand
|
||||
class LocalVars < Pry::Command::Ls::Formatter
|
||||
|
||||
def initialize(target, sticky_locals, opts)
|
||||
super(target)
|
||||
@sticky_locals = sticky_locals
|
||||
def initialize(opts, _pry_)
|
||||
super(_pry_)
|
||||
@default_switch = opts[:locals]
|
||||
@sticky_locals = _pry_.sticky_locals
|
||||
end
|
||||
|
||||
def output_self
|
||||
|
|
|
@ -12,15 +12,15 @@ class Pry
|
|||
class Command::Ls < Pry::ClassCommand
|
||||
|
||||
class LsEntity
|
||||
attr_reader :_pry_
|
||||
|
||||
def initialize(opts)
|
||||
@interrogatee = opts[:interrogatee]
|
||||
@target = opts[:target]
|
||||
@no_user_opts = opts[:no_user_opts]
|
||||
@opts = opts[:opts]
|
||||
@sticky_locals = opts[:sticky_locals]
|
||||
@args = opts[:args]
|
||||
@grep = Grep.new(Regexp.new(opts[:opts][:G] || '.'))
|
||||
@_pry_ = opts.delete(:_pry_)
|
||||
end
|
||||
|
||||
def entities_table
|
||||
|
@ -29,45 +29,42 @@ class Pry
|
|||
|
||||
private
|
||||
|
||||
def greppable
|
||||
proc do |entity|
|
||||
entity.tap { |o| o.grep = @grep }
|
||||
end
|
||||
def grep(entity)
|
||||
entity.tap { |o| o.grep = @grep }
|
||||
end
|
||||
|
||||
def globals
|
||||
greppable.call(Globals.new(@target, @opts))
|
||||
grep Globals.new(@opts, _pry_)
|
||||
end
|
||||
|
||||
def constants
|
||||
greppable.call(Constants.new(@interrogatee, @target, @no_user_opts, @opts))
|
||||
grep Constants.new(@interrogatee, @no_user_opts, @opts, _pry_)
|
||||
end
|
||||
|
||||
def methods
|
||||
greppable.call(Methods.new(@interrogatee, @no_user_opts, @opts))
|
||||
grep(Methods.new(@interrogatee, @no_user_opts, @opts, _pry_))
|
||||
end
|
||||
|
||||
def self_methods
|
||||
greppable.call(SelfMethods.new(@interrogatee, @no_user_opts, @opts))
|
||||
grep SelfMethods.new(@interrogatee, @no_user_opts, @opts, _pry_)
|
||||
end
|
||||
|
||||
def instance_vars
|
||||
greppable.call(InstanceVars.new(@interrogatee, @no_user_opts, @opts))
|
||||
grep InstanceVars.new(@interrogatee, @no_user_opts, @opts, _pry_)
|
||||
end
|
||||
|
||||
def local_names
|
||||
greppable.call(LocalNames.new(@target, @no_user_opts, @sticky_locals, @args))
|
||||
grep LocalNames.new(@no_user_opts, @args, _pry_)
|
||||
end
|
||||
|
||||
def local_vars
|
||||
LocalVars.new(@target, @sticky_locals, @opts)
|
||||
LocalVars.new(@opts, _pry_)
|
||||
end
|
||||
|
||||
def entities
|
||||
[globals, constants, methods, self_methods, instance_vars, local_names,
|
||||
local_vars]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
require 'pry/commands/ls/methods_helper'
|
||||
require 'pry/commands/ls/interrogateable'
|
||||
require 'pry/commands/ls/interrogatable'
|
||||
|
||||
class Pry
|
||||
class Command::Ls < Pry::ClassCommand
|
||||
class Methods < Pry::Command::Ls::Formatter
|
||||
|
||||
include Pry::Command::Ls::Interrogateable
|
||||
include Pry::Command::Ls::Interrogatable
|
||||
include Pry::Command::Ls::MethodsHelper
|
||||
|
||||
def initialize(interrogatee, no_user_opts, opts)
|
||||
def initialize(interrogatee, no_user_opts, opts, _pry_)
|
||||
super(_pry_)
|
||||
@interrogatee = interrogatee
|
||||
@no_user_opts = no_user_opts
|
||||
@default_switch = opts[:methods]
|
||||
|
@ -42,11 +43,11 @@ class Pry
|
|||
def below_ceiling
|
||||
ceiling = if @quiet_switch
|
||||
[Pry::Method.safe_send(interrogatee_mod, :ancestors)[1]] +
|
||||
Pry.config.ls.ceiling
|
||||
_pry_.config.ls.ceiling
|
||||
elsif @verbose_switch
|
||||
[]
|
||||
else
|
||||
Pry.config.ls.ceiling.dup
|
||||
_pry_.config.ls.ceiling.dup
|
||||
end
|
||||
lambda { |klass| !ceiling.include?(klass) }
|
||||
end
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
require 'pry/commands/ls/interrogateable'
|
||||
require 'pry/commands/ls/interrogatable'
|
||||
require 'pry/commands/ls/methods_helper'
|
||||
|
||||
class Pry
|
||||
class Command::Ls < Pry::ClassCommand
|
||||
class SelfMethods < Pry::Command::Ls::Formatter
|
||||
|
||||
include Pry::Command::Ls::Interrogateable
|
||||
include Pry::Command::Ls::Interrogatable
|
||||
include Pry::Command::Ls::MethodsHelper
|
||||
|
||||
def initialize(interrogatee, no_user_opts, opts)
|
||||
def initialize(interrogatee, no_user_opts, opts, _pry_)
|
||||
super(_pry_)
|
||||
@interrogatee = interrogatee
|
||||
@no_user_opts = no_user_opts
|
||||
end
|
||||
|
|
|
@ -20,11 +20,10 @@ class Pry
|
|||
process_cd parse_destination($1)
|
||||
else
|
||||
pass_block(cmd)
|
||||
|
||||
if command_block
|
||||
command_block.call `#{cmd}`
|
||||
else
|
||||
Pry.config.system.call(output, cmd, _pry_)
|
||||
_pry_.config.system.call(output, cmd, _pry_)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,10 +12,10 @@ class Pry
|
|||
case _pry_.prompt
|
||||
when Pry::SHELL_PROMPT
|
||||
_pry_.pop_prompt
|
||||
_pry_.custom_completions = Pry::DEFAULT_CUSTOM_COMPLETIONS
|
||||
_pry_.custom_completions = _pry_.config.file_completions
|
||||
else
|
||||
_pry_.push_prompt Pry::SHELL_PROMPT
|
||||
_pry_.custom_completions = Pry::FILE_COMPLETIONS
|
||||
_pry_.custom_completions = _pry_.config.command_completions
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,11 +3,6 @@ class Pry
|
|||
extend Pry::Helpers::BaseHelpers
|
||||
|
||||
command_options :shellwords => false, :interpolate => false
|
||||
command_options :requires_gem => "ruby18_source_location" if mri_18?
|
||||
|
||||
def setup
|
||||
require 'ruby18_source_location' if mri_18?
|
||||
end
|
||||
|
||||
def options(opt)
|
||||
opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count
|
||||
|
|
105
lib/pry/commands/watch_expression.rb
Normal file
105
lib/pry/commands/watch_expression.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
class Pry
|
||||
class Command::WatchExpression < Pry::ClassCommand
|
||||
require 'pry/commands/watch_expression/expression.rb'
|
||||
|
||||
match 'watch'
|
||||
group 'Context'
|
||||
description 'Watch the value of an expression and print a notification whenever it changes.'
|
||||
command_options :use_prefix => false
|
||||
|
||||
banner <<-'BANNER'
|
||||
Usage: watch [EXPRESSION]
|
||||
watch
|
||||
watch --delete [INDEX]
|
||||
|
||||
watch [EXPRESSION] adds an expression to the list of those being watched.
|
||||
It will be re-evaluated every time you hit enter in pry. If its value has
|
||||
changed, the new value will be printed to the console.
|
||||
|
||||
This is useful if you are step-through debugging and want to see how
|
||||
something changes over time. It's also useful if you're trying to write
|
||||
a method inside pry and want to check that it gives the right answers
|
||||
every time you redefine it.
|
||||
|
||||
watch on its own displays all the currently watched expressions and their
|
||||
values, and watch --delete [INDEX] allows you to delete expressions from
|
||||
the list being watched.
|
||||
BANNER
|
||||
|
||||
def options(opt)
|
||||
opt.on :d, :delete,
|
||||
"Delete the watch expression with the given index. If no index is given; clear all watch expressions.",
|
||||
:optional_argument => true, :as => Integer
|
||||
opt.on :l, :list,
|
||||
"Show all current watch expressions and their values. Calling watch with no expressions or options will also show the watch expressions."
|
||||
end
|
||||
|
||||
def process
|
||||
case
|
||||
when opts.present?(:delete)
|
||||
delete opts[:delete]
|
||||
when opts.present?(:list) || args.empty?
|
||||
list
|
||||
else
|
||||
add_hook
|
||||
add_expression(args)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def expressions
|
||||
_pry_.config.watch_expressions ||= []
|
||||
end
|
||||
|
||||
def delete(index)
|
||||
if index
|
||||
output.puts "Deleting watch expression ##{index}: #{expressions[index-1]}"
|
||||
expressions.delete_at(index-1)
|
||||
else
|
||||
output.puts "Deleting all watched expressions"
|
||||
expressions.clear
|
||||
end
|
||||
end
|
||||
|
||||
def list
|
||||
if expressions.empty?
|
||||
output.puts "No watched expressions"
|
||||
else
|
||||
Pry::Pager.with_pager(output) do |pager|
|
||||
pager.puts "Listing all watched expressions:"
|
||||
pager.puts ""
|
||||
expressions.each_with_index do |expr, index|
|
||||
pager.print text.with_line_numbers(expr.to_s, index+1)
|
||||
end
|
||||
pager.puts ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def eval_and_print_changed(output)
|
||||
expressions.each do |expr|
|
||||
expr.eval!
|
||||
if expr.changed?
|
||||
output.puts "#{text.blue "watch"}: #{expr.to_s}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_expression(arguments)
|
||||
expressions << Expression.new(target, arg_string)
|
||||
output.puts "Watching #{Code.new(arg_string)}"
|
||||
end
|
||||
|
||||
def add_hook
|
||||
hook = [:after_eval, :watch_expression]
|
||||
unless _pry_.hooks.hook_exists?(*hook)
|
||||
_pry_.hooks.add_hook(*hook) do |_, _pry_|
|
||||
eval_and_print_changed _pry_.output
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Pry::Commands.add_command(Pry::Command::WatchExpression)
|
||||
end
|
37
lib/pry/commands/watch_expression/expression.rb
Normal file
37
lib/pry/commands/watch_expression/expression.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
class Pry
|
||||
class Command::WatchExpression
|
||||
class Expression
|
||||
attr_reader :target, :source, :value, :previous_value
|
||||
|
||||
def initialize(target, source)
|
||||
@target = target
|
||||
@source = Code.new(source).strip
|
||||
end
|
||||
|
||||
def eval!
|
||||
@previous_value = @value
|
||||
@value = Pry::ColorPrinter.pp(target_eval(target, source), "")
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{source} => #{value}"
|
||||
end
|
||||
|
||||
# Has the value of the expression changed?
|
||||
#
|
||||
# We use the pretty-printed string represenation to detect differences
|
||||
# as this avoids problems with dup (causes too many differences) and == (causes too few)
|
||||
def changed?
|
||||
(value != previous_value)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target_eval(target, source)
|
||||
target.eval(source)
|
||||
rescue => e
|
||||
e
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -109,7 +109,7 @@ class Pry
|
|||
end
|
||||
|
||||
def top_level?
|
||||
target_self == TOPLEVEL_BINDING.eval("self")
|
||||
target_self == Pry.main
|
||||
end
|
||||
|
||||
def handle_internal_binding
|
||||
|
@ -178,7 +178,7 @@ class Pry
|
|||
|
||||
def window_size
|
||||
if args.empty?
|
||||
Pry.config.default_window_size
|
||||
_pry_.config.default_window_size
|
||||
else
|
||||
args.first.to_i
|
||||
end
|
||||
|
|
|
@ -1,260 +1,24 @@
|
|||
require 'ostruct'
|
||||
class Pry::Config
|
||||
require_relative 'config/behavior'
|
||||
require_relative 'config/default'
|
||||
require_relative 'config/convenience'
|
||||
include Pry::Config::Behavior
|
||||
|
||||
class Pry
|
||||
class Config < OpenStruct
|
||||
def self.shortcuts
|
||||
Convenience::SHORTCUTS
|
||||
end
|
||||
|
||||
# Get/Set the object to use for input by default by all Pry instances.
|
||||
# Pry.config.input is an option determining the input object - the object
|
||||
# from which Pry retrieves its lines of input. Pry accepts any object that
|
||||
# implements the readline method. This includes IO objects, StringIO,
|
||||
# Readline, File and custom objects.
|
||||
# @return [#readline] The object to use for input by default by all
|
||||
# Pry instances.
|
||||
# @example
|
||||
# Pry.config.input = StringIO.new("@x = 10\nexit")
|
||||
attr_accessor :input
|
||||
|
||||
# Get/Set the object to use for output by default by all Pry instances.
|
||||
# Pry.config.output is an option determining the output object - the object
|
||||
# to which Pry writes its output. Pry accepts any object that implements the
|
||||
# puts method. This includes IO objects, StringIO, File and custom objects.
|
||||
# @return [#puts] The object to use for output by default by all
|
||||
# Pry instances.
|
||||
# @example
|
||||
# Pry.config.output = StringIO.new
|
||||
attr_accessor :output
|
||||
|
||||
# Get/Set the object to use for commands by default by all Pry instances.
|
||||
# @return [Pry::CommandBase] The object to use for commands by default by
|
||||
# all Pry instances.
|
||||
# @example
|
||||
# Pry.config.commands = Pry::CommandSet.new do
|
||||
# import_from Pry::Commands, "ls"
|
||||
# command "greet" do |name|
|
||||
# output.puts "hello #{name}"
|
||||
# end
|
||||
# end
|
||||
attr_accessor :commands
|
||||
|
||||
# Get/Set the Proc to use for printing by default by all Pry
|
||||
# instances.
|
||||
# Two parameters are passed to the print Proc: these are (1) the
|
||||
# output object for the current session and (2) the expression value to
|
||||
# print. It is important that you write to the output object instead of just
|
||||
# stdout so that all Pry output can be redirected if necessary. This is the
|
||||
# 'print' component of the REPL.
|
||||
# @return [Proc] The Proc to use for printing by default by all
|
||||
# Pry instances.
|
||||
# @example
|
||||
# Pry.config.print = proc { |output, value| output.puts "=> #{value.inspect}" }
|
||||
attr_accessor :print
|
||||
|
||||
# Pry.config.exception_handler is an option determining the exception
|
||||
# handler object - the Proc responsible for dealing with exceptions raised
|
||||
# by user input to the REPL. Three parameters are passed to the exception
|
||||
# handler Proc: these are (1) the output object for the current session, (2)
|
||||
# the exception object that was raised inside the Pry session, and (3) a
|
||||
# reference to the associated Pry instance.
|
||||
# @return [Proc] The Proc to use for printing exceptions by default by all
|
||||
# Pry instances.
|
||||
# @example
|
||||
# Pry.config.exception_handler = proc do |output, exception, _|
|
||||
# output.puts "#{exception.class}: #{exception.message}"
|
||||
# output.puts "from #{exception.backtrace.first}"
|
||||
# end
|
||||
attr_accessor :exception_handler
|
||||
|
||||
# @return [Array] The classes of exception that will not be caught by Pry.
|
||||
# @example
|
||||
# Pry.config.exception_whitelist = [SystemExit, SignalException]
|
||||
attr_accessor :exception_whitelist
|
||||
|
||||
# Send Pry into interactive mode after finishing execution
|
||||
# @return [Boolean]
|
||||
attr_accessor :exit_interactive
|
||||
|
||||
# @return [Fixnum] The number of lines of context to show before and after
|
||||
# exceptions, etc.
|
||||
# @example
|
||||
# Pry.config.default_window_size = 10
|
||||
attr_accessor :default_window_size
|
||||
|
||||
# Get/Set the `Pry::Hooks` instance that defines Pry hooks used by default
|
||||
# by all Pry instances.
|
||||
# @return [Pry::Hooks] The hooks used by default by all Pry instances.
|
||||
# @example
|
||||
# Pry.config.hooks = Pry::Hooks.new.add_hook(:before_session,
|
||||
# :default) { |output, target, _pry_| output.puts "Good morning!" }
|
||||
attr_reader :hooks
|
||||
|
||||
# FIXME:
|
||||
# This is a hack to alert people of the new API.
|
||||
# @param [Pry::Hooks] v Only accept `Pry::Hooks` now!
|
||||
def hooks=(v)
|
||||
if v.is_a?(Hash)
|
||||
warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||
@hooks = Pry::Hooks.from_hash(v)
|
||||
else
|
||||
@hooks = v
|
||||
end
|
||||
#
|
||||
# FIXME
|
||||
# @param [Pry::Hooks] hooks
|
||||
#
|
||||
def hooks=(hooks)
|
||||
if hooks.is_a?(Hash)
|
||||
warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object " \
|
||||
"instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||
self["hooks"] = Pry::Hooks.from_hash(hooks)
|
||||
else
|
||||
self["hooks"] = hooks
|
||||
end
|
||||
|
||||
# Get the array of Procs (or single Proc) to be used for the prompts by
|
||||
# default by all Pry instances. Three parameters are passed into the prompt
|
||||
# procs, (1) the object that is the target of the session, (2) the current
|
||||
# nesting level, and (3) a reference to the associated Pry instance. These
|
||||
# objects can be used in the prompt, if desired.
|
||||
# @return [Array<Proc>, Proc] The array of Procs to be used for the
|
||||
# prompts by default by all Pry instances.
|
||||
# @example
|
||||
# Pry.config.prompt = proc { |obj, nest_level, _pry_| "#{obj}:#{nest_level}> " }
|
||||
attr_accessor :prompt
|
||||
|
||||
# The display name that is part of the prompt. Default is 'pry'. You can
|
||||
# set your own name so you can identify which project your current pry
|
||||
# session is using. This is useful if you have a local pryrc file in a
|
||||
# Rails project for example.
|
||||
# @return [String]
|
||||
# @example
|
||||
# Pry.config.prompt_name = 'my_rails_project'
|
||||
attr_accessor :prompt_name
|
||||
|
||||
# The list of safe objects, the `#inspect` method of which can be used for
|
||||
# the prompt. The default safe objects are defined in
|
||||
# `DEFAULT_PROMPT_SAFE_OBJECTS` (see Pry::DEFAULT_PROMPT_SAFE_OBJECTS).
|
||||
# @return [Array]
|
||||
# @example
|
||||
# class Barbie
|
||||
# def inspect
|
||||
# 'You can brush my hair, undress me everywhere!'
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Pry.config.prompt_safe_objects << Barbie
|
||||
attr_accessor :prompt_safe_objects
|
||||
|
||||
# The default editor to use. Defaults to $VISUAL, $EDITOR, or a sensible
|
||||
# fallback for the platform. If `editor` is a String then that string is
|
||||
# used as the shell command to invoke the editor. If `editor` is callable
|
||||
# (e.g a Proc) then `file`, `line`, and `reloading` are passed in as
|
||||
# parameters and the return value of that callable invocation is used as the
|
||||
# exact shell command to invoke the editor. `reloading` indicates whether
|
||||
# Pry will be reloading code after the shell command returns. Any or all of
|
||||
# these parameters can be omitted from the callable's signature.
|
||||
# @example String
|
||||
# Pry.config.editor = "emacsclient"
|
||||
# @example Callable
|
||||
# Pry.config.editor = proc { |file, line| "emacsclient #{file} +#{line}" }
|
||||
# @example Callable waiting only if reloading
|
||||
# Pry.config.editor = proc { |file, line, reloading|
|
||||
# "subl #{'--wait' if reloading} #{file}:#{line}"
|
||||
# }
|
||||
# @return [String, #call]
|
||||
attr_accessor :editor
|
||||
|
||||
# A string that must precede all Pry commands (e.g., if command_prefix is
|
||||
# set to "%", the "cd" command must be invoked as "%cd").
|
||||
# @return [String]
|
||||
attr_accessor :command_prefix
|
||||
|
||||
# @return [Boolean] Toggle Pry color on and off.
|
||||
attr_accessor :color
|
||||
|
||||
# @return [Boolean] Toggle paging on and off.
|
||||
attr_accessor :pager
|
||||
|
||||
# Determines whether the rc file (~/.pryrc) should be loaded.
|
||||
# @return [Boolean]
|
||||
attr_accessor :should_load_rc
|
||||
|
||||
# Determines whether the local rc file (./.pryrc) should be loaded.
|
||||
# @return [Boolean]
|
||||
attr_accessor :should_load_local_rc
|
||||
|
||||
# Determines whether plugins should be loaded.
|
||||
# @return [Boolean]
|
||||
attr_accessor :should_load_plugins
|
||||
|
||||
# Determines whether to load files specified with the -r flag.
|
||||
# @return [Boolean]
|
||||
attr_accessor :should_load_requires
|
||||
|
||||
# Determines whether to disable edit-method's auto-reloading behavior.
|
||||
# @return [Boolean]
|
||||
attr_accessor :disable_auto_reload
|
||||
|
||||
# Determines whether Pry should trap SIGINT and cause it to raise an
|
||||
# Interrupt exception. This is only useful on jruby, MRI does this
|
||||
# for us.
|
||||
# @return [Boolean]
|
||||
attr_accessor :should_trap_interrupts
|
||||
|
||||
# Config option for history.
|
||||
# sub-options include history.file, history.load, and history.save
|
||||
# history.file is the file to save/load history to, e.g
|
||||
# Pry.config.history.file = "~/.pry_history".
|
||||
# history.should_load is a boolean that determines whether history will be
|
||||
# loaded from history.file at session start.
|
||||
# history.should_save is a boolean that determines whether history will be
|
||||
# saved to history.file at session end.
|
||||
# @return [OpenStruct]
|
||||
attr_accessor :history
|
||||
|
||||
# Config option for plugins:
|
||||
# sub-options include:
|
||||
# `plugins.strict_loading` (Boolean) which toggles whether referring to a
|
||||
# non-existent plugin should raise an exception (defaults to `false`).
|
||||
# @return [OpenStruct]
|
||||
attr_accessor :plugins
|
||||
|
||||
# @return [Array<String>] Ruby files to be required after loading
|
||||
# any plugins.
|
||||
attr_accessor :requires
|
||||
|
||||
# @return [Integer] Amount of results that will be stored into out
|
||||
attr_accessor :memory_size
|
||||
|
||||
# @return [Proc] The proc that manages ^D presses in the REPL.
|
||||
# The proc is passed the current eval_string and the current pry instance.
|
||||
attr_accessor :control_d_handler
|
||||
|
||||
# @return [Proc] The proc that runs system commands
|
||||
# The proc is passed the pry output object, the command string
|
||||
# to eval, and a reference to the pry instance
|
||||
attr_accessor :system
|
||||
|
||||
# @return [Boolean] Whether or not code should be indented
|
||||
# using Pry::Indent.
|
||||
attr_accessor :auto_indent
|
||||
|
||||
# @return [Boolean] Whether or not indentation should be corrected
|
||||
# after hitting enter. This feature is not supported by all terminals.
|
||||
attr_accessor :correct_indent
|
||||
|
||||
# @return [Boolean] Whether or not a warning will be displayed when
|
||||
# a command name collides with a method/local in the current context.
|
||||
attr_accessor :collision_warning
|
||||
|
||||
# Config option for gist.
|
||||
# sub-options include `gist.inspecter`,
|
||||
# `gist.inspecter` is a callable that defines how the expression output
|
||||
# will be displayed when using the `gist -i` command.
|
||||
# @example Pretty inspect output
|
||||
# Pry.config.gist.inspecter = proc { |v| v.pretty_inspect }
|
||||
# @example Regular inspect
|
||||
# Pry.config.gist.inspecter = proc &:inspect
|
||||
# @return [OpenStruct]
|
||||
attr_accessor :gist
|
||||
|
||||
# @return [Hash] Additional sticky locals (to the standard ones) to use in
|
||||
# Pry sessions.
|
||||
# @example Inject `random_number` sticky local into Pry session
|
||||
# Pry.config.extra_sticky_locals = { :random_number => proc {
|
||||
# rand(10) } }
|
||||
attr_accessor :extra_sticky_locals
|
||||
|
||||
# @return [#build_completion_proc] A completer to use.
|
||||
attr_accessor :completer
|
||||
end
|
||||
end
|
||||
|
||||
|
|
115
lib/pry/config/behavior.rb
Normal file
115
lib/pry/config/behavior.rb
Normal file
|
@ -0,0 +1,115 @@
|
|||
module Pry::Config::Behavior
|
||||
ASSIGNMENT = "=".freeze
|
||||
NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze
|
||||
RESERVED_KEYS = [
|
||||
"[]", "[]=", "merge!",
|
||||
"respond_to?", "key?", "refresh",
|
||||
"forget", "inherited_by", "to_h",
|
||||
"to_hash", "_dup"
|
||||
].freeze
|
||||
|
||||
def self.included(klass)
|
||||
klass.extend Module.new {
|
||||
def from_hash(hash, default = nil)
|
||||
new(default).tap do |config|
|
||||
config.merge!(hash)
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def initialize(default = Pry.config)
|
||||
@default = default.dup if default
|
||||
@default.inherited_by(self) if default
|
||||
@writes = {}
|
||||
end
|
||||
|
||||
def [](key)
|
||||
@writes[key.to_s]
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
key = key.to_s
|
||||
if RESERVED_KEYS.include?(key)
|
||||
raise ArgumentError, "sorry, '#{key}' is a reserved configuration key."
|
||||
end
|
||||
@writes[key] = value
|
||||
end
|
||||
|
||||
def method_missing(name, *args, &block)
|
||||
key = name.to_s
|
||||
if key[-1] == ASSIGNMENT
|
||||
short_key = key[0..-2]
|
||||
self[short_key] = args[0]
|
||||
elsif key?(key)
|
||||
self[key]
|
||||
elsif @default.respond_to?(name)
|
||||
value = @default.public_send(name, *args, &block)
|
||||
self[key] = _dup(value)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def merge!(other)
|
||||
raise TypeError, "cannot coerce argument to Hash" unless other.respond_to?(:to_hash)
|
||||
other = other.to_hash
|
||||
other.each do |key, value|
|
||||
self[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
def respond_to?(name, boolean=false)
|
||||
key?(name) or @default.respond_to?(name) or super(name, boolean)
|
||||
end
|
||||
|
||||
def key?(key)
|
||||
key = key.to_s
|
||||
@writes.key?(key)
|
||||
end
|
||||
|
||||
def refresh
|
||||
@writes.clear
|
||||
true
|
||||
end
|
||||
|
||||
def forget(key)
|
||||
@writes.delete(key.to_s)
|
||||
end
|
||||
|
||||
def inherited_by(other)
|
||||
if @inherited_by
|
||||
raise RuntimeError, "instance of '#{self.class}' cannot reassign its child."
|
||||
else
|
||||
@inherited_by = other
|
||||
end
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
return false unless other.respond_to?(:to_hash)
|
||||
to_hash == other.to_hash
|
||||
end
|
||||
alias_method :eql?, :==
|
||||
|
||||
def keys
|
||||
@writes.keys
|
||||
end
|
||||
|
||||
def to_hash
|
||||
@writes.dup
|
||||
end
|
||||
alias_method :to_h, :to_hash
|
||||
|
||||
def quiet?
|
||||
quiet
|
||||
end
|
||||
|
||||
private
|
||||
def _dup(value)
|
||||
if NODUP.any? { |klass| klass === value }
|
||||
value
|
||||
else
|
||||
value.dup
|
||||
end
|
||||
end
|
||||
end
|
26
lib/pry/config/convenience.rb
Normal file
26
lib/pry/config/convenience.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
module Pry::Config::Convenience
|
||||
SHORTCUTS = [
|
||||
:input,
|
||||
:output,
|
||||
:commands,
|
||||
:print,
|
||||
:exception_handler,
|
||||
:quiet?,
|
||||
:hooks,
|
||||
:color,
|
||||
:pager,
|
||||
:editor,
|
||||
:memory_size,
|
||||
:extra_sticky_locals
|
||||
]
|
||||
|
||||
|
||||
def config_shortcut(*names)
|
||||
names.each do |name|
|
||||
reader = name
|
||||
setter = "#{name}="
|
||||
define_method(reader) { config.public_send(name) }
|
||||
define_method(setter) { |value| config.public_send(setter, value) }
|
||||
end
|
||||
end
|
||||
end
|
123
lib/pry/config/default.rb
Normal file
123
lib/pry/config/default.rb
Normal file
|
@ -0,0 +1,123 @@
|
|||
class Pry::Config::Default
|
||||
include Pry::Config::Behavior
|
||||
|
||||
default = {
|
||||
:input => proc { lazy_readline },
|
||||
:output => proc { $stdout },
|
||||
:commands => proc { Pry::Commands },
|
||||
:prompt_name => proc { Pry::DEFAULT_PROMPT_NAME },
|
||||
:prompt => proc { Pry::DEFAULT_PROMPT },
|
||||
:prompt_safe_objects => proc { Pry::DEFAULT_PROMPT_SAFE_OBJECTS },
|
||||
:print => proc { Pry::DEFAULT_PRINT },
|
||||
:quiet => proc { false },
|
||||
:exception_handler => proc { Pry::DEFAULT_EXCEPTION_HANDLER },
|
||||
:exception_whitelist => proc { Pry::DEFAULT_EXCEPTION_WHITELIST },
|
||||
:hooks => proc { Pry::DEFAULT_HOOKS },
|
||||
:pager => proc { true },
|
||||
:system => proc { Pry::DEFAULT_SYSTEM },
|
||||
:color => proc { Pry::Helpers::BaseHelpers.use_ansi_codes? },
|
||||
:default_window_size => proc { 5 },
|
||||
:editor => proc { Pry.default_editor_for_platform }, # TODO: Pry::Platform.editor
|
||||
:should_load_rc => proc { true },
|
||||
:should_load_local_rc => proc { true },
|
||||
:should_trap_interrupts => proc { Pry::Helpers::BaseHelpers.jruby? }, # TODO: Pry::Platform.jruby?
|
||||
:disable_auto_reload => proc { false },
|
||||
:command_prefix => proc { "" },
|
||||
:auto_indent => proc { Pry::Helpers::BaseHelpers.use_ansi_codes? },
|
||||
:correct_indent => proc { true },
|
||||
:collision_warning => proc { false },
|
||||
:output_prefix => proc { "=> "},
|
||||
:requires => proc { [] },
|
||||
:should_load_requires => proc { true },
|
||||
:should_load_plugins => proc { true },
|
||||
:control_d_handler => proc { Pry::DEFAULT_CONTROL_D_HANDLER },
|
||||
:memory_size => proc { 100 },
|
||||
:extra_sticky_locals => proc { {} },
|
||||
:command_completions => proc { proc { commands.keys } },
|
||||
:file_completions => proc { proc { Dir["."] } },
|
||||
:completer => proc { lazy_completer }
|
||||
}
|
||||
|
||||
def initialize
|
||||
super(nil)
|
||||
configure_ls
|
||||
configure_gist
|
||||
configure_history
|
||||
end
|
||||
|
||||
default.each do |key, value|
|
||||
define_method(key) do
|
||||
if default[key].equal?(value)
|
||||
default[key] = instance_eval(&value)
|
||||
end
|
||||
default[key]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# TODO:
|
||||
# all of this configure_* stuff is a relic of old code.
|
||||
# we should try move this code to being command-local.
|
||||
def configure_ls
|
||||
self["ls"] = Pry::Config.from_hash({
|
||||
:heading_color => :bright_blue,
|
||||
:public_method_color => :default,
|
||||
:private_method_color => :blue,
|
||||
:protected_method_color => :blue,
|
||||
:method_missing_color => :bright_red,
|
||||
:local_var_color => :yellow,
|
||||
:pry_var_color => :default, # e.g. _, _pry_, _file_
|
||||
:instance_var_color => :blue, # e.g. @foo
|
||||
:class_var_color => :bright_blue, # e.g. @@foo
|
||||
:global_var_color => :default, # e.g. $CODERAY_DEBUG, $eventmachine_library
|
||||
:builtin_global_color => :cyan, # e.g. $stdin, $-w, $PID
|
||||
:pseudo_global_color => :cyan, # e.g. $~, $1..$9, $LAST_MATCH_INFO
|
||||
:constant_color => :default, # e.g. VERSION, ARGF
|
||||
:class_constant_color => :blue, # e.g. Object, Kernel
|
||||
:exception_constant_color => :magenta, # e.g. Exception, RuntimeError
|
||||
:unloaded_constant_color => :yellow, # Any constant that is still in .autoload? state
|
||||
:separator => " ",
|
||||
:ceiling => [Object, Module, Class]
|
||||
})
|
||||
end
|
||||
|
||||
def configure_gist
|
||||
self["gist"] = Pry::Config.from_hash(inspecter: proc(&:pretty_inspect))
|
||||
end
|
||||
|
||||
def configure_history
|
||||
self["history"] = Pry::Config.from_hash "should_save" => true,
|
||||
"should_load" => true
|
||||
history.file = File.expand_path("~/.pry_history") rescue nil
|
||||
if history.file.nil?
|
||||
self.should_load_rc = false
|
||||
history.should_save = false
|
||||
history.should_load = false
|
||||
end
|
||||
end
|
||||
|
||||
def lazy_readline
|
||||
require 'readline'
|
||||
Readline
|
||||
rescue LoadError
|
||||
warn "Sorry, you can't use Pry without Readline or a compatible library."
|
||||
warn "Possible solutions:"
|
||||
warn " * Rebuild Ruby with Readline support using `--with-readline`"
|
||||
warn " * Use the rb-readline gem, which is a pure-Ruby port of Readline"
|
||||
warn " * Use the pry-coolline gem, a pure-ruby alternative to Readline"
|
||||
raise
|
||||
end
|
||||
|
||||
def lazy_completer
|
||||
if defined?(Bond) && !is_editline?(input)
|
||||
Pry::BondCompleter.start
|
||||
else
|
||||
Pry::InputCompleter.start
|
||||
end
|
||||
end
|
||||
|
||||
def is_editline?(input)
|
||||
defined?(input::VERSION) && input::VERSION =~ /editline/i
|
||||
end
|
||||
end
|
|
@ -99,37 +99,33 @@ class Object
|
|||
end
|
||||
end
|
||||
|
||||
if defined?(BasicObject)
|
||||
class BasicObject
|
||||
# Return a binding object for the receiver.
|
||||
#
|
||||
# The `self` of the binding is set to the current object, and it contains no
|
||||
# local variables.
|
||||
#
|
||||
# The default definee (http://yugui.jp/articles/846) is set such that new
|
||||
# methods defined will be added to the singleton class of the BasicObject.
|
||||
#
|
||||
# @return [Binding]
|
||||
def __binding__
|
||||
# BasicObjects don't have respond_to?, so we just define the method
|
||||
# every time. As they also don't have `.freeze`, this call won't
|
||||
# fail as it can for normal Objects.
|
||||
(class << self; self; end).class_eval <<-EOF, __FILE__, __LINE__ + 1
|
||||
# Get a binding with 'self' set to self, and no locals.
|
||||
#
|
||||
# The default definee is determined by the context in which the
|
||||
# definition is eval'd.
|
||||
#
|
||||
# Please don't call this method directly, see {__binding__}.
|
||||
#
|
||||
# @return [Binding]
|
||||
def __pry__
|
||||
# In ruby-1.8.7 ::Kernel.binding sets self to Kernel in the returned binding.
|
||||
# Luckily ruby-1.8.7 doesn't have BasicObject, so this is safe.
|
||||
::Kernel.binding
|
||||
end
|
||||
EOF
|
||||
self.__pry__
|
||||
end
|
||||
class BasicObject
|
||||
# Return a binding object for the receiver.
|
||||
#
|
||||
# The `self` of the binding is set to the current object, and it contains no
|
||||
# local variables.
|
||||
#
|
||||
# The default definee (http://yugui.jp/articles/846) is set such that new
|
||||
# methods defined will be added to the singleton class of the BasicObject.
|
||||
#
|
||||
# @return [Binding]
|
||||
def __binding__
|
||||
# BasicObjects don't have respond_to?, so we just define the method
|
||||
# every time. As they also don't have `.freeze`, this call won't
|
||||
# fail as it can for normal Objects.
|
||||
(class << self; self; end).class_eval <<-EOF, __FILE__, __LINE__ + 1
|
||||
# Get a binding with 'self' set to self, and no locals.
|
||||
#
|
||||
# The default definee is determined by the context in which the
|
||||
# definition is eval'd.
|
||||
#
|
||||
# Please don't call this method directly, see {__binding__}.
|
||||
#
|
||||
# @return [Binding]
|
||||
def __pry__
|
||||
::Kernel.binding
|
||||
end
|
||||
EOF
|
||||
self.__pry__
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
class Pry
|
||||
|
||||
# This proc will be instance_eval's against the active Pry instance
|
||||
DEFAULT_CUSTOM_COMPLETIONS = proc { commands.commands.keys }
|
||||
FILE_COMPLETIONS = proc { commands.commands.keys + Dir.entries('.') }
|
||||
end
|
|
@ -90,10 +90,6 @@ class Pry
|
|||
RbConfig::CONFIG['ruby_install_name'] == 'ruby'
|
||||
end
|
||||
|
||||
def mri_18?
|
||||
mri? && RUBY_VERSION =~ /1.8/
|
||||
end
|
||||
|
||||
def mri_19?
|
||||
mri? && RUBY_VERSION =~ /1.9/
|
||||
end
|
||||
|
|
|
@ -16,10 +16,18 @@ class Pry
|
|||
|
||||
# Assign the default methods for loading, saving, pushing, and clearing.
|
||||
def restore_default_behavior
|
||||
@loader = method(:read_from_file)
|
||||
@saver = method(:save_to_file)
|
||||
@pusher = method(:push_to_readline)
|
||||
@clearer = method(:clear_readline)
|
||||
Pry.config.input # force Readline to load if applicable
|
||||
|
||||
@loader = method(:read_from_file)
|
||||
@saver = method(:save_to_file)
|
||||
|
||||
if defined?(Readline)
|
||||
@pusher = method(:push_to_readline)
|
||||
@clearer = method(:clear_readline)
|
||||
else
|
||||
@pusher = proc { }
|
||||
@clearer = proc { }
|
||||
end
|
||||
end
|
||||
|
||||
# Load the input history using `History.loader`.
|
||||
|
|
|
@ -18,11 +18,11 @@ class Pry
|
|||
# @param [Hash] hash The hash to convert to `Pry::Hooks`.
|
||||
# @return [Pry::Hooks] The resulting `Pry::Hooks` instance.
|
||||
def self.from_hash(hash)
|
||||
return hash if hash.instance_of?(self)
|
||||
instance = new
|
||||
hash.each do |k, v|
|
||||
instance.add_hook(k, nil, v)
|
||||
end
|
||||
|
||||
instance
|
||||
end
|
||||
|
||||
|
@ -146,18 +146,14 @@ class Pry
|
|||
def exec_hook(event_name, *args, &block)
|
||||
@hooks[event_name] ||= []
|
||||
|
||||
# silence warnings to get rid of 1.8's "warning: multiple values
|
||||
# for a block parameter" warnings
|
||||
Pry::Helpers::BaseHelpers.silence_warnings do
|
||||
@hooks[event_name].map do |hook_name, callable|
|
||||
begin
|
||||
callable.call(*args, &block)
|
||||
rescue RescuableException => e
|
||||
errors << e
|
||||
e
|
||||
end
|
||||
end.last
|
||||
end
|
||||
@hooks[event_name].map do |hook_name, callable|
|
||||
begin
|
||||
callable.call(*args, &block)
|
||||
rescue RescuableException => e
|
||||
errors << e
|
||||
e
|
||||
end
|
||||
end.last
|
||||
end
|
||||
|
||||
# Return the number of hook functions registered for the `event_name` event.
|
||||
|
|
|
@ -31,8 +31,7 @@ class Pry
|
|||
# search in, find and return the requested method wrapped in a `Pry::Method`
|
||||
# instance.
|
||||
#
|
||||
# @param [String, nil] name The name of the method to retrieve, or `nil` to
|
||||
# delegate to `from_binding` instead.
|
||||
# @param [String] name The name of the method to retrieve.
|
||||
# @param [Binding] target The context in which to search for the method.
|
||||
# @param [Hash] options
|
||||
# @option options [Boolean] :instance Look for an instance method if `name` doesn't
|
||||
|
@ -40,10 +39,10 @@ class Pry
|
|||
# @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't
|
||||
# contain any context.
|
||||
# @return [Pry::Method, nil] A `Pry::Method` instance containing the requested
|
||||
# method, or `nil` if no method could be located matching the parameters.
|
||||
# method, or `nil` if name is `nil` or no method could be located matching the parameters.
|
||||
def from_str(name, target=TOPLEVEL_BINDING, options={})
|
||||
if name.nil?
|
||||
from_binding(target)
|
||||
nil
|
||||
elsif name.to_s =~ /(.+)\#(\S+)\Z/
|
||||
context, meth_name = $1, $2
|
||||
from_module(target.eval(context), meth_name, target)
|
||||
|
@ -154,7 +153,7 @@ class Pry
|
|||
# @param [Boolean] include_super Whether to include methods from ancestors.
|
||||
# @return [Array[Pry::Method]]
|
||||
def all_from_obj(obj, include_super=true)
|
||||
all_from_class(class << obj; self; end, include_super)
|
||||
all_from_class(singleton_class_of(obj), include_super)
|
||||
end
|
||||
|
||||
# Get every `Class` and `Module`, in order, that will be checked when looking
|
||||
|
@ -193,8 +192,6 @@ class Pry
|
|||
/^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*#{Regexp.escape(name)}/ =~ definition_line.strip
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Get the singleton classes of superclasses that could define methods on
|
||||
# the given class object, and any modules they include.
|
||||
# If a module is included at multiple points in the ancestry, only
|
||||
|
@ -208,7 +205,13 @@ class Pry
|
|||
resolution_order.reverse.uniq.reverse - Class.included_modules
|
||||
end
|
||||
|
||||
def singleton_class_of(obj); class << obj; self; end end
|
||||
def singleton_class_of(obj)
|
||||
begin
|
||||
class << obj; self; end
|
||||
rescue TypeError # can't define singleton. Fixnum, Symbol, Float, ...
|
||||
obj.class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`.
|
||||
|
@ -405,8 +408,6 @@ class Pry
|
|||
end
|
||||
|
||||
# @return [Array<String>] All known aliases for the method.
|
||||
# @note On Ruby 1.8 this method always returns an empty Array for methods
|
||||
# implemented in C.
|
||||
def aliases
|
||||
owner = @method.owner
|
||||
# Avoid using `to_sym` on {Method#name}, which returns a `String`, because
|
||||
|
|
|
@ -97,7 +97,7 @@ module Pry::Pager
|
|||
@out.print "\e[0m" if Pry.color
|
||||
@out.print "<page break> --- Press enter to continue " \
|
||||
"( q<enter> to break ) --- <page break>\n"
|
||||
raise StopPaging if Readline.readline.chomp == "q"
|
||||
raise StopPaging if Readline.readline("").chomp == "q"
|
||||
@tracker.reset
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ class Pry
|
|||
# Does not reload plugin if it's already active.
|
||||
def activate!
|
||||
# Create the configuration object for the plugin.
|
||||
Pry.config.send("#{gem_name.gsub('-', '_')}=", OpenStruct.new)
|
||||
Pry.config.send("#{gem_name.gsub('-', '_')}=", Pry::Config.from_hash({}))
|
||||
|
||||
begin
|
||||
require gem_name if !active?
|
||||
|
|
|
@ -1,15 +1,49 @@
|
|||
require 'ostruct'
|
||||
require 'pry/config'
|
||||
|
||||
class Pry
|
||||
|
||||
# The RC Files to load.
|
||||
HOME_RC_FILE = ENV["PRYRC"] || "~/.pryrc"
|
||||
LOCAL_RC_FILE = "./.pryrc"
|
||||
|
||||
# @return [Hash] Pry's `Thread.current` hash
|
||||
class << self
|
||||
extend Forwardable
|
||||
attr_accessor :custom_completions
|
||||
attr_accessor :current_line
|
||||
attr_accessor :line_buffer
|
||||
attr_accessor :eval_path
|
||||
attr_accessor :cli
|
||||
attr_accessor :quiet
|
||||
attr_accessor :last_internal_error
|
||||
attr_accessor :config
|
||||
attr_writer :history
|
||||
|
||||
def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
|
||||
|
||||
extend Pry::Config::Convenience
|
||||
config_shortcut *Pry::Config.shortcuts
|
||||
|
||||
def prompt=(value)
|
||||
config.prompt = value
|
||||
end
|
||||
|
||||
def prompt
|
||||
config.prompt
|
||||
end
|
||||
|
||||
def history
|
||||
@history ||= History.new
|
||||
end
|
||||
end
|
||||
|
||||
def self.main
|
||||
@main ||= TOPLEVEL_BINDING.eval "self"
|
||||
end
|
||||
|
||||
#
|
||||
# @return [Pry::Config]
|
||||
# Returns a value store for an instance of Pry running on the current thread.
|
||||
#
|
||||
def self.current
|
||||
Thread.current[:__pry__] ||= {}
|
||||
Thread.current[:__pry__] ||= Pry::Config.from_hash({}, nil)
|
||||
end
|
||||
|
||||
# Load the given file in the context of `Pry.toplevel_binding`
|
||||
|
@ -24,7 +58,9 @@ class Pry
|
|||
# This method can also be used to reload the files if they have changed.
|
||||
def self.load_rc_files
|
||||
rc_files_to_load.each do |file|
|
||||
load_file_at_toplevel(file)
|
||||
critical_section do
|
||||
load_file_at_toplevel(file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -62,7 +98,6 @@ class Pry
|
|||
# Including: loading .pryrc, loading plugins, loading requires, and
|
||||
# loading history.
|
||||
def self.initial_session_setup
|
||||
|
||||
return unless initial_session?
|
||||
@initial_session = false
|
||||
|
||||
|
@ -85,6 +120,7 @@ class Pry
|
|||
# Pry.start(Object.new, :input => MyInput.new)
|
||||
def self.start(target=nil, options={})
|
||||
return if ENV['DISABLE_PRY']
|
||||
options = options.to_hash
|
||||
|
||||
if in_critical_section?
|
||||
output.puts "ERROR: Pry started inside Pry."
|
||||
|
@ -93,7 +129,7 @@ class Pry
|
|||
end
|
||||
|
||||
options[:target] = Pry.binding_for(target || toplevel_binding)
|
||||
|
||||
options[:hooks] = Pry::Hooks.from_hash options.delete(:hooks) if options.key?(:hooks)
|
||||
initial_session_setup
|
||||
|
||||
# Unless we were given a backtrace, save the current one
|
||||
|
@ -130,8 +166,10 @@ class Pry
|
|||
def self.view_clip(obj, max_length = 60)
|
||||
if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max_length
|
||||
obj.name.to_s
|
||||
elsif TOPLEVEL_BINDING.eval('self') == obj
|
||||
# special case for 'main' object :)
|
||||
elsif Pry.main == obj
|
||||
# special-case to support jruby.
|
||||
# fixed as of https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039
|
||||
# we can drop in the future.
|
||||
obj.to_s
|
||||
elsif Pry.config.prompt_safe_objects.any? { |v| v === obj } && obj.inspect.length <= max_length
|
||||
obj.inspect
|
||||
|
@ -189,7 +227,6 @@ class Pry
|
|||
def self.default_editor_for_platform
|
||||
return ENV['VISUAL'] if ENV['VISUAL'] and not ENV['VISUAL'].empty?
|
||||
return ENV['EDITOR'] if ENV['EDITOR'] and not ENV['EDITOR'].empty?
|
||||
|
||||
if Helpers::BaseHelpers.windows?
|
||||
'notepad'
|
||||
else
|
||||
|
@ -200,15 +237,22 @@ class Pry
|
|||
end
|
||||
|
||||
def self.auto_resize!
|
||||
ver = Readline::VERSION
|
||||
if ver[/edit/i]
|
||||
Pry.config.input # by default, load Readline
|
||||
|
||||
if !defined?(Readline) || Pry.config.input != Readline
|
||||
warn "Sorry, you must be using Readline for Pry.auto_resize! to work."
|
||||
return
|
||||
end
|
||||
|
||||
if Readline::VERSION =~ /edit/i
|
||||
warn <<-EOT
|
||||
Readline version #{ver} detected - will not auto_resize! correctly.
|
||||
Readline version #{Readline::VERSION} detected - will not auto_resize! correctly.
|
||||
For the fix, use GNU Readline instead:
|
||||
https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X
|
||||
EOT
|
||||
return
|
||||
end
|
||||
|
||||
trap :WINCH do
|
||||
begin
|
||||
Readline.set_screen_size(*Terminal.size!)
|
||||
|
@ -223,105 +267,10 @@ Readline version #{ver} detected - will not auto_resize! correctly.
|
|||
end
|
||||
end
|
||||
|
||||
def self.set_config_defaults
|
||||
config.input = Readline
|
||||
config.output = $stdout
|
||||
config.commands = Pry::Commands
|
||||
config.prompt_name = DEFAULT_PROMPT_NAME
|
||||
config.prompt = DEFAULT_PROMPT
|
||||
config.prompt_safe_objects = DEFAULT_PROMPT_SAFE_OBJECTS
|
||||
config.print = DEFAULT_PRINT
|
||||
config.exception_handler = DEFAULT_EXCEPTION_HANDLER
|
||||
config.exception_whitelist = DEFAULT_EXCEPTION_WHITELIST
|
||||
config.default_window_size = 5
|
||||
config.hooks = DEFAULT_HOOKS
|
||||
config.color = Helpers::BaseHelpers.use_ansi_codes?
|
||||
config.pager = true
|
||||
config.system = DEFAULT_SYSTEM
|
||||
config.editor = default_editor_for_platform
|
||||
config.should_load_rc = true
|
||||
config.should_load_local_rc = true
|
||||
config.should_trap_interrupts = Helpers::BaseHelpers.jruby?
|
||||
config.disable_auto_reload = false
|
||||
config.command_prefix = ""
|
||||
config.auto_indent = Helpers::BaseHelpers.use_ansi_codes?
|
||||
config.correct_indent = true
|
||||
config.collision_warning = false
|
||||
config.output_prefix = "=> "
|
||||
|
||||
if defined?(Bond) && Readline::VERSION !~ /editline/i
|
||||
config.completer = Pry::BondCompleter.start
|
||||
else
|
||||
config.completer = Pry::InputCompleter.start
|
||||
end
|
||||
|
||||
config.gist ||= OpenStruct.new
|
||||
config.gist.inspecter = proc(&:pretty_inspect)
|
||||
|
||||
config.should_load_plugins = true
|
||||
|
||||
config.requires ||= []
|
||||
config.should_load_requires = true
|
||||
|
||||
config.history ||= OpenStruct.new
|
||||
config.history.should_save = true
|
||||
config.history.should_load = true
|
||||
config.history.file = File.expand_path("~/.pry_history") rescue nil
|
||||
|
||||
if config.history.file.nil?
|
||||
config.should_load_rc = false
|
||||
config.history.should_save = false
|
||||
config.history.should_load = false
|
||||
end
|
||||
|
||||
config.control_d_handler = DEFAULT_CONTROL_D_HANDLER
|
||||
|
||||
config.memory_size = 100
|
||||
|
||||
config.extra_sticky_locals = {}
|
||||
|
||||
config.ls ||= OpenStruct.new({
|
||||
:heading_color => :bright_blue,
|
||||
|
||||
:public_method_color => :default,
|
||||
:private_method_color => :blue,
|
||||
:protected_method_color => :blue,
|
||||
:method_missing_color => :bright_red,
|
||||
|
||||
:local_var_color => :yellow,
|
||||
:pry_var_color => :default, # e.g. _, _pry_, _file_
|
||||
|
||||
:instance_var_color => :blue, # e.g. @foo
|
||||
:class_var_color => :bright_blue, # e.g. @@foo
|
||||
|
||||
:global_var_color => :default, # e.g. $CODERAY_DEBUG, $eventmachine_library
|
||||
:builtin_global_color => :cyan, # e.g. $stdin, $-w, $PID
|
||||
:pseudo_global_color => :cyan, # e.g. $~, $1..$9, $LAST_MATCH_INFO
|
||||
|
||||
:constant_color => :default, # e.g. VERSION, ARGF
|
||||
:class_constant_color => :blue, # e.g. Object, Kernel
|
||||
:exception_constant_color => :magenta, # e.g. Exception, RuntimeError
|
||||
:unloaded_constant_color => :yellow, # Any constant that is still in .autoload? state
|
||||
|
||||
# What should separate items listed by ls?
|
||||
:separator => " ",
|
||||
|
||||
# Any methods defined on these classes, or modules included into these classes, will not
|
||||
# be shown by ls unless the -v flag is used.
|
||||
# A user of Rails may wih to add ActiveRecord::Base to the list.
|
||||
# add the following to your .pryrc:
|
||||
# Pry.config.ls.ceiling << ActiveRecord::Base if defined? ActiveRecordBase
|
||||
:ceiling => [Object, Module, Class]
|
||||
})
|
||||
end
|
||||
|
||||
# Set all the configurable options back to their default values
|
||||
def self.reset_defaults
|
||||
set_config_defaults
|
||||
|
||||
@initial_session = true
|
||||
|
||||
self.custom_completions = DEFAULT_CUSTOM_COMPLETIONS
|
||||
self.config = Pry::Config.new Pry::Config::Default.new
|
||||
self.cli = false
|
||||
self.current_line = 1
|
||||
self.line_buffer = [""]
|
||||
|
@ -331,9 +280,6 @@ Readline version #{ver} detected - will not auto_resize! correctly.
|
|||
# Basic initialization.
|
||||
def self.init
|
||||
@plugin_manager ||= PluginManager.new
|
||||
self.config ||= Config.new
|
||||
self.history ||= History.new
|
||||
|
||||
reset_defaults
|
||||
locate_plugins
|
||||
end
|
||||
|
@ -347,7 +293,7 @@ Readline version #{ver} detected - will not auto_resize! correctly.
|
|||
if Binding === target
|
||||
target
|
||||
else
|
||||
if TOPLEVEL_BINDING.eval('self') == target
|
||||
if Pry.main == target
|
||||
TOPLEVEL_BINDING
|
||||
else
|
||||
target.__binding__
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require "pry/indent"
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
##
|
||||
# Pry is a powerful alternative to the standard IRB shell for Ruby. It
|
||||
# features syntax highlighting, a flexible plugin architecture, runtime
|
||||
|
@ -21,54 +20,27 @@ require "pry/indent"
|
|||
# * https://github.com/pry/pry
|
||||
# * the IRC channel, which is #pry on the Freenode network
|
||||
#
|
||||
|
||||
class Pry
|
||||
attr_accessor :input
|
||||
attr_accessor :output
|
||||
attr_accessor :commands
|
||||
attr_accessor :print
|
||||
attr_accessor :exception_handler
|
||||
attr_accessor :quiet
|
||||
alias :quiet? :quiet
|
||||
|
||||
attr_accessor :custom_completions
|
||||
|
||||
attr_accessor :binding_stack
|
||||
attr_accessor :custom_completions
|
||||
attr_accessor :eval_string
|
||||
|
||||
attr_accessor :backtrace
|
||||
attr_accessor :suppress_output
|
||||
attr_accessor :last_result
|
||||
attr_accessor :last_file
|
||||
attr_accessor :last_dir
|
||||
|
||||
attr_reader :last_exception
|
||||
|
||||
attr_reader :command_state
|
||||
attr_reader :exit_value
|
||||
attr_reader :input_array
|
||||
attr_reader :output_array
|
||||
attr_reader :config
|
||||
|
||||
attr_accessor :backtrace
|
||||
|
||||
attr_accessor :extra_sticky_locals
|
||||
|
||||
attr_accessor :suppress_output
|
||||
|
||||
# This is exposed via Pry::Command#state.
|
||||
attr_reader :command_state
|
||||
|
||||
attr_reader :exit_value
|
||||
|
||||
attr_reader :hooks # Special treatment as we want to alert people of the
|
||||
# changed API.
|
||||
|
||||
# FIXME: This is a hack to alert people of the new API.
|
||||
# @param [Pry::Hooks] hooks
|
||||
def hooks=(hooks)
|
||||
if hooks.is_a?(Hash)
|
||||
warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object " \
|
||||
"instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks"
|
||||
@hooks = Pry::Hooks.from_hash(hooks)
|
||||
else
|
||||
@hooks = hooks
|
||||
end
|
||||
end
|
||||
extend Pry::Config::Convenience
|
||||
config_shortcut *Pry::Config.shortcuts
|
||||
EMPTY_COMPLETIONS = [].freeze
|
||||
|
||||
# Create a new {Pry} instance.
|
||||
# @param [Hash] options
|
||||
|
@ -95,62 +67,19 @@ class Pry
|
|||
@indent = Pry::Indent.new
|
||||
@command_state = {}
|
||||
@eval_string = ""
|
||||
@backtrace = options[:backtrace] || caller
|
||||
|
||||
refresh_config(options)
|
||||
|
||||
@backtrace = options.delete(:backtrace) || caller
|
||||
@config = Pry::Config.new
|
||||
config.merge!(options)
|
||||
push_prompt(config.prompt)
|
||||
@input_array = Pry::HistoryArray.new config.memory_size
|
||||
@output_array = Pry::HistoryArray.new config.memory_size
|
||||
@custom_completions = config.command_completions
|
||||
push_initial_binding(options[:target])
|
||||
|
||||
set_last_result nil
|
||||
@input_array << nil # add empty input so _in_ and _out_ match
|
||||
|
||||
# yield the binding_stack to the hook for modification
|
||||
@input_array << nil
|
||||
exec_hook(:when_started, options[:target], options, self)
|
||||
end
|
||||
|
||||
# Refresh the Pry instance settings from the Pry class.
|
||||
# Allows options to be specified to override settings from Pry class.
|
||||
# @param [Hash] options The options to override Pry class settings
|
||||
# for this instance.
|
||||
def refresh_config(options={})
|
||||
defaults = {}
|
||||
attributes = [
|
||||
:input, :output, :commands, :print, :quiet,
|
||||
:exception_handler, :hooks, :custom_completions,
|
||||
:prompt, :memory_size, :extra_sticky_locals
|
||||
]
|
||||
|
||||
attributes.each do |attribute|
|
||||
defaults[attribute] = Pry.send attribute
|
||||
end
|
||||
|
||||
defaults.merge!(options).each do |key, value|
|
||||
send("#{key}=", value) if respond_to?("#{key}=")
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Initialize this instance by pushing its initial context into the binding
|
||||
# stack. If no target is given, start at the top level.
|
||||
def push_initial_binding(target=nil)
|
||||
push_binding(target || Pry.toplevel_binding)
|
||||
end
|
||||
|
||||
# The currently active `Binding`.
|
||||
# @return [Binding] The currently active `Binding` for the session.
|
||||
def current_binding
|
||||
binding_stack.last
|
||||
end
|
||||
alias current_context current_binding # support previous API
|
||||
|
||||
# Push a binding for the given object onto the stack. If this instance is
|
||||
# currently stopped, mark it as usable again.
|
||||
def push_binding(object)
|
||||
@stopped = false
|
||||
binding_stack << Pry.binding_for(object)
|
||||
end
|
||||
|
||||
# The current prompt.
|
||||
# This is the prompt at the top of the prompt stack.
|
||||
#
|
||||
|
@ -171,14 +100,43 @@ class Pry
|
|||
end
|
||||
end
|
||||
|
||||
# Initialize this instance by pushing its initial context into the binding
|
||||
# stack. If no target is given, start at the top level.
|
||||
def push_initial_binding(target=nil)
|
||||
push_binding(target || Pry.toplevel_binding)
|
||||
end
|
||||
|
||||
# The currently active `Binding`.
|
||||
# @return [Binding] The currently active `Binding` for the session.
|
||||
def current_binding
|
||||
binding_stack.last
|
||||
end
|
||||
alias current_context current_binding # support previous API
|
||||
|
||||
# Push a binding for the given object onto the stack. If this instance is
|
||||
# currently stopped, mark it as usable again.
|
||||
def push_binding(object)
|
||||
@stopped = false
|
||||
binding_stack << Pry.binding_for(object)
|
||||
end
|
||||
|
||||
def prompt=(new_prompt)
|
||||
if prompt_stack.empty?
|
||||
push_prompt new_prompt
|
||||
else
|
||||
prompt_stack[-1] = new_prompt
|
||||
end
|
||||
end
|
||||
|
||||
# Generate completions.
|
||||
# @param [String] input What the user has typed so far
|
||||
# @return [Array<String>] Possible completions
|
||||
def complete(input)
|
||||
return EMPTY_COMPLETIONS unless config.completer
|
||||
Pry.critical_section do
|
||||
Pry.config.completer.call(input, :target => current_binding,
|
||||
:pry => self,
|
||||
:custom_completions => instance_eval(&custom_completions))
|
||||
config.completer.call input, :target => current_binding,
|
||||
:pry => self,
|
||||
:custom_completions => custom_completions
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -218,21 +176,19 @@ class Pry
|
|||
# @yield The block that defines the content of the local. The local
|
||||
# will be refreshed at each tick of the repl loop.
|
||||
def add_sticky_local(name, &block)
|
||||
sticky_locals[name] = block
|
||||
config.extra_sticky_locals[name] = block
|
||||
end
|
||||
|
||||
# @return [Hash] The currently defined sticky locals.
|
||||
def sticky_locals
|
||||
@sticky_locals ||= {
|
||||
:_in_ => proc { @input_array },
|
||||
:_out_ => proc { @output_array },
|
||||
:_pry_ => self,
|
||||
:_ex_ => proc { last_exception },
|
||||
:_file_ => proc { last_file },
|
||||
:_dir_ => proc { last_dir },
|
||||
:_ => proc { last_result },
|
||||
:__ => proc { @output_array[-2] }
|
||||
}.merge(extra_sticky_locals)
|
||||
{ _in_: input_array,
|
||||
_out_: output_array,
|
||||
_pry_: self,
|
||||
_ex_: last_exception,
|
||||
_file_: last_file,
|
||||
_dir_: last_dir,
|
||||
_: proc { last_result },
|
||||
__: proc { output_array[-2] }
|
||||
}.merge(config.extra_sticky_locals)
|
||||
end
|
||||
|
||||
# Reset the current eval string. If the user has entered part of a multiline
|
||||
|
@ -286,7 +242,7 @@ class Pry
|
|||
|
||||
def handle_line(line, options)
|
||||
if line.nil?
|
||||
Pry.config.control_d_handler.call(@eval_string, self)
|
||||
config.control_d_handler.call(@eval_string, self)
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -391,7 +347,7 @@ class Pry
|
|||
if last_result_is_exception?
|
||||
exception_handler.call(output, result, self)
|
||||
elsif should_print?
|
||||
print.call(output, result)
|
||||
print.call(output, result, self)
|
||||
else
|
||||
# nothin'
|
||||
end
|
||||
|
@ -568,7 +524,7 @@ class Pry
|
|||
open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last :
|
||||
@indent.stack.last
|
||||
|
||||
c = OpenStruct.new(
|
||||
c = Pry::Config.from_hash({
|
||||
:object => object,
|
||||
:nesting_level => binding_stack.size - 1,
|
||||
:open_token => open_token,
|
||||
|
@ -579,7 +535,7 @@ class Pry
|
|||
:binding_stack => binding_stack,
|
||||
:input_array => input_array,
|
||||
:eval_string => @eval_string,
|
||||
:cont => !@eval_string.empty?)
|
||||
:cont => !@eval_string.empty?})
|
||||
|
||||
Pry.critical_section do
|
||||
# If input buffer is empty then use normal prompt
|
||||
|
|
|
@ -179,10 +179,7 @@ class Pry
|
|||
end
|
||||
end
|
||||
|
||||
if input == Readline
|
||||
if !$stdout.tty? && $stdin.tty? && !Pry::Helpers::BaseHelpers.windows?
|
||||
Readline.output = File.open('/dev/tty', 'w')
|
||||
end
|
||||
if defined?(Readline) and input == Readline
|
||||
input_readline(current_prompt, false) # false since we'll add it manually
|
||||
elsif defined? Coolline and input.is_a? Coolline
|
||||
input_readline(current_prompt)
|
||||
|
|
|
@ -44,6 +44,11 @@ class Pry
|
|||
content.lines.each do |line|
|
||||
break unless _pry_.eval line, :generated => true
|
||||
end
|
||||
|
||||
unless _pry_.eval_string.empty?
|
||||
_pry_.output.puts "#{_pry_.eval_string}...exception encountered, going interactive!"
|
||||
interactive_mode(_pry_)
|
||||
end
|
||||
end
|
||||
|
||||
# Define a few extra commands useful for flipping back & forth
|
||||
|
|
|
@ -44,7 +44,8 @@ class Pry::Terminal
|
|||
require 'io/console'
|
||||
$stdout.winsize if $stdout.tty? and $stdout.respond_to?(:winsize)
|
||||
rescue LoadError
|
||||
# They're probably on 1.8 without the io-console gem. We'll keep trying.
|
||||
# They probably don't have the io/console stdlib or the io-console gem.
|
||||
# We'll keep trying.
|
||||
end
|
||||
|
||||
def screen_size_according_to_env
|
||||
|
@ -53,7 +54,7 @@ class Pry::Terminal
|
|||
end
|
||||
|
||||
def screen_size_according_to_readline
|
||||
if Readline.respond_to?(:get_screen_size)
|
||||
if defined?(Readline) && Readline.respond_to?(:get_screen_size)
|
||||
size = Readline.get_screen_size
|
||||
size if nonzero_column?(size)
|
||||
end
|
||||
|
|
|
@ -47,10 +47,6 @@ module PryTestHelpers
|
|||
end
|
||||
end
|
||||
|
||||
def mri18_and_no_real_source_location?
|
||||
Pry::Helpers::BaseHelpers.mri_18? && !(Method.instance_method(:source_location).owner == Method)
|
||||
end
|
||||
|
||||
# Open a temp file and yield it to the block, closing it after
|
||||
# @return [String] The path of the temp file
|
||||
def temp_file(ext='.rb')
|
||||
|
|
|
@ -66,28 +66,12 @@ class Pry
|
|||
end
|
||||
|
||||
# Returns an array of the names of the constants accessible in the wrapped
|
||||
# module. This provides a consistent interface between 1.8 and 1.9 and also
|
||||
# avoids the problem of accidentally calling the singleton method
|
||||
# `Module.constants`.
|
||||
# module. This avoids the problem of accidentally calling the singleton
|
||||
# method `Module.constants`.
|
||||
# @param [Boolean] inherit Include the names of constants from included
|
||||
# modules?
|
||||
def constants(inherit = true)
|
||||
method = Module.instance_method(:constants).bind(@wrapped)
|
||||
|
||||
# If we're on 1.8, we have to manually remove ancestors' constants. If
|
||||
# we're on 1.9, though, it's better to use the built-in `inherit` param,
|
||||
# since it doesn't do things like incorrectly remove Pry::Config.
|
||||
if method.arity == 0
|
||||
consts = method.call
|
||||
if !inherit
|
||||
ancestors_ = Pry::Method.safe_send(@wrapped, :ancestors)
|
||||
consts -= (ancestors_ - [@wrapped]).map(&:constants).flatten
|
||||
end
|
||||
else
|
||||
consts = method.call(inherit)
|
||||
end
|
||||
|
||||
consts
|
||||
Module.instance_method(:constants).bind(@wrapped).call(inherit)
|
||||
end
|
||||
|
||||
# The prefix that would appear before methods defined on this class.
|
||||
|
@ -259,7 +243,7 @@ class Pry
|
|||
# @return [Enumerator, Array] on JRuby 1.9 and higher returns Array, on
|
||||
# other rubies returns Enumerator
|
||||
def candidates
|
||||
enum = generator.new do |y|
|
||||
enum = Enumerator.new do |y|
|
||||
(0...number_of_candidates).each do |num|
|
||||
y.yield candidate(num)
|
||||
end
|
||||
|
@ -292,18 +276,6 @@ class Pry
|
|||
|
||||
private
|
||||
|
||||
# Ruby 1.8 doesn't support `Enumerator` (it's called Generator instead)
|
||||
#
|
||||
# @return [Object] Return the appropriate generator class.
|
||||
def generator
|
||||
@generator ||= if defined?(Enumerator)
|
||||
Enumerator
|
||||
else
|
||||
require 'generator'
|
||||
Generator
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Pry::WrappedModule::Candidate] The candidate with the
|
||||
# highest rank, that is the 'monkey patch' of this module with the
|
||||
# highest number of methods, which contains a source code line that
|
||||
|
@ -367,22 +339,7 @@ class Pry
|
|||
# given module.
|
||||
# @return [Array<Pry::Method>]
|
||||
def all_methods_for(mod)
|
||||
all_from_common(mod, :instance_method) + all_from_common(mod, :method)
|
||||
end
|
||||
|
||||
# FIXME: a variant of this method is also found in Pry::Method
|
||||
def all_from_common(mod, method_type)
|
||||
%w(public protected private).map do |visibility|
|
||||
safe_send(mod, :"#{visibility}_#{method_type}s", false).select do |method_name|
|
||||
if method_type == :method
|
||||
safe_send(mod, method_type, method_name).owner == class << mod; self; end
|
||||
else
|
||||
safe_send(mod, method_type, method_name).owner == mod
|
||||
end
|
||||
end.map do |method_name|
|
||||
Pry::Method.new(safe_send(mod, method_type, method_name), :visibility => visibility.to_sym)
|
||||
end
|
||||
end.flatten
|
||||
Pry::Method.all_from_obj(mod, false) + Pry::Method.all_from_class(mod, false)
|
||||
end
|
||||
|
||||
def nested_module?(parent, name)
|
||||
|
|
|
@ -27,5 +27,5 @@ Gem::Specification.new do |s|
|
|||
s.add_development_dependency 'mocha', '~> 0.13.1'
|
||||
s.add_development_dependency 'simplecov'
|
||||
# TODO: make this a plain dependency:
|
||||
s.add_development_dependency 'bond', '~> 0.4.2'
|
||||
s.add_development_dependency 'bond', '~> 0.5.0'
|
||||
end
|
||||
|
|
|
@ -60,7 +60,7 @@ describe Pry::Hooks do
|
|||
|
||||
Pry::CLI.add_options do
|
||||
on :optiontest, "A test option"
|
||||
end.process_options do |opts|
|
||||
end.add_option_processor do |opts|
|
||||
run = true if opts.present?(:optiontest)
|
||||
end.parse_options(["--optiontest"])
|
||||
|
||||
|
@ -74,9 +74,9 @@ describe Pry::Hooks do
|
|||
Pry::CLI.add_options do
|
||||
on :optiontest, "A test option"
|
||||
on :optiontest2, "Another test option"
|
||||
end.process_options do |opts|
|
||||
end.add_option_processor do |opts|
|
||||
run = true if opts.present?(:optiontest)
|
||||
end.process_options do |opts|
|
||||
end.add_option_processor do |opts|
|
||||
run2 = true if opts.present?(:optiontest2)
|
||||
end.parse_options(["--optiontest", "--optiontest2"])
|
||||
|
||||
|
|
|
@ -473,22 +473,23 @@ describe "commands" do
|
|||
end
|
||||
end
|
||||
|
||||
klass.commands.include?("nesting").should == true
|
||||
klass.commands.include?("jump-to").should == true
|
||||
klass.commands.include?("cd").should == true
|
||||
klass.commands.include?("v").should == true
|
||||
klass.to_hash.include?("nesting").should == true
|
||||
klass.to_hash.include?("jump-to").should == true
|
||||
klass.to_hash.include?("cd").should == true
|
||||
klass.to_hash.include?("v").should == true
|
||||
end
|
||||
|
||||
it 'should change description of a command using desc' do
|
||||
klass = Pry::CommandSet.new do
|
||||
import Pry::Commands
|
||||
end
|
||||
orig = klass.commands["help"].description
|
||||
orig = klass["help"].description
|
||||
klass.instance_eval do
|
||||
desc "help", "blah"
|
||||
end
|
||||
klass.commands["help"].description.should.not == orig
|
||||
klass.commands["help"].description.should == "blah"
|
||||
commands = klass.to_hash
|
||||
commands["help"].description.should.not == orig
|
||||
commands["help"].description.should == "blah"
|
||||
end
|
||||
|
||||
it 'should enable an inherited method to access opts and output and target, due to instance_exec' do
|
||||
|
@ -512,8 +513,8 @@ describe "commands" do
|
|||
import_from Pry::Commands, "ls", "jump-to"
|
||||
end
|
||||
|
||||
klass.commands.include?("ls").should == true
|
||||
klass.commands.include?("jump-to").should == true
|
||||
klass.to_hash.include?("ls").should == true
|
||||
klass.to_hash.include?("jump-to").should == true
|
||||
end
|
||||
|
||||
it 'should delete some inherited commands when using delete method' do
|
||||
|
@ -525,13 +526,14 @@ describe "commands" do
|
|||
delete "ls"
|
||||
end
|
||||
|
||||
klass.commands.include?("nesting").should == true
|
||||
klass.commands.include?("jump-to").should == true
|
||||
klass.commands.include?("cd").should == true
|
||||
klass.commands.include?("v").should == true
|
||||
klass.commands.include?("show-doc").should == false
|
||||
klass.commands.include?("show-method").should == false
|
||||
klass.commands.include?("ls").should == false
|
||||
commands = klass.to_hash
|
||||
commands.include?("nesting").should == true
|
||||
commands.include?("jump-to").should == true
|
||||
commands.include?("cd").should == true
|
||||
commands.include?("v").should == true
|
||||
commands.include?("show-doc").should == false
|
||||
commands.include?("show-method").should == false
|
||||
commands.include?("ls").should == false
|
||||
end
|
||||
|
||||
it 'should override some inherited commands' do
|
||||
|
|
|
@ -167,7 +167,7 @@ describe Pry::CommandSet do
|
|||
|
||||
it 'should set the descriptions of commands' do
|
||||
@set.command('foo', 'some stuff') {}
|
||||
@set.commands['foo'].description.should == 'some stuff'
|
||||
@set['foo'].description.should == 'some stuff'
|
||||
end
|
||||
|
||||
describe "aliases" do
|
||||
|
@ -176,8 +176,8 @@ describe Pry::CommandSet do
|
|||
@set.command('foo', 'stuff') { run = true }
|
||||
|
||||
@set.alias_command 'bar', 'foo'
|
||||
@set.commands['bar'].match.should == 'bar'
|
||||
@set.commands['bar'].description.should == 'Alias for `foo`'
|
||||
@set['bar'].match.should == 'bar'
|
||||
@set['bar'].description.should == 'Alias for `foo`'
|
||||
|
||||
@set.run_command @ctx, 'bar'
|
||||
run.should == true
|
||||
|
@ -203,12 +203,12 @@ describe Pry::CommandSet do
|
|||
@set.command('foo', 'stuff', :shellwords => true, :interpolate => false) { run = true }
|
||||
|
||||
@set.alias_command 'bar', 'foo'
|
||||
@set.commands['bar'].options[:shellwords].should == @set.commands['foo'].options[:shellwords]
|
||||
@set.commands['bar'].options[:interpolate].should == @set.commands['foo'].options[:interpolate]
|
||||
@set['bar'].options[:shellwords].should == @set['foo'].options[:shellwords]
|
||||
@set['bar'].options[:interpolate].should == @set['foo'].options[:interpolate]
|
||||
|
||||
# however some options should not be inherited
|
||||
@set.commands['bar'].options[:listing].should.not == @set.commands['foo'].options[:listing]
|
||||
@set.commands['bar'].options[:listing].should == "bar"
|
||||
@set['bar'].options[:listing].should.not == @set['foo'].options[:listing]
|
||||
@set['bar'].options[:listing].should == "bar"
|
||||
end
|
||||
|
||||
it 'should be able to specify alias\'s description when aliasing' do
|
||||
|
@ -216,8 +216,8 @@ describe Pry::CommandSet do
|
|||
@set.command('foo', 'stuff') { run = true }
|
||||
|
||||
@set.alias_command 'bar', 'foo', :desc => "tobina"
|
||||
@set.commands['bar'].match.should == 'bar'
|
||||
@set.commands['bar'].description.should == "tobina"
|
||||
@set['bar'].match.should == 'bar'
|
||||
@set['bar'].description.should == "tobina"
|
||||
|
||||
@set.run_command @ctx, 'bar'
|
||||
run.should == true
|
||||
|
@ -228,8 +228,8 @@ describe Pry::CommandSet do
|
|||
@set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
|
||||
|
||||
@set.alias_command 'bar', 'foo1'
|
||||
@set.commands['bar'].match.should == 'bar'
|
||||
@set.commands['bar'].description.should == 'Alias for `foo1`'
|
||||
@set['bar'].match.should == 'bar'
|
||||
@set['bar'].description.should == 'Alias for `foo1`'
|
||||
|
||||
@set.run_command @ctx, 'bar'
|
||||
run.should == true
|
||||
|
@ -240,7 +240,7 @@ describe Pry::CommandSet do
|
|||
@set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
|
||||
|
||||
@set.alias_command /^b.r/, 'foo1', :listing => "bar"
|
||||
@set.commands[/^b.r/].options[:listing].should == "bar"
|
||||
@set.to_hash[/^b.r/].options[:listing].should == "bar"
|
||||
end
|
||||
|
||||
it "should set description to default if description parameter is nil" do
|
||||
|
@ -248,7 +248,7 @@ describe Pry::CommandSet do
|
|||
@set.command(/^foo1/, 'stuff', :listing => 'foo') { run = true }
|
||||
|
||||
@set.alias_command "bar", 'foo1'
|
||||
@set.commands["bar"].description.should == "Alias for `foo1`"
|
||||
@set["bar"].description.should == "Alias for `foo1`"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -256,7 +256,7 @@ describe Pry::CommandSet do
|
|||
@set.command('foo', 'bar') {}
|
||||
@set.desc 'foo', 'baz'
|
||||
|
||||
@set.commands['foo'].description.should == 'baz'
|
||||
@set['foo'].description.should == 'baz'
|
||||
end
|
||||
|
||||
it 'should get the descriptions of commands' do
|
||||
|
@ -342,12 +342,12 @@ describe Pry::CommandSet do
|
|||
|
||||
it 'should provide a :listing for a command that defaults to its name' do
|
||||
@set.command 'foo', "" do;end
|
||||
@set.commands['foo'].options[:listing].should == 'foo'
|
||||
@set['foo'].options[:listing].should == 'foo'
|
||||
end
|
||||
|
||||
it 'should provide a :listing for a command that differs from its name' do
|
||||
@set.command 'foo', "", :listing => 'bar' do;end
|
||||
@set.commands['foo'].options[:listing].should == 'bar'
|
||||
@set['foo'].options[:listing].should == 'bar'
|
||||
end
|
||||
|
||||
it "should provide a 'help' command" do
|
||||
|
@ -392,9 +392,9 @@ describe Pry::CommandSet do
|
|||
listing = "bing"
|
||||
@set.command('foo') { }
|
||||
@set.rename_command('bar', 'foo', :description => desc, :listing => listing, :keep_retval => true)
|
||||
@set.commands['bar'].description.should == desc
|
||||
@set.commands['bar'].options[:listing].should == listing
|
||||
@set.commands['bar'].options[:keep_retval].should == true
|
||||
@set['bar'].description.should == desc
|
||||
@set['bar'].options[:listing].should == listing
|
||||
@set['bar'].options[:keep_retval].should == true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ describe "Pry::Command" do
|
|||
#
|
||||
end
|
||||
|
||||
mock_command(@set.commands['help'], %w(oolon-colluphid), :command_set => @set).output.should =~ /Raving Atheist/
|
||||
mock_command(@set['help'], %w(oolon-colluphid), :command_set => @set).output.should =~ /Raving Atheist/
|
||||
end
|
||||
|
||||
it 'should use slop to generate the help for classy commands' do
|
||||
|
@ -104,7 +104,7 @@ describe "Pry::Command" do
|
|||
end
|
||||
end
|
||||
|
||||
mock_command(@set.commands['help'], %w(eddie), :command_set => @set).output.should =~ /Over-cheerful/
|
||||
mock_command(@set['help'], %w(eddie), :command_set => @set).output.should =~ /Over-cheerful/
|
||||
end
|
||||
|
||||
it 'should provide --help for classy commands' do
|
||||
|
@ -664,10 +664,8 @@ describe "Pry::Command" do
|
|||
pry_eval('my---test').should =~ /my-testmy-test/
|
||||
end
|
||||
|
||||
if !mri18_and_no_real_source_location?
|
||||
it "shows the source of the process method" do
|
||||
pry_eval('show-source my-test').should =~ /output.puts command_name/
|
||||
end
|
||||
it "shows the source of the process method" do
|
||||
pry_eval('show-source my-test').should =~ /output.puts command_name/
|
||||
end
|
||||
|
||||
describe "command options hash" do
|
||||
|
@ -805,17 +803,17 @@ describe "Pry::Command" do
|
|||
end
|
||||
|
||||
it 'should be correct for default commands' do
|
||||
@set.commands["help"].group.should == "Help"
|
||||
@set["help"].group.should == "Help"
|
||||
end
|
||||
|
||||
it 'should not change once it is initialized' do
|
||||
@set.commands["magic"].group("-==CD COMMAND==-")
|
||||
@set.commands["magic"].group.should == "Not for a public use"
|
||||
@set["magic"].group("-==CD COMMAND==-")
|
||||
@set["magic"].group.should == "Not for a public use"
|
||||
end
|
||||
|
||||
it 'should not disappear after the call without parameters' do
|
||||
@set.commands["magic"].group
|
||||
@set.commands["magic"].group.should == "Not for a public use"
|
||||
@set["magic"].group
|
||||
@set["magic"].group.should == "Not for a public use"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,6 +35,16 @@ describe "edit" do
|
|||
FileUtils.rm(@tf_path) if File.exists?(@tf_path)
|
||||
end
|
||||
|
||||
it "should not allow patching any known kind of file" do
|
||||
["file.rb", "file.c", "file.py", "file.yml", "file.gemspec",
|
||||
"/tmp/file", "\\\\Temp\\\\file"].each do |file|
|
||||
proc {
|
||||
pry_eval "edit -p #{file}"
|
||||
}.should.raise(NotImplementedError).
|
||||
message.should =~ /Cannot yet patch false objects!/
|
||||
end
|
||||
end
|
||||
|
||||
it "should invoke Pry.config.editor with absolutified filenames" do
|
||||
pry_eval 'edit lib/pry.rb'
|
||||
@file.should == File.expand_path('lib/pry.rb')
|
||||
|
|
|
@ -1,70 +1,63 @@
|
|||
require 'helper'
|
||||
|
||||
# we turn off the test for MRI 1.8 because our source_location hack
|
||||
# for C methods actually runs the methods - and since it runs ALL
|
||||
# methods (in an attempt to find a match) it runs 'exit' and aborts
|
||||
# the test, causing a failure. We should fix this in the future by
|
||||
# blacklisting certain methods for 1.8 MRI (such as exit, fork, and so on)
|
||||
unless Pry::Helpers::BaseHelpers.mri_18?
|
||||
MyKlass = Class.new do
|
||||
def hello
|
||||
"timothy"
|
||||
MyKlass = Class.new do
|
||||
def hello
|
||||
"timothy"
|
||||
end
|
||||
def goodbye
|
||||
"jenny"
|
||||
end
|
||||
def tea_tim?
|
||||
"timothy"
|
||||
end
|
||||
def tea_time?
|
||||
"polly"
|
||||
end
|
||||
end
|
||||
|
||||
describe "find-method" do
|
||||
describe "find matching methods by name regex (-n option)" do
|
||||
it "should find a method by regex" do
|
||||
pry_eval("find-method hell MyKlass").should =~
|
||||
/MyKlass.*?hello/m
|
||||
end
|
||||
def goodbye
|
||||
"jenny"
|
||||
end
|
||||
def tea_tim?
|
||||
"timothy"
|
||||
end
|
||||
def tea_time?
|
||||
"polly"
|
||||
|
||||
it "should NOT match a method that does not match the regex" do
|
||||
pry_eval("find-method hell MyKlass").should.not =~
|
||||
/MyKlass.*?goodbye/m
|
||||
end
|
||||
end
|
||||
|
||||
describe "find-method" do
|
||||
describe "find matching methods by name regex (-n option)" do
|
||||
it "should find a method by regex" do
|
||||
pry_eval("find-method hell MyKlass").should =~
|
||||
/MyKlass.*?hello/m
|
||||
end
|
||||
|
||||
it "should NOT match a method that does not match the regex" do
|
||||
pry_eval("find-method hell MyKlass").should.not =~
|
||||
/MyKlass.*?goodbye/m
|
||||
end
|
||||
end
|
||||
|
||||
describe "find matching methods by content regex (-c option)" do
|
||||
it "should find a method by regex" do
|
||||
pry_eval("find-method -c timothy MyKlass").should =~
|
||||
/MyKlass.*?hello/m
|
||||
end
|
||||
|
||||
it "should NOT match a method that does not match the regex" do
|
||||
pry_eval("find-method timothy MyKlass").should.not =~
|
||||
/MyKlass.*?goodbye/m
|
||||
end
|
||||
end
|
||||
|
||||
it "should work with badly behaved constants" do
|
||||
MyKlass::X = Object.new
|
||||
def (MyKlass::X).hash
|
||||
raise "mooo"
|
||||
end
|
||||
|
||||
describe "find matching methods by content regex (-c option)" do
|
||||
it "should find a method by regex" do
|
||||
pry_eval("find-method -c timothy MyKlass").should =~
|
||||
/MyKlass.*?hello/m
|
||||
end
|
||||
|
||||
it "should escape regexes correctly" do
|
||||
good = /tea_time\?/
|
||||
bad = /tea_tim\?/
|
||||
pry_eval('find-method tea_time? MyKlass').should =~ good
|
||||
pry_eval('find-method tea_time? MyKlass').should =~ good
|
||||
pry_eval('find-method tea_time\? MyKlass').should.not =~ bad
|
||||
pry_eval('find-method tea_time\? MyKlass').should =~ good
|
||||
it "should NOT match a method that does not match the regex" do
|
||||
pry_eval("find-method timothy MyKlass").should.not =~
|
||||
/MyKlass.*?goodbye/m
|
||||
end
|
||||
end
|
||||
|
||||
Object.remove_const(:MyKlass)
|
||||
it "should work with badly behaved constants" do
|
||||
MyKlass::X = Object.new
|
||||
def (MyKlass::X).hash
|
||||
raise "mooo"
|
||||
end
|
||||
|
||||
pry_eval("find-method -c timothy MyKlass").should =~
|
||||
/MyKlass.*?hello/m
|
||||
end
|
||||
|
||||
it "should escape regexes correctly" do
|
||||
good = /tea_time\?/
|
||||
bad = /tea_tim\?/
|
||||
pry_eval('find-method tea_time? MyKlass').should =~ good
|
||||
pry_eval('find-method tea_time? MyKlass').should =~ good
|
||||
pry_eval('find-method tea_time\? MyKlass').should.not =~ bad
|
||||
pry_eval('find-method tea_time\? MyKlass').should =~ good
|
||||
end
|
||||
end
|
||||
|
||||
Object.remove_const(:MyKlass)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
require 'helper'
|
||||
|
||||
describe "gem-list" do
|
||||
# fixing bug for 1.8 compat
|
||||
it 'should not raise when invoked' do
|
||||
proc {
|
||||
pry_eval(self, 'gem-list')
|
||||
|
|
|
@ -34,18 +34,22 @@ describe "ls" do
|
|||
end
|
||||
end
|
||||
|
||||
if defined?(BasicObject)
|
||||
describe "BasicObject" do
|
||||
it "should work on BasicObject" do
|
||||
pry_eval("ls BasicObject.new").should =~ /BasicObject#methods:.*__send__/m
|
||||
end
|
||||
describe "BasicObject" do
|
||||
it "should work on BasicObject" do
|
||||
pry_eval("ls BasicObject.new").should =~ /BasicObject#methods:.*__send__/m
|
||||
end
|
||||
|
||||
it "should work on subclasses of BasicObject" do
|
||||
pry_eval(
|
||||
"class LessBasic < BasicObject; def jaroussky; 5; end; end",
|
||||
"ls LessBasic.new"
|
||||
).should =~ /LessBasic#methods:.*jaroussky/m
|
||||
end
|
||||
it "should work on subclasses of BasicObject" do
|
||||
pry_eval(
|
||||
"class LessBasic < BasicObject; def jaroussky; 5; end; end",
|
||||
"ls LessBasic.new"
|
||||
).should =~ /LessBasic#methods:.*jaroussky/m
|
||||
end
|
||||
end
|
||||
|
||||
describe "immediates" do
|
||||
it "should work on Fixnum" do
|
||||
pry_eval("ls 5").should =~ /Fixnum#methods:.*modulo/m
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -92,6 +96,11 @@ describe "ls" do
|
|||
test.should.not.raise
|
||||
end
|
||||
|
||||
it "should show error message when instance is given with -M option" do
|
||||
error = lambda{ pry_eval("ls -M String.new") }.should.raise(Pry::CommandError)
|
||||
error.message.should.match(/-M only makes sense with a Module or a Class/)
|
||||
end
|
||||
|
||||
|
||||
# see: https://travis-ci.org/pry/pry/jobs/5071918
|
||||
unless Pry::Helpers::BaseHelpers.rbx?
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
119
spec/commands/watch_expression_spec.rb
Normal file
119
spec/commands/watch_expression_spec.rb
Normal file
|
@ -0,0 +1,119 @@
|
|||
require 'helper'
|
||||
|
||||
describe "watch expression" do
|
||||
|
||||
# Custom eval that will:
|
||||
# 1) Create an instance of pry that can use for multiple calls
|
||||
# 2) Exercise the after_eval hook
|
||||
# 3) Return the output
|
||||
def eval(expr)
|
||||
output = @tester.eval expr
|
||||
@tester.pry.hooks.exec_hook :after_eval, nil, @tester.pry
|
||||
output
|
||||
end
|
||||
|
||||
before do
|
||||
@tester = pry_tester
|
||||
@tester.pry.hooks.clear :after_eval
|
||||
eval "watch --delete"
|
||||
end
|
||||
|
||||
it "registers the after_eval hook" do
|
||||
eval 'watch 1+1'
|
||||
@tester.pry.hooks.hook_exists?(:after_eval, :watch_expression).should == true
|
||||
end
|
||||
|
||||
it "prints no watched expressions" do
|
||||
eval('watch').should =~ /No watched expressions/
|
||||
end
|
||||
|
||||
it "watches an expression" do
|
||||
eval "watch 1+1"
|
||||
eval('watch').should =~ /=> 2/
|
||||
end
|
||||
|
||||
it "watches a local variable" do
|
||||
eval 'foo = :bar'
|
||||
eval 'watch foo'
|
||||
eval('watch').should =~ /=> :bar/
|
||||
end
|
||||
|
||||
it "prints when an expression changes" do
|
||||
ReplTester.start do
|
||||
input 'a = 1'
|
||||
output '=> 1'
|
||||
|
||||
input 'watch a'
|
||||
output "Watching a\nwatch: a => 1"
|
||||
|
||||
input "a = 2"
|
||||
output "watch: a => 2\n=> 2"
|
||||
end
|
||||
end
|
||||
|
||||
it "prints when an expression is mutated" do
|
||||
ReplTester.start do
|
||||
input 'a = "one"'
|
||||
output '=> "one"'
|
||||
|
||||
input 'watch a'
|
||||
output %(Watching a\nwatch: a => "one")
|
||||
|
||||
input "a.sub! 'o', 'p'"
|
||||
output %(watch: a => "pne"\n=> "pne")
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't print when an expresison remains the same" do
|
||||
ReplTester.start do
|
||||
input 'a = 1'
|
||||
output '=> 1'
|
||||
|
||||
input 'watch a'
|
||||
output "Watching a\nwatch: a => 1"
|
||||
|
||||
input "a = 1"
|
||||
output "=> 1"
|
||||
end
|
||||
end
|
||||
|
||||
it "continues to work if you start a second pry instance" do
|
||||
ReplTester.start do
|
||||
input 'a = 1'
|
||||
output '=> 1'
|
||||
|
||||
input 'watch a'
|
||||
output "Watching a\nwatch: a => 1"
|
||||
|
||||
input "a = 2"
|
||||
output "watch: a => 2\n=> 2"
|
||||
end
|
||||
|
||||
ReplTester.start do
|
||||
input 'b = 1'
|
||||
output '=> 1'
|
||||
|
||||
input 'watch b'
|
||||
output "Watching b\nwatch: b => 1"
|
||||
|
||||
input "b = 2"
|
||||
output "watch: b => 2\n=> 2"
|
||||
end
|
||||
end
|
||||
|
||||
describe "deleting expressions" do
|
||||
before do
|
||||
eval 'watch :keeper'
|
||||
eval 'watch :delete'
|
||||
eval 'watch -d 2'
|
||||
end
|
||||
|
||||
it "keeps keeper" do
|
||||
eval('watch').should =~ /keeper/
|
||||
end
|
||||
|
||||
it "deletes delete" do
|
||||
eval('watch').should.not =~ /delete/
|
||||
end
|
||||
end
|
||||
end
|
|
@ -41,16 +41,14 @@ describe "whereami" do
|
|||
Object.remove_const(:Cor)
|
||||
end
|
||||
|
||||
if defined?(BasicObject)
|
||||
it 'should work in BasicObjects' do
|
||||
cor = Class.new(BasicObject) do
|
||||
def blimey!
|
||||
::Kernel.binding # omnom
|
||||
end
|
||||
end.new.blimey!
|
||||
it 'should work in BasicObjects' do
|
||||
cor = Class.new(BasicObject) do
|
||||
def blimey!
|
||||
::Kernel.binding # omnom
|
||||
end
|
||||
end.new.blimey!
|
||||
|
||||
pry_eval(cor, 'whereami').should =~ /::Kernel.binding [#] omnom/
|
||||
end
|
||||
pry_eval(cor, 'whereami').should =~ /::Kernel.binding [#] omnom/
|
||||
end
|
||||
|
||||
it 'should show description and correct code when __LINE__ and __FILE__ are outside @method.source_location' do
|
||||
|
|
|
@ -6,16 +6,22 @@ def completer_test(bind, pry=nil, assert_flag=true)
|
|||
return proc {|*symbols| symbols.each(&test) }
|
||||
end
|
||||
|
||||
if defined?(Bond) && Readline::VERSION !~ /editline/i
|
||||
describe 'bond-based completion' do
|
||||
it 'should pull in Bond by default' do
|
||||
Pry.config.completer.should == Pry::BondCompleter
|
||||
describe 'Bond-based completion' do
|
||||
before do
|
||||
@local = Pry::Config.new Pry::Config::Default.new
|
||||
@local.completer
|
||||
end
|
||||
|
||||
it "should use Bond if it's available" do
|
||||
if defined?(Bond) && defined?(Readline) && Readline::VERSION !~ /editline/i
|
||||
@local.completer.should == Pry::BondCompleter
|
||||
else
|
||||
@local.completer.should == Pry::InputCompleter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Pry::InputCompleter do
|
||||
|
||||
before do
|
||||
# The AMQP gem has some classes like this:
|
||||
# pry(main)> AMQP::Protocol::Test::ContentOk.name
|
||||
|
|
122
spec/config_spec.rb
Normal file
122
spec/config_spec.rb
Normal file
|
@ -0,0 +1,122 @@
|
|||
require 'helper'
|
||||
|
||||
describe Pry::Config do
|
||||
describe "reserved keys" do
|
||||
it "raises an ArgumentError on assignment of a reserved key" do
|
||||
local = Pry::Config.from_hash({})
|
||||
Pry::Config::RESERVED_KEYS.each do |key|
|
||||
should.raise(ArgumentError) { local[key] = 1 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "traversal to parent" do
|
||||
it "traverses back to the parent when a local key is not found" do
|
||||
local = Pry::Config.new Pry::Config.from_hash(foo: 1)
|
||||
local.foo.should == 1
|
||||
end
|
||||
|
||||
it "stores a local key and prevents traversal to the parent" do
|
||||
local = Pry::Config.new Pry::Config.from_hash(foo: 1)
|
||||
local.foo = 2
|
||||
local.foo.should == 2
|
||||
end
|
||||
|
||||
it "duplicates a copy on read from the parent" do
|
||||
ukraine = "i love"
|
||||
local = Pry::Config.new Pry::Config.from_hash(home: ukraine)
|
||||
local.home.equal?(ukraine).should == false
|
||||
end
|
||||
|
||||
it "traverses through a chain of parents" do
|
||||
root = Pry::Config.from_hash({foo: 21})
|
||||
local1 = Pry::Config.new(root)
|
||||
local2 = Pry::Config.new(local1)
|
||||
local3 = Pry::Config.new(local2)
|
||||
local3.foo.should == 21
|
||||
end
|
||||
end
|
||||
|
||||
describe ".from_hash" do
|
||||
it "returns an object without a default when given 1 argument" do
|
||||
local = Pry::Config.from_hash({})
|
||||
local.instance_variable_get(:@default).should == nil
|
||||
end
|
||||
|
||||
it "returns an object with a default when given 2 arguments" do
|
||||
default = Pry::Config.new(nil)
|
||||
local = Pry::Config.from_hash({}, default)
|
||||
local.instance_variable_get(:@default).should == default
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "#keys" do
|
||||
it "returns an array of local keys" do
|
||||
root = Pry::Config.from_hash({zoo: "boo"}, nil)
|
||||
local = Pry::Config.from_hash({foo: "bar"}, root)
|
||||
local.keys.should == ["foo"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#==" do
|
||||
it "compares equality through the underlying lookup table" do
|
||||
local1 = Pry::Config.new(nil)
|
||||
local2 = Pry::Config.new(nil)
|
||||
local1.foo = "hi"
|
||||
local2.foo = "hi"
|
||||
local1.should == local2
|
||||
end
|
||||
|
||||
it "compares equality against an object who does not implement #to_hash" do
|
||||
local1 = Pry::Config.new(nil)
|
||||
local1.should.not == Object.new
|
||||
end
|
||||
end
|
||||
|
||||
describe "#forget" do
|
||||
it "forgets a local key" do
|
||||
local = Pry::Config.new Pry::Config.from_hash(foo: 1)
|
||||
local.foo = 2
|
||||
local.foo.should == 2
|
||||
local.forget(:foo)
|
||||
local.foo.should == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_hash" do
|
||||
it "provides a copy of local key & value pairs as a Hash" do
|
||||
local = Pry::Config.new Pry::Config.from_hash(bar: true)
|
||||
local.foo = "21"
|
||||
local.to_hash.should == { "foo" => "21" }
|
||||
end
|
||||
|
||||
it "returns a duplicate of the lookup table" do
|
||||
local = Pry::Config.new(nil)
|
||||
local.to_hash.merge!("foo" => 42)
|
||||
local.foo.should.not == 42
|
||||
end
|
||||
end
|
||||
|
||||
describe "#merge!" do
|
||||
it "can merge a Hash-like object" do
|
||||
local = Pry::Config.new(nil)
|
||||
local.merge! Pry::Config.from_hash(foo: 21)
|
||||
local.foo.should == 21
|
||||
end
|
||||
|
||||
it "can merge a Hash" do
|
||||
local = Pry::Config.new(nil)
|
||||
local.merge!(foo: 21)
|
||||
local.foo.should == 21
|
||||
end
|
||||
end
|
||||
|
||||
describe "#[]=" do
|
||||
it "stores keys as strings" do
|
||||
local = Pry::Config.from_hash({})
|
||||
local[:zoo] = "hello"
|
||||
local.to_hash.should == { "zoo" => "hello" }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,11 +9,11 @@ unless Object.const_defined? 'Pry'
|
|||
end
|
||||
|
||||
require 'mocha/api'
|
||||
|
||||
require "ostruct"
|
||||
require 'pry/test/helper'
|
||||
require 'helpers/bacon'
|
||||
require 'helpers/mock_pry'
|
||||
require 'helpers/repl_tester'
|
||||
require 'spec_helpers/bacon'
|
||||
require 'spec_helpers/mock_pry'
|
||||
require 'spec_helpers/repl_tester'
|
||||
|
||||
class Module
|
||||
public :remove_const
|
||||
|
|
17
spec/isolation/readline_spec.rb
Normal file
17
spec/isolation/readline_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
require "bundler/setup"
|
||||
require "bacon"
|
||||
describe "Readline" do
|
||||
describe "on require of 'pry'" do
|
||||
it "is not made available" do
|
||||
require('pry').should.be.true
|
||||
defined?(Readline).should.be.nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "on invoke of 'pry'" do
|
||||
it "is made available" do
|
||||
Pry.start self, input: StringIO.new("exit-all\n"), output: StringIO.new
|
||||
defined?(Readline).should == "constant"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -144,7 +144,8 @@ describe Pry::Method do
|
|||
m.name.should == "gag"
|
||||
end
|
||||
|
||||
if defined?(BasicObject) && !Pry::Helpers::BaseHelpers.rbx? # rubinius issue 1921
|
||||
# Temporarily disabled to work around rubinius/rubinius#2871.
|
||||
unless Pry::Helpers::BaseHelpers.rbx?
|
||||
it "should find the right method from a BasicObject" do
|
||||
a = Class.new(BasicObject) { def gag; ::Kernel.binding; end; def self.line; __LINE__; end }
|
||||
|
||||
|
@ -433,8 +434,8 @@ describe Pry::Method do
|
|||
|
||||
it "should include the Pry::Method.instance_resolution_order of Class after the singleton classes" do
|
||||
Pry::Method.resolution_order(LS::Top).should ==
|
||||
[singleton_class(LS::Top), singleton_class(Object), (defined? BasicObject) && singleton_class(BasicObject)].compact +
|
||||
Pry::Method.instance_resolution_order(Class)
|
||||
[singleton_class(LS::Top), singleton_class(Object), singleton_class(BasicObject),
|
||||
*Pry::Method.instance_resolution_order(Class)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -496,15 +497,11 @@ describe Pry::Method do
|
|||
end
|
||||
end
|
||||
|
||||
unless Pry::Helpers::BaseHelpers.mri_18?
|
||||
# Ruby 1.8 doesn't support this feature.
|
||||
it 'should be able to find aliases for methods implemented in C' do
|
||||
meth = Pry::Method(Hash.new.method(:key?))
|
||||
aliases = Set.new(meth.aliases)
|
||||
it 'should be able to find aliases for methods implemented in C' do
|
||||
meth = Pry::Method(Hash.new.method(:key?))
|
||||
aliases = Set.new(meth.aliases)
|
||||
|
||||
aliases.should == Set.new(["include?", "member?", "has_key?"])
|
||||
end
|
||||
aliases.should == Set.new(["include?", "member?", "has_key?"])
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ describe "Prompts" do
|
|||
redirect_pry_io(InputTester.new("exit-all")) do
|
||||
Pry.start(self, :prompt => proc { |v| config = v })
|
||||
end
|
||||
config.is_a?(OpenStruct).should == true
|
||||
config.is_a?(Pry::Config).should == true
|
||||
end
|
||||
|
||||
it 'should get full config object, when using a proc array' do
|
||||
|
@ -15,7 +15,7 @@ describe "Prompts" do
|
|||
redirect_pry_io(InputTester.new("exit-all")) do
|
||||
Pry.start(self, :prompt => [proc { |v| config1 = v }, proc { |v| config2 = v }])
|
||||
end
|
||||
config1.is_a?(OpenStruct).should == true
|
||||
config1.is_a?(Pry::Config).should == true
|
||||
end
|
||||
|
||||
it 'should receive correct data in the config object' do
|
||||
|
|
|
@ -35,8 +35,9 @@ describe Pry do
|
|||
end
|
||||
|
||||
it "should include the =>" do
|
||||
pry = Pry.new
|
||||
accumulator = StringIO.new
|
||||
Pry.config.print.call(accumulator, [1])
|
||||
pry.config.print.call(accumulator, [1], pry)
|
||||
accumulator.string.should == "=> \[1\]\n"
|
||||
end
|
||||
|
||||
|
@ -49,6 +50,16 @@ describe Pry do
|
|||
end
|
||||
end
|
||||
|
||||
describe "output_prefix" do
|
||||
it "should be able to change output_prefix" do
|
||||
pry = Pry.new
|
||||
accumulator = StringIO.new
|
||||
pry.config.output_prefix = "-> "
|
||||
pry.config.print.call(accumulator, [1], pry)
|
||||
accumulator.string.should == "-> \[1\]\n"
|
||||
end
|
||||
end
|
||||
|
||||
describe "color" do
|
||||
before do
|
||||
Pry.color = true
|
||||
|
@ -59,19 +70,21 @@ describe Pry do
|
|||
end
|
||||
|
||||
it "should colorize strings as though they were ruby" do
|
||||
pry = Pry.new
|
||||
accumulator = StringIO.new
|
||||
colorized = CodeRay.scan("[1]", :ruby).term
|
||||
Pry.config.print.call(accumulator, [1])
|
||||
pry.config.print.call(accumulator, [1], pry)
|
||||
accumulator.string.should == "=> #{colorized}\n"
|
||||
end
|
||||
|
||||
it "should not colorize strings that already include color" do
|
||||
pry = Pry.new
|
||||
f = Object.new
|
||||
def f.inspect
|
||||
"\e[1;31mFoo\e[0m"
|
||||
end
|
||||
accumulator = StringIO.new
|
||||
Pry.config.print.call(accumulator, f)
|
||||
pry.config.print.call(accumulator, f, pry)
|
||||
# We add an extra \e[0m to prevent color leak
|
||||
accumulator.string.should == "=> \e[1;31mFoo\e[0m\e[0m\n"
|
||||
end
|
||||
|
|
|
@ -47,7 +47,7 @@ describe "The whole thing" do
|
|||
|
||||
it "shouldn't break if we start a nested instance" do
|
||||
ReplTester.start do
|
||||
input 'Pry.start(10)'
|
||||
input 'Pry.start(10, _pry_.config)'
|
||||
output ''
|
||||
prompt /10.*> $/
|
||||
|
||||
|
|
|
@ -5,15 +5,11 @@ describe Pry do
|
|||
@str_output = StringIO.new
|
||||
end
|
||||
|
||||
if RUBY_VERSION =~ /1.9/
|
||||
describe "Exotic object support" do
|
||||
# regression test for exotic object support
|
||||
it "Should not error when return value is a BasicObject instance" do
|
||||
|
||||
ReplTester.start do
|
||||
input('BasicObject.new').should =~ /^=> #<BasicObject:/
|
||||
end
|
||||
|
||||
describe "Exotic object support" do
|
||||
# regression test for exotic object support
|
||||
it "Should not error when return value is a BasicObject instance" do
|
||||
ReplTester.start do
|
||||
input('BasicObject.new').should =~ /^=> #<BasicObject:/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -89,11 +85,9 @@ describe Pry do
|
|||
}.should.raise(NameError)
|
||||
end
|
||||
|
||||
if defined?(BasicObject)
|
||||
it 'should be able to operate inside the BasicObject class' do
|
||||
pry_eval(BasicObject, ":foo", "Pad.obj = _")
|
||||
Pad.obj.should == :foo
|
||||
end
|
||||
it 'should be able to operate inside the BasicObject class' do
|
||||
pry_eval(BasicObject, ":foo", "Pad.obj = _")
|
||||
Pad.obj.should == :foo
|
||||
end
|
||||
|
||||
it 'should set an ivar on an object' do
|
||||
|
@ -325,9 +319,8 @@ describe Pry do
|
|||
end
|
||||
|
||||
it 'should define a method on the class of an object when performing "def meth;end" inside an immediate value or Numeric' do
|
||||
# should include float in here, but test fails for some reason
|
||||
# on 1.8.7, no idea why!
|
||||
[:test, 0, true, false, nil].each do |val|
|
||||
[:test, 0, true, false, nil,
|
||||
(0.0 unless Pry::Helpers::BaseHelpers.jruby?)].each do |val|
|
||||
pry_eval(val, "def hello; end");
|
||||
val.class.instance_methods(false).map(&:to_sym).include?(:hello).should == true
|
||||
end
|
||||
|
|
|
@ -15,11 +15,9 @@ describe "Pry.run_command" do
|
|||
out.string.should =~ /hokey_pokey/
|
||||
end
|
||||
|
||||
if !PryTestHelpers.mri18_and_no_real_source_location?
|
||||
# This is a regression test as 0.9.11 broke this behaviour
|
||||
it 'can perform a show-source' do
|
||||
Pry.run_command "show-source drum", :context => @context, :output => out = StringIO.new
|
||||
out.string.should =~ /roken is dodelijk/
|
||||
end
|
||||
# This is a regression test as 0.9.11 broke this behaviour
|
||||
it 'can perform a show-source' do
|
||||
Pry.run_command "show-source drum", :context => @context, :output => out = StringIO.new
|
||||
out.string.should =~ /roken is dodelijk/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,7 +67,7 @@ class ReplTester
|
|||
reset_output
|
||||
repl_mailbox.push input
|
||||
wait
|
||||
Pry.output.string
|
||||
@pry.output.string
|
||||
end
|
||||
|
||||
# Assert that the current prompt matches the given string or regex.
|
||||
|
@ -78,7 +78,7 @@ class ReplTester
|
|||
# Assert that the most recent output (since the last time input was called)
|
||||
# matches the given string or regex.
|
||||
def output(match)
|
||||
match.should === Pry.output.string.chomp
|
||||
match.should === @pry.output.string.chomp
|
||||
end
|
||||
|
||||
# Assert that the Pry session ended naturally after the last input.
|
||||
|
@ -99,7 +99,7 @@ class ReplTester
|
|||
private
|
||||
|
||||
def reset_output
|
||||
Pry.output.clear
|
||||
@pry.output.clear
|
||||
end
|
||||
|
||||
def repl_mailbox
|
|
@ -40,17 +40,30 @@ describe "Sticky locals (_file_ and friends)" do
|
|||
Pry.commands.delete "file-and-dir-test"
|
||||
end
|
||||
|
||||
it 'locals should return last result (_)' do
|
||||
pry_tester.tap do |t|
|
||||
lam = t.eval 'lambda { |foo| }'
|
||||
t.eval('_').should == lam
|
||||
end
|
||||
end
|
||||
|
||||
it 'locals should return second last result (__)' do
|
||||
pry_tester.tap do |t|
|
||||
lam = t.eval 'lambda { |foo| }'
|
||||
t.eval 'num = 1'
|
||||
t.eval('__').should == lam
|
||||
end
|
||||
end
|
||||
|
||||
describe "User defined sticky locals" do
|
||||
describe "setting as Pry.config option" do
|
||||
it 'should define a new sticky local for the session (normal value)' do
|
||||
Pry.config.extra_sticky_locals[:test_local] = :john
|
||||
|
||||
o = Object.new
|
||||
redirect_pry_io(InputTester.new("@value = test_local",
|
||||
"exit-all")) do
|
||||
Pry.start(o)
|
||||
end
|
||||
|
||||
o.instance_variable_get(:@value).should == :john
|
||||
Pry.config.extra_sticky_locals = {}
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue