mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
Merge pull request #1117 from pry/lazy-readline
lazy load readline through Proc defined on Pry::Config::Default.
This commit is contained in:
commit
e054af7468
11 changed files with 96 additions and 37 deletions
|
@ -8,6 +8,10 @@ rvm:
|
||||||
- jruby-19mode
|
- jruby-19mode
|
||||||
- jruby-head
|
- jruby-head
|
||||||
|
|
||||||
|
script:
|
||||||
|
- rake spec
|
||||||
|
- bundle exec bacon spec/isolation/readline_spec.rb
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rvm: ruby-head
|
- rvm: ruby-head
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
* User can whitelist objects whose inspect output should appear in prompt (#885)
|
* User can whitelist objects whose inspect output should appear in prompt (#885)
|
||||||
* See `Pry.config.prompt_safe_objects`
|
* See `Pry.config.prompt_safe_objects`
|
||||||
* `whereami` is now aliased to `@`
|
* `whereami` is now aliased to `@`
|
||||||
* improve configuration(Pry.config) to lazy-load default configuration values. (#1096)
|
* 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)
|
||||||
|
|
||||||
#### Bug fixes, etc.
|
#### Bug fixes, etc.
|
||||||
* `binding.pry` inside `.pryrc` file now works, with some limitations (@richo / #1118)
|
* `binding.pry` inside `.pryrc` file now works, with some limitations (@richo / #1118)
|
||||||
|
|
2
Rakefile
2
Rakefile
|
@ -42,7 +42,7 @@ task :test do
|
||||||
if explicit_list = ENV['run']
|
if explicit_list = ENV['run']
|
||||||
explicit_list.split(',')
|
explicit_list.split(',')
|
||||||
else
|
else
|
||||||
Dir['spec/**/*_spec.rb'].shuffle!
|
(Dir['spec/**/*_spec.rb'] - Dir["spec/isolation/*_spec.rb"]).shuffle!
|
||||||
end
|
end
|
||||||
run_specs paths
|
run_specs paths
|
||||||
end
|
end
|
||||||
|
|
13
lib/pry.rb
13
lib/pry.rb
|
@ -132,19 +132,13 @@ require 'rbconfig'
|
||||||
require 'tempfile'
|
require 'tempfile'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
|
||||||
begin
|
|
||||||
require 'readline'
|
|
||||||
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?
|
if Pry::Helpers::BaseHelpers.jruby?
|
||||||
begin
|
begin
|
||||||
require 'ffi'
|
require 'ffi'
|
||||||
rescue LoadError
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -155,7 +149,8 @@ if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi
|
||||||
# only fail on jruby (where win32console doesn't work).
|
# only fail on jruby (where win32console doesn't work).
|
||||||
# Instead we'll recommend ansicon, which does.
|
# Instead we'll recommend ansicon, which does.
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
warn "For a better pry experience, please use ansicon: https://github.com/adoxa/ansicon"
|
warn "For a better Pry experience on Windows, please use ansicon:"
|
||||||
|
warn " http://adoxa.3eeweb.com/ansicon/"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ class Pry::Config::Default
|
||||||
include Pry::Config::Behavior
|
include Pry::Config::Behavior
|
||||||
|
|
||||||
default = {
|
default = {
|
||||||
:input => proc { Readline },
|
:input => proc { lazy_readline },
|
||||||
:output => proc { $stdout },
|
:output => proc { $stdout },
|
||||||
:commands => proc { Pry::Commands },
|
:commands => proc { Pry::Commands },
|
||||||
:prompt_name => proc { Pry::DEFAULT_PROMPT_NAME },
|
:prompt_name => proc { Pry::DEFAULT_PROMPT_NAME },
|
||||||
|
@ -35,13 +35,7 @@ class Pry::Config::Default
|
||||||
:extra_sticky_locals => proc { {} },
|
:extra_sticky_locals => proc { {} },
|
||||||
:command_completer => proc { proc { Pry.commands.commands.keys } },
|
:command_completer => proc { proc { Pry.commands.commands.keys } },
|
||||||
:file_completer => proc { proc { Dir["."] } },
|
:file_completer => proc { proc { Dir["."] } },
|
||||||
:completer => proc {
|
:completer => proc { lazy_completer }
|
||||||
if defined?(Bond) && Readline::VERSION !~ /editline/i
|
|
||||||
Pry::BondCompleter.start
|
|
||||||
else
|
|
||||||
Pry::InputCompleter.start
|
|
||||||
end
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
|
@ -54,13 +48,14 @@ class Pry::Config::Default
|
||||||
default.each do |key, value|
|
default.each do |key, value|
|
||||||
define_method(key) do
|
define_method(key) do
|
||||||
if default[key].equal?(value)
|
if default[key].equal?(value)
|
||||||
default[key] = value.call
|
default[key] = instance_eval(&value)
|
||||||
end
|
end
|
||||||
default[key]
|
default[key]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
# all of this configure_* stuff is a relic of old code.
|
# all of this configure_* stuff is a relic of old code.
|
||||||
# we should try move this code to being command-local.
|
# we should try move this code to being command-local.
|
||||||
|
@ -101,4 +96,28 @@ private
|
||||||
history.should_load = false
|
history.should_load = false
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
|
@ -2,7 +2,6 @@ class Pry
|
||||||
# The History class is responsible for maintaining the user's input history,
|
# The History class is responsible for maintaining the user's input history,
|
||||||
# both internally and within Readline.
|
# both internally and within Readline.
|
||||||
class History
|
class History
|
||||||
|
|
||||||
attr_accessor :loader, :saver, :pusher, :clearer
|
attr_accessor :loader, :saver, :pusher, :clearer
|
||||||
|
|
||||||
# @return [Fixnum] Number of lines in history when Pry first loaded.
|
# @return [Fixnum] Number of lines in history when Pry first loaded.
|
||||||
|
@ -17,10 +16,18 @@ class Pry
|
||||||
|
|
||||||
# Assign the default methods for loading, saving, pushing, and clearing.
|
# Assign the default methods for loading, saving, pushing, and clearing.
|
||||||
def restore_default_behavior
|
def restore_default_behavior
|
||||||
@loader = method(:read_from_file)
|
Pry.config.input # force Readline to load if applicable
|
||||||
@saver = method(:save_to_file)
|
|
||||||
@pusher = method(:push_to_readline)
|
@loader = method(:read_from_file)
|
||||||
@clearer = method(:clear_readline)
|
@saver = method(:save_to_file)
|
||||||
|
|
||||||
|
if defined?(Readline)
|
||||||
|
@pusher = method(:push_to_readline)
|
||||||
|
@clearer = method(:clear_readline)
|
||||||
|
else
|
||||||
|
@pusher = proc { }
|
||||||
|
@clearer = proc { }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load the input history using `History.loader`.
|
# Load the input history using `History.loader`.
|
||||||
|
|
|
@ -10,11 +10,11 @@ class Pry
|
||||||
attr_accessor :current_line
|
attr_accessor :current_line
|
||||||
attr_accessor :line_buffer
|
attr_accessor :line_buffer
|
||||||
attr_accessor :eval_path
|
attr_accessor :eval_path
|
||||||
attr_accessor :history
|
|
||||||
attr_accessor :cli
|
attr_accessor :cli
|
||||||
attr_accessor :quiet
|
attr_accessor :quiet
|
||||||
attr_accessor :last_internal_error
|
attr_accessor :last_internal_error
|
||||||
attr_accessor :config
|
attr_accessor :config
|
||||||
|
attr_writer :history
|
||||||
|
|
||||||
def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
|
def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
|
||||||
|
|
||||||
|
@ -28,6 +28,10 @@ class Pry
|
||||||
def prompt
|
def prompt
|
||||||
config.prompt
|
config.prompt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def history
|
||||||
|
@history ||= History.new
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.main
|
def self.main
|
||||||
|
@ -233,15 +237,22 @@ class Pry
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.auto_resize!
|
def self.auto_resize!
|
||||||
ver = Readline::VERSION
|
Pry.config.input # by default, load Readline
|
||||||
if ver[/edit/i]
|
|
||||||
|
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
|
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:
|
For the fix, use GNU Readline instead:
|
||||||
https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X
|
https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X
|
||||||
EOT
|
EOT
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
trap :WINCH do
|
trap :WINCH do
|
||||||
begin
|
begin
|
||||||
Readline.set_screen_size(*Terminal.size!)
|
Readline.set_screen_size(*Terminal.size!)
|
||||||
|
@ -269,7 +280,6 @@ Readline version #{ver} detected - will not auto_resize! correctly.
|
||||||
# Basic initialization.
|
# Basic initialization.
|
||||||
def self.init
|
def self.init
|
||||||
@plugin_manager ||= PluginManager.new
|
@plugin_manager ||= PluginManager.new
|
||||||
self.history ||= History.new
|
|
||||||
reset_defaults
|
reset_defaults
|
||||||
locate_plugins
|
locate_plugins
|
||||||
end
|
end
|
||||||
|
|
|
@ -179,7 +179,7 @@ class Pry
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if input == Readline
|
if defined?(Readline) and input == Readline
|
||||||
input_readline(current_prompt, false) # false since we'll add it manually
|
input_readline(current_prompt, false) # false since we'll add it manually
|
||||||
elsif defined? Coolline and input.is_a? Coolline
|
elsif defined? Coolline and input.is_a? Coolline
|
||||||
input_readline(current_prompt)
|
input_readline(current_prompt)
|
||||||
|
|
|
@ -54,7 +54,7 @@ class Pry::Terminal
|
||||||
end
|
end
|
||||||
|
|
||||||
def screen_size_according_to_readline
|
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 = Readline.get_screen_size
|
||||||
size if nonzero_column?(size)
|
size if nonzero_column?(size)
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,16 +6,22 @@ def completer_test(bind, pry=nil, assert_flag=true)
|
||||||
return proc {|*symbols| symbols.each(&test) }
|
return proc {|*symbols| symbols.each(&test) }
|
||||||
end
|
end
|
||||||
|
|
||||||
if defined?(Bond) && Readline::VERSION !~ /editline/i
|
describe 'Bond-based completion' do
|
||||||
describe 'bond-based completion' do
|
before do
|
||||||
it 'should pull in Bond by default' do
|
@local = Pry::Config.new Pry::Config::Default.new
|
||||||
Pry.config.completer.should == Pry::BondCompleter
|
@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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Pry::InputCompleter do
|
describe Pry::InputCompleter do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
# The AMQP gem has some classes like this:
|
# The AMQP gem has some classes like this:
|
||||||
# pry(main)> AMQP::Protocol::Test::ContentOk.name
|
# pry(main)> AMQP::Protocol::Test::ContentOk.name
|
||||||
|
|
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
|
Loading…
Reference in a new issue