2013-02-12 07:42:29 -05:00
|
|
|
require 'pry/terminal'
|
2013-10-29 00:25:13 -04:00
|
|
|
|
|
|
|
# A Pry::Pager is an IO-like object that accepts text and either prints it
|
|
|
|
# immediately, prints it one page at a time, or streams it to an external
|
|
|
|
# program to print one page at a time.
|
2012-08-08 17:57:19 -04:00
|
|
|
class Pry::Pager
|
2013-10-29 00:25:13 -04:00
|
|
|
class StopPaging < StandardError
|
|
|
|
end
|
|
|
|
|
2012-08-09 17:51:50 -04:00
|
|
|
# @param [String] text
|
|
|
|
# A piece of text to run through a pager.
|
2013-10-29 00:25:13 -04:00
|
|
|
# @param [Symbol?] pager_type
|
2012-11-03 23:59:21 -04:00
|
|
|
# `:simple` -- Use the pure ruby pager.
|
|
|
|
# `:system` -- Use the system pager (less) or the environment variable
|
|
|
|
# $PAGER if set.
|
|
|
|
# `nil` -- Infer what pager to use from the environment. What this
|
|
|
|
# really means is that JRuby and systems that do not have
|
|
|
|
# access to 'less' will run through the pure ruby pager.
|
2013-10-29 00:25:13 -04:00
|
|
|
def self.page(text, pager_type = nil)
|
|
|
|
pager = best_available($stdout, pager_type)
|
|
|
|
pager << text
|
|
|
|
ensure
|
|
|
|
pager.close if pager
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.best_available(output, pager_type = nil)
|
|
|
|
case pager_type
|
2012-08-09 11:43:46 -04:00
|
|
|
when nil
|
2012-10-26 09:09:07 -04:00
|
|
|
no_pager = !SystemPager.available?
|
2013-01-30 02:46:16 -05:00
|
|
|
if no_pager || Pry::Helpers::BaseHelpers.jruby?
|
2013-10-29 00:25:13 -04:00
|
|
|
SimplePager.new(output)
|
2013-01-30 02:46:16 -05:00
|
|
|
else
|
2013-10-29 00:25:13 -04:00
|
|
|
SystemPager.new(output)
|
2013-01-30 02:46:16 -05:00
|
|
|
end
|
2012-08-09 11:43:46 -04:00
|
|
|
when :simple
|
2013-10-29 00:25:13 -04:00
|
|
|
SimplePager.new(output)
|
2012-08-09 11:43:46 -04:00
|
|
|
when :system
|
2013-10-29 00:25:13 -04:00
|
|
|
SystemPager.new(output)
|
2012-08-09 11:43:46 -04:00
|
|
|
else
|
2012-12-02 11:45:42 -05:00
|
|
|
raise "'#{pager}' is not a recognized pager."
|
2012-08-09 11:43:46 -04:00
|
|
|
end
|
2012-08-08 17:57:19 -04:00
|
|
|
end
|
|
|
|
|
2012-08-09 17:51:50 -04:00
|
|
|
def self.page_size
|
2013-10-29 00:25:13 -04:00
|
|
|
Pry::Terminal.height!
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(out)
|
|
|
|
@out = out
|
|
|
|
end
|
|
|
|
|
|
|
|
def page_size
|
|
|
|
@page_size ||= self.class.page_size
|
|
|
|
end
|
|
|
|
|
|
|
|
def puts(str)
|
|
|
|
print "#{str.chomp}\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
def write(str)
|
|
|
|
@out.write str
|
2012-08-09 17:51:50 -04:00
|
|
|
end
|
|
|
|
|
2013-10-29 00:25:13 -04:00
|
|
|
def print(str)
|
|
|
|
write str
|
|
|
|
end
|
|
|
|
alias << print
|
|
|
|
|
|
|
|
def close
|
|
|
|
# no-op for base pager, but important for subclasses
|
2012-08-08 18:29:51 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
class SimplePager < Pry::Pager
|
2013-10-29 00:25:13 -04:00
|
|
|
# Window height minus the number of lines used by the info bar.
|
|
|
|
def self.page_size
|
|
|
|
super - 3
|
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(*)
|
|
|
|
super
|
|
|
|
@lines_printed = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
def write(str)
|
|
|
|
page_size = self.class.page_size
|
|
|
|
|
|
|
|
str.lines.each do |line|
|
|
|
|
@out.write line
|
|
|
|
@lines_printed += 1 if line.end_with?("\n")
|
|
|
|
|
|
|
|
if @lines_printed >= page_size
|
|
|
|
@out.puts "\n<page break> --- Press enter to continue " \
|
|
|
|
"( q<enter> to break ) --- <page break>"
|
|
|
|
raise StopPaging if $stdin.gets.chomp == "q"
|
|
|
|
@lines_printed = 0
|
2012-08-08 18:29:51 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class SystemPager < Pry::Pager
|
2012-10-26 09:09:07 -04:00
|
|
|
def self.default_pager
|
2013-01-18 20:58:11 -05:00
|
|
|
pager = ENV["PAGER"] || ""
|
|
|
|
|
|
|
|
# Default to less, and make sure less is being passed the correct options
|
|
|
|
if pager.strip.empty? or pager =~ /^less\s*/
|
|
|
|
pager = "less -R -S -F -X"
|
|
|
|
end
|
|
|
|
|
|
|
|
pager
|
2012-10-26 09:09:07 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.available?
|
2013-01-18 20:58:11 -05:00
|
|
|
if @system_pager.nil?
|
|
|
|
@system_pager = begin
|
|
|
|
pager_executable = default_pager.split(' ').first
|
|
|
|
`which #{ pager_executable }`
|
|
|
|
rescue
|
|
|
|
false
|
|
|
|
end
|
|
|
|
else
|
|
|
|
@system_pager
|
|
|
|
end
|
2012-10-26 09:09:07 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(*)
|
|
|
|
super
|
2013-10-29 00:25:13 -04:00
|
|
|
@pager = IO.popen(SystemPager.default_pager, 'w')
|
2012-10-26 09:09:07 -04:00
|
|
|
end
|
|
|
|
|
2013-10-29 00:25:13 -04:00
|
|
|
def write(str)
|
|
|
|
@pager.write str
|
|
|
|
rescue Errno::EPIPE
|
|
|
|
end
|
|
|
|
|
|
|
|
def close
|
|
|
|
@pager.close if @pager
|
2012-08-08 17:57:19 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|