A cross-platform terminal pager that works on all major Ruby interpreters.
TTY::Pager provides independent terminal pager component for TTY toolkit.
Add this line to your application's Gemfile:
gem 'tty-pager'
And then execute:
$ bundle
Or install it yourself as:
$ gem install tty-pager
The TTY::Pager will automatically choose the best available pager on a user's system. Failing to do so, it will fallback on a pure Ruby version that is guaranteed to work with any Ruby interpreter and on any platform.
The TTY::Pager will pick the best paging mechanism available on your system when initialized:
pager = TTY::Pager.new
Then to start paginating text call the page
method with the content as the first argument:
pager.page("Very long text...")
This will launch a pager in the background and wait until the user is done.
Alternatively, you can pass the :path
keyword to specify a file path:
pager.page(path: "/path/to/filename.txt")
If instead you'd like to paginate a long-running operation, you could use the block form of the pager:
TTY::Pager.page do |pager|
File.open("file_with_lots_of_lines.txt", "r").each_line do |line|
# do some work with the line
pager.write(line) # send it to the pager
end
end
After block finishes, the pager is automatically closed.
For more control, you can translate the block form into separate write
and close
calls:
begin
pager = TTY::Pager.new
File.open("file_with_lots_of_lines.txt", "r").each_line do |line|
# do some work with the line
pager.write(line) # send it to the pager
end
rescue TTY::Pager::PagerClosed
# the user closed the paginating tool
ensure
pager.close
end
If you want to use a specific pager you can do so by invoking it directly:
pager = TTY::Pager::BasicPager.new
# or
pager = TTY::Pager::SystemPager.new
# or
pager = TTY::Pager::NullPager.new
The TTY::Pager
can be configured during initialization for terminal width, type of prompt when basic pager is invoked, and the pagination command to run.
For example, to disable a pager in CI you could do:
pager = TTY::Pager.new(enabled: false)
If you want to disable the paging use the :enabled
option set to false
:
pager = TTY::Pager.new(enabled: false)
This will directly print all the content to the standard output. If the output isn't a tty device, the pager will return the content directly to the caller.
To force TTY::Pager
to always use a specific paging tool(s), use the :command
option:
TTY::Pager.new(command: "less -R")
The :command
also accepts an array of pagers to use:
pager = TTY::Pager.new(command: ["less -r", "more -r"])
If the provided pager command or commands don't exist on user's system, the pager will fallback automatically on a basic Ruby implementation.
To skip automatic detection of pager and always use a system pager do:
TTY::Pager::SystemPager.new(command: "less -R")
Only the BasicPager
allows you to wrap content at given terminal width:
pager = TTY::Pager.new(width: 80)
This option doesn't affect the SystemPager
.
To directly use BasicPager
do:
pager = TTY::Pager::BasicPager.new(width: 80)
To change the BasicPager
page break prompt display, use the :prompt
option:
prompt = -> (page) { "Page -#{page_num}- Press enter to continue" }
pager = TTY::Pager.new(prompt: prompt)
To start paging use the page
method. It can be invoked on an instance or a class.
The class-level page
is a convenient shortcut. To page some text you only need to do:
TTY::Pager.page("Some long text...")
You can also include extra initialization parameters. For example, if you prefer to use a specific command do this:
TTY::Pager.page("Some long text...", command: "less -R")
The instance equivalent would be:
pager = TTY::Pager.new(command: "less -R")
pager.page("Some long text...")
Apart from text, you can page file content by passing the :path
option:
TTY::Pager.page(path: "/path/to/filename.txt")
The final way is to use the class-level page
with a block. After the block is done, the pager is automatically closed. For example, to read a file line by line with additional processing you could do:
TTY::Pager.page do |pager|
File.foreach("filename.txt") do |line|
# do some work with the line
pager.write(line) # write line to the pager
end
end
The instance equivalent of the block version would be:
pager = TTY::Pager.new
begin
File.foreach("filename.txt") do |line|
# do some work with the line
pager.write(line) # write line to the pager
end
rescue TTY::Pager::PagerClosed
ensure
pager.close
end
To stream content to the pager use the write
method.
pager.write("Some text")
You can pass in any number of arguments:
pager.write("one", "two", "three")
To check if a write has been successful use try_write
:
pager.try_write("Some text")
# => true
To write a line of text and end it with a new line use puts
call:
pager.puts("Single line of content")
When you're done streaming content manually use close
to finish paging.
All interactions with a pager can raise an exception for various reasons, so wrap your code using the following pattern:
pager = TTY::Pager.new
begin
# ... perform pager writes
rescue TTY::Pager::PagerClosed
# the user closed the paginating tool
ensure
pager.close
end
Alternatively use the class-level page
call with a block to automatically close the pager:
TTY::Pager.page do |pager|
# ... perform pager writes
end
By default the SystemPager
will check the PAGER
environment variable. If the PAGER
isn't set, the pager will try one of the searched commands like less
, more
or pg
.
Therefore, if you wish to set your preferred pager you can either set up your shell like so:
PAGER=less -R
export PAGER
Or set PAGER
in Ruby script:
ENV["PAGER"]="less -R"
Bug reports and pull requests are welcome on GitHub at https://github.com/piotrmurach/tty-pager. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
- Fork it ( https://github.com/piotrmurach/tty-pager/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Everyone interacting in the TTY::Pager project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Copyright (c) 2015 Piotr Murach. See LICENSE for further details.