55 lines
1.4 KiB
Ruby
55 lines
1.4 KiB
Ruby
module Pager
|
|
module PagerHelper
|
|
def self.options opts = nil
|
|
opts = opts.kind_of?( Hash) ? opts.dup : {}
|
|
stdout = opts[:stdout] || opts[:out] || $stdout
|
|
stderr = opts[:stderr] || opts[:err] || $stderr
|
|
stdin = opts[:stdin] || opts[:in] || $stdin
|
|
pager = opts[:pager] || opts[:less] || $PAGER || ENV['PAGER'] || 'less'
|
|
rescuing = opts[:rescuing] || opts[:exceptions] || $PAGER_RESCUE
|
|
[stdout, stderr, stdin, pager, rescuing]
|
|
end
|
|
|
|
def self.exception_formatter exception
|
|
["#{exception.class}: #{exception.message}", exception.backtrace.collect {|c| "\tfrom #{c}" }].join "\n"
|
|
end
|
|
end
|
|
|
|
def self.pager obj = nil, opts = nil, &exe
|
|
if block_given?
|
|
stdout, stderr, stdin, pager, rescuing = PagerHelper.options( opts || obj)
|
|
pid, dupout, duperr, dupin = nil, stdout.dup, stderr.dup, stdin.dup
|
|
IO.pipe do |inrd, inwr|
|
|
begin
|
|
IO.pipe do |rd, wr|
|
|
pid = Process.fork do
|
|
stdin.reopen rd
|
|
wr.close
|
|
exec *pager
|
|
end
|
|
stdout.reopen wr
|
|
stderr.reopen wr
|
|
stdin.reopen inrd
|
|
if rescuing
|
|
begin
|
|
yield
|
|
rescue Object
|
|
stdout.puts PagerHelper.exception_formatter
|
|
end
|
|
else
|
|
yield
|
|
end
|
|
end
|
|
ensure
|
|
stdout.reopen dupout
|
|
stderr.reopen duperr
|
|
Process.wait pid
|
|
stdin.reopen dupin
|
|
end
|
|
end
|
|
else
|
|
pager( opts) { Kernel.p obj }
|
|
end
|
|
end
|
|
end
|