summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Fitzgerald <rwfitzge@gmail.com>2014-01-25 12:55:02 -0800
committerRyan Fitzgerald <rwfitzge@gmail.com>2014-01-27 23:37:07 -0800
commit4610a87838c54fdb1c175514a03c7e8e6bee6d5a (patch)
tree235d1c542ccaa181d544426e4650ad74395917a9
parent7464f8d0ae9d3838c47064541bac9bcb8123c3f5 (diff)
downloadpry-0-9-12-defer-readline.tar.gz
Defer Readline load as long as possible (fix #1081, #1095)0-9-12-defer-readline
Also fixes rweng/pry-rails#50 and rails/spring#244.
-rw-r--r--lib/pry.rb23
-rw-r--r--lib/pry/completion.rb31
-rw-r--r--lib/pry/config.rb20
-rw-r--r--lib/pry/history.rb6
-rw-r--r--lib/pry/pry_class.rb13
-rw-r--r--lib/pry/pry_instance.rb2
-rw-r--r--lib/pry/terminal.rb2
-rw-r--r--spec/completion_spec.rb2
8 files changed, 66 insertions, 33 deletions
diff --git a/lib/pry.rb b/lib/pry.rb
index 4b76bcee..2fe87cf6 100644
--- a/lib/pry.rb
+++ b/lib/pry.rb
@@ -196,6 +196,16 @@ class Pry
# IRB = Pry thing.
module ExtendCommandBundle
end
+
+ def self.require_readline
+ return false if @required_readline
+ require 'readline'
+ @required_readline = true
+ rescue LoadError
+ warn "Sorry, you can't use Pry without Readline or a compatible library."
+ warn "Please `gem install rb-readline` or recompile Ruby --with-readline."
+ raise
+ end
end
if Pry::Helpers::BaseHelpers.mri_18?
@@ -213,19 +223,11 @@ require 'slop'
require 'rbconfig'
require 'tempfile'
-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?
begin
require 'ffi'
rescue LoadError
- warn "Need to `gem install ffi`"
+ warn "For a better Pry experience on JRuby, please `gem install ffi`."
end
end
@@ -236,7 +238,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
diff --git a/lib/pry/completion.rb b/lib/pry/completion.rb
index 03ced306..e521aa53 100644
--- a/lib/pry/completion.rb
+++ b/lib/pry/completion.rb
@@ -5,6 +5,14 @@ class Pry
module BondCompleter
def self.build_completion_proc(target, pry=nil, commands=[""])
+ Pry.require_readline
+
+ # If we're using libedit, don't use Bond.
+ if Readline::VERSION =~ /editline/i
+ Pry.config.completer = InputCompleter
+ return InputCompleter.build_completion_proc(target, pry, commands)
+ end
+
if !@started
@started = true
start
@@ -28,13 +36,6 @@ class Pry
# Implements tab completion for Readline in Pry
module InputCompleter
-
- if Readline.respond_to?("basic_word_break_characters=")
- Readline.basic_word_break_characters = " \t\n\"\\'`><=;|&{("
- end
-
- Readline.completion_append_character = nil
-
ReservedWords = [
"BEGIN", "END",
"alias", "and",
@@ -60,10 +61,26 @@ class Pry
"[]", "[]=", "^", "!", "!=", "!~"
]
+ # If we haven't configured Readline for completion yet, do it now.
+ # @private
+ def self.initialize_readline
+ Pry.require_readline
+ return if @initialized_readline
+
+ if Readline.respond_to?("basic_word_break_characters=")
+ Readline.basic_word_break_characters = " \t\n\"\\'`><=;|&{("
+ end
+
+ Readline.completion_append_character = nil
+
+ @initialized_readline = true
+ end
+
# Return a new completion proc for use by Readline.
# @param [Binding] target The current binding context.
# @param [Array<String>] commands The array of Pry commands.
def self.build_completion_proc(target, pry=nil, commands=[""])
+ initialize_readline
proc do |input|
diff --git a/lib/pry/config.rb b/lib/pry/config.rb
index 6249e456..21dbdb34 100644
--- a/lib/pry/config.rb
+++ b/lib/pry/config.rb
@@ -5,13 +5,27 @@ class Pry
# 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.
+ # 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. It can also be a Proc which returns an
+ # object implementing the readline method.
# @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
+ def input
+ @reified_input ||=
+ if @input.respond_to?(:call)
+ @input.call
+ else
+ @input
+ end
+ end
+
+ def input=(input)
+ @reified_input = nil
+ @input = input
+ end
# 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
diff --git a/lib/pry/history.rb b/lib/pry/history.rb
index df50df21..4f63838f 100644
--- a/lib/pry/history.rb
+++ b/lib/pry/history.rb
@@ -1,6 +1,6 @@
class Pry
- # The History class is responsible for maintaining the user's input history, both
- # internally and within Readline.
+ # The History class is responsible for maintaining the user's input history,
+ # both internally and within Readline.
class History
attr_accessor :loader, :saver, :pusher, :clearer
@@ -111,11 +111,13 @@ class Pry
# The default pusher. Appends the given line to Readline::HISTORY.
# @param [String] line
def push_to_readline(line)
+ Pry.require_readline
Readline::HISTORY << line
end
# The default clearer. Clears Readline::HISTORY.
def clear_readline
+ Pry.require_readline
Readline::HISTORY.shift until Readline::HISTORY.empty?
end
end
diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb
index c030b82e..0de17b95 100644
--- a/lib/pry/pry_class.rb
+++ b/lib/pry/pry_class.rb
@@ -107,8 +107,7 @@ class Pry
# Including: loading .pryrc, loading plugins, loading requires, and
# loading history.
def self.initial_session_setup
-
- return if !initial_session?
+ return unless initial_session?
# note these have to be loaded here rather than in pry_instance as
# we only want them loaded once per entire Pry lifetime.
@@ -262,6 +261,7 @@ class Pry
end
def self.auto_resize!
+ Pry.require_readline
ver = Readline::VERSION
if ver[/edit/i]
warn <<-EOT
@@ -286,7 +286,7 @@ Readline version #{ver} detected - will not auto_resize! correctly.
end
def self.set_config_defaults
- config.input = Readline
+ config.input = proc { Pry.require_readline; Readline }
config.output = $stdout
config.commands = Pry::Commands
config.prompt_name = DEFAULT_PROMPT_NAME
@@ -310,12 +310,7 @@ Readline version #{ver} detected - will not auto_resize! correctly.
config.correct_indent = true
config.collision_warning = false
config.output_prefix = "=> "
-
- if defined?(Bond) && Readline::VERSION !~ /editline/i
- config.completer = Pry::BondCompleter
- else
- config.completer = Pry::InputCompleter
- end
+ config.completer = Pry::BondCompleter
config.gist ||= OpenStruct.new
config.gist.inspecter = proc(&:pretty_inspect)
diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb
index a3f67206..51cc48a0 100644
--- a/lib/pry/pry_instance.rb
+++ b/lib/pry/pry_instance.rb
@@ -619,7 +619,7 @@ class Pry
input.completion_proc = completion_proc
end
- if input == Readline
+ if defined?(Readline) && input == Readline
if !$stdout.tty? && $stdin.tty? && !Pry::Helpers::BaseHelpers.windows?
Readline.output = File.open('/dev/tty', 'w')
end
diff --git a/lib/pry/terminal.rb b/lib/pry/terminal.rb
index 10cbcf85..6116de6a 100644
--- a/lib/pry/terminal.rb
+++ b/lib/pry/terminal.rb
@@ -53,7 +53,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
diff --git a/spec/completion_spec.rb b/spec/completion_spec.rb
index f6dd60cc..6dff5bf1 100644
--- a/spec/completion_spec.rb
+++ b/spec/completion_spec.rb
@@ -10,6 +10,8 @@ def completer_test(bind, pry=nil, assert_flag=true)
return proc {|*symbols| symbols.each(&test) }
end
+Pry.require_readline
+
if defined?(Bond) && Readline::VERSION !~ /editline/i
describe 'bond-based completion' do
it 'should pull in Bond by default' do