tty-pager 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 762884b7e1c8aed7cb329a22577247b1d13e3dec
4
+ data.tar.gz: 3a0e5d127f2348ab58a7e95402b4a76c8cf1aea9
5
+ SHA512:
6
+ metadata.gz: 9fbcf3ac3cbbbe53591bc2ced88aa28af51825e6d094f2fe22d7aa47940293f8b0fb8abca0861d98664de6b3bb7397b12477973a5599fd36aade65b8918e7d2e
7
+ data.tar.gz: a7632fc1596b11cd0e9a4aa9d2bde295020b856eca9e5e2f6b28aca8252d4db5228a4a7e177920851d68e8db5b1aae6f47800c3ff25af8f9ca3a3b5cc3b27594
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --warnings
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0.0
data/.travis.yml ADDED
@@ -0,0 +1,24 @@
1
+ language: ruby
2
+ bundler_args: --without yard benchmarks
3
+ script: "bundle exec rake ci"
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0
7
+ - 2.1
8
+ - 2.2
9
+ - ruby-head
10
+ matrix:
11
+ include:
12
+ - rvm: jruby-19mode
13
+ - rvm: jruby-20mode
14
+ - rvm: jruby-21mode
15
+ - rvm: jruby-head
16
+ - rvm: rbx-2
17
+ allow_failures:
18
+ - rvm: ruby-head
19
+ - rvm: jruby-head
20
+ - rvm: jruby-20mode
21
+ - rvm: jruby-21mode
22
+ fast_finish: true
23
+ branches:
24
+ only: master
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake', '~> 10.4.2'
7
+ gem 'rspec', '~> 3.2.0'
8
+ gem 'yard', '~> 0.8.7'
9
+ end
10
+
11
+ group :metrics do
12
+ gem 'coveralls', '~> 0.8.1'
13
+ gem 'simplecov', '~> 0.10.0'
14
+ gem 'yardstick', '~> 0.9.9'
15
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Piotr Murach
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # TTY::Pager
2
+ [![Gem Version](https://badge.fury.io/rb/tty-pager.svg)][gem]
3
+ [![Build Status](https://secure.travis-ci.org/peter-murach/tty-pager.svg?branch=master)][travis]
4
+ [![Code Climate](https://codeclimate.com/github/peter-murach/tty-pager/badges/gpa.svg)][codeclimate]
5
+ [![Coverage Status](https://coveralls.io/repos/peter-murach/tty-pager/badge.svg)][coverage]
6
+ [![Inline docs](http://inch-ci.org/github/peter-murach/tty-pager.svg?branch=master)][inchpages]
7
+
8
+ [gem]: http://badge.fury.io/rb/tty-pager
9
+ [travis]: http://travis-ci.org/peter-murach/tty-pager
10
+ [codeclimate]: https://codeclimate.com/github/peter-murach/tty-pager
11
+ [coverage]: https://coveralls.io/r/peter-murach/tty-pager
12
+ [inchpages]: http://inch-ci.org/github/peter-murach/tty-pager
13
+
14
+ > Terminal output paging in a cross-platform way supporting all major ruby interpreters.
15
+
16
+ **TTY::Pager** provides independent terminal output paging component for [TTY](https://github.com/peter-murach/tty) toolkit.
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ gem 'tty-pager'
23
+
24
+ And then execute:
25
+
26
+ $ bundle
27
+
28
+ Or install it yourself as:
29
+
30
+ $ gem install tty-pager
31
+
32
+ ## 1. Usage
33
+
34
+ The **TTY::Pager** upon initialization will choose the best available pager out of `SystemPager`, `BasicPager` or `NullPager`. If paging is disabled then a `NullPager` is used that simply prints content out to stdout, otherwise a check is performed to find native system executable to perform pagination natively with `SystemPager`. If no system executable is found, a `BasicPager` is used which is a pure Ruby implementation that will work with any ruby interpreter.
35
+
36
+ ```ruby
37
+ pager = TTY::Pager.new
38
+ ```
39
+
40
+ Then to perform actual content pagination invoke `page` like so:
41
+
42
+ ```ruby
43
+ pager.page("Very long text...")
44
+ ```
45
+
46
+ If you want to use specific pager you can do so by invoking it directly
47
+
48
+ ```ruby
49
+ pager = TTY::Pager::BasicPager.new
50
+ ```
51
+
52
+ If you want to disable the pager pass the `:enabled` option:
53
+
54
+ ```ruby
55
+ pager = TTY::Pager.new enabled: false
56
+ ```
57
+
58
+ For the `BasicPager` you can also pass a `:prompt` option to change the page break content:
59
+
60
+ ```ruby
61
+ prompt = -> (page_num) { output.puts "Page -#{page_num}- Press enter to continue" }
62
+ pager = TTY::Pager::BasicPager.new prompt: prompt
63
+ ```
64
+
65
+ ## Contributing
66
+
67
+ 1. Fork it ( https://github.com/peter-murach/tty-pager/fork )
68
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
69
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
70
+ 4. Push to the branch (`git push origin my-new-feature`)
71
+ 5. Create a new Pull Request
72
+
73
+ ## Copyright
74
+
75
+ Copyright (c) 2015 Piotr Murach. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ FileList['tasks/**/*.rake'].each(&method(:import))
6
+
7
+ desc 'Run all specs'
8
+ task ci: %w[ spec ]
@@ -0,0 +1,60 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class Pager
5
+ # A basic pager is used to work on systems where
6
+ # system pager is not supported.
7
+ #
8
+ # @api public
9
+ class BasicPager < Pager
10
+ # Page text
11
+ #
12
+ # @api public
13
+ def page(text, &callback)
14
+ page_num = 1
15
+ leftover = []
16
+ lines_left = @height
17
+
18
+ text.lines.each do |line|
19
+ chunk = []
20
+ if !leftover.empty?
21
+ chunk = leftover
22
+ leftover = []
23
+ end
24
+ wrapped_line = Verse.wrap(line, @width)
25
+ wrapped_line.lines.each do |line_part|
26
+ if lines_left > 0
27
+ chunk << line_part
28
+ lines_left -= 1
29
+ else
30
+ leftover << line_part
31
+ end
32
+ end
33
+ output.print(chunk.join)
34
+
35
+ if lines_left == 0
36
+ break unless continue_paging?(page_num)
37
+ lines_left = @height
38
+ if leftover.size > 0
39
+ lines_left -= leftover.size
40
+ end
41
+ page_num += 1
42
+ return !callback.call(page_num) unless callback.nil?
43
+ end
44
+ end
45
+
46
+ if leftover.size > 0
47
+ output.print(leftover.join)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ # @api private
54
+ def continue_paging?(page_num)
55
+ instance_exec(page_num, &@prompt)
56
+ !@input.gets.chomp[/q/i]
57
+ end
58
+ end # BasicPager
59
+ end # Pager
60
+ end # TTY
@@ -0,0 +1,14 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class Pager
5
+ class NullPager < Pager
6
+ # Pass output directly to stdout
7
+ #
8
+ # @api public
9
+ def page(text, &callback)
10
+ output.puts(text)
11
+ end
12
+ end
13
+ end # Pager
14
+ end # TTY
@@ -0,0 +1,124 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class Pager
5
+ # A system pager is used on systems where native
6
+ # pagination exists
7
+ #
8
+ # @api public
9
+ class SystemPager < Pager
10
+ # Find first available system command for paging
11
+ #
12
+ # @example Basic usage
13
+ # available # => 'less'
14
+ #
15
+ # @example Usage with commands
16
+ # available('less', 'cat') # => 'less'
17
+ #
18
+ # @param [Array[String]] commands
19
+ #
20
+ # @return [String]
21
+ #
22
+ # @api public
23
+ def self.available(*commands)
24
+ commands = commands.empty? ? executables : commands
25
+ commands.compact.uniq.find { |cmd| command_exists?(cmd) }
26
+ end
27
+
28
+ # Check if command is available
29
+ #
30
+ # @example Basic usage
31
+ # available? # => true
32
+ #
33
+ # @example Usage with command
34
+ # available?('less') # => true
35
+ #
36
+ # @return [Boolean]
37
+ #
38
+ # @api public
39
+ def self.available?(*commands)
40
+ !available(*commands).nil?
41
+ end
42
+
43
+ # Use system command to page output text
44
+ #
45
+ # @example
46
+ # page('some long text...')
47
+ #
48
+ # @param [String] text
49
+ # the text to paginate
50
+ #
51
+ # @return [nil]
52
+ #
53
+ # @api public
54
+ def page(text, &callback)
55
+ read_io, write_io = IO.pipe
56
+
57
+ if Kernel.fork
58
+ # parent process
59
+ write_io.close
60
+ input.reopen(read_io)
61
+ read_io.close
62
+
63
+ # Wait until we have input before we start the pager
64
+ IO.select [input]
65
+
66
+ begin
67
+ exec(pager_command)
68
+ rescue SystemCallError
69
+ exit 1
70
+ end
71
+ else
72
+ # child process
73
+ read_io.close
74
+ write_io.write(text)
75
+ write_io.close
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ # List possible executables for output paging
82
+ #
83
+ # @return [Array[String]]
84
+ #
85
+ # @api private
86
+ def self.executables
87
+ [ENV['GIT_PAGER'], ENV['PAGER'],
88
+ `git config --get-all core.pager`.split.first,
89
+ 'less', 'more', 'cat', 'pager']
90
+ end
91
+ private_class_method :executables
92
+
93
+ # Check if command exists
94
+ #
95
+ # @example
96
+ # command_exists?('less) # => true
97
+ #
98
+ # @param [String] command
99
+ # the command to check
100
+ #
101
+ # @return [Boolean]
102
+ #
103
+ # @api private
104
+ def self.command_exists?(command)
105
+ !TTY::Which.which(command).nil?
106
+ end
107
+ private_class_method :command_exists?
108
+
109
+ # The pager command to run
110
+ #
111
+ # @return [String]
112
+ # the name of executable to run
113
+ #
114
+ # @api private
115
+ def pager_command(*commands)
116
+ @pager_command = if @pager_command && commands.empty?
117
+ @pager_command
118
+ else
119
+ self.class.available(*commands)
120
+ end
121
+ end
122
+ end # SystemPager
123
+ end # Pager
124
+ end # TTY
@@ -0,0 +1,7 @@
1
+ # coding: utf-8
2
+
3
+ module TTY
4
+ class Pager
5
+ VERSION = "0.1.0"
6
+ end # Pager
7
+ end # TTY
data/lib/tty/pager.rb ADDED
@@ -0,0 +1,129 @@
1
+ # coding: utf-8
2
+
3
+ require "tty/pager/basic"
4
+ require "tty/pager/null"
5
+ require "tty/pager/system"
6
+ require "tty/pager/version"
7
+
8
+ module TTY
9
+ class Pager
10
+ PROMPT_HEIGHT = 2
11
+
12
+ PAGE_BREAK = "\n--- Page -%s- " \
13
+ "Press enter/return to continue " \
14
+ "(or q to quit) ---".freeze
15
+
16
+ # Create a pager
17
+ #
18
+ # @param [Hash] options
19
+ # @option options [Proc] :prompt
20
+ # a proc object that accepts page number
21
+ # @option options [IO] :input
22
+ # the object to send input to
23
+ # @option options [IO] :output
24
+ # the object to send output to
25
+ # @option options [Integer] :height
26
+ # the terminal height
27
+ # @option options [Integer] :width
28
+ # the terminal width
29
+ # @option options [Boolean] :enabled
30
+ # disable/enable text paging
31
+ #
32
+ # @api public
33
+ def initialize(options = {})
34
+ @height = options.fetch(:height) { page_height }
35
+ @width = options.fetch(:width) { page_width }
36
+ @input = options.fetch(:input) { $stdin }
37
+ @output = options.fetch(:output) { $stdout }
38
+ @enabled = options.fetch(:enabled) { true }
39
+ @prompt = options.fetch(:prompt) { default_prompt }
40
+ @height -= PROMPT_HEIGHT
41
+ @output = output
42
+
43
+ if self.class == TTY::Pager
44
+ @pager = find_available
45
+ end
46
+ end
47
+
48
+ # Default prompt for paging
49
+ #
50
+ # @return [Proc]
51
+ #
52
+ # @api private
53
+ def default_prompt
54
+ proc { |page_num| output.puts PAGE_BREAK % page_num }
55
+ end
56
+
57
+ # Check if pager is enabled
58
+ #
59
+ # @return [Boolean]
60
+ #
61
+ # @api public
62
+ def enabled?
63
+ !!@enabled
64
+ end
65
+
66
+ # Page the given text through the available pager
67
+ #
68
+ # @param [String] text
69
+ # the text to run through a pager
70
+ #
71
+ # @yield [Integer] page number
72
+ #
73
+ # @return [TTY::Pager]
74
+ #
75
+ # @api public
76
+ def page(text, &callback)
77
+ pager.page(text, &callback)
78
+ self
79
+ end
80
+
81
+ # The terminal height
82
+ #
83
+ # @api public
84
+ def page_height
85
+ TTY::Screen.height
86
+ end
87
+
88
+ # The terminal width
89
+ #
90
+ # @api public
91
+ def page_width
92
+ TTY::Screen.width
93
+ end
94
+
95
+ protected
96
+
97
+ attr_reader :output
98
+
99
+ attr_reader :input
100
+
101
+ attr_reader :pager
102
+
103
+ # Find available pager
104
+ #
105
+ # If the user disabled paging then a NullPager is returned,
106
+ # otherwise a check is performed to find native system
107
+ # utility to perform pagination with SystemPager. Finally,
108
+ # if no system utility exists a BasicPager is used which
109
+ # is pure Ruby implementation.
110
+ #
111
+ # @api private
112
+ def find_available
113
+ if !enabled?
114
+ NullPager.new
115
+ elsif SystemPager.available? && !Pager.jruby?
116
+ SystemPager.new
117
+ else
118
+ BasicPager.new
119
+ end
120
+ end
121
+
122
+ # Check if running on jruby
123
+ #
124
+ # @api private
125
+ def self.jruby?
126
+ RbConfig::CONFIG['ruby_install_name'] == 'jruby'
127
+ end
128
+ end # Pager
129
+ end # TTY
data/lib/tty-pager.rb ADDED
@@ -0,0 +1,6 @@
1
+ # coding: utf-8
2
+
3
+ require 'tty-screen'
4
+ require 'tty-which'
5
+ require 'verse'
6
+ require 'tty/pager'
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+
3
+ if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ Coveralls::SimpleCov::Formatter
10
+ ]
11
+
12
+ SimpleCov.start do
13
+ command_name 'spec'
14
+ add_filter 'spec'
15
+ end
16
+ end
17
+
18
+ require 'tty-pager'
19
+
20
+ RSpec.configure do |config|
21
+ config.expect_with :rspec do |expectations|
22
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
+ end
24
+
25
+ config.mock_with :rspec do |mocks|
26
+ mocks.verify_partial_doubles = true
27
+ end
28
+
29
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
30
+ config.disable_monkey_patching!
31
+
32
+ # This setting enables warnings. It's recommended, but in some cases may
33
+ # be too noisy due to issues in dependencies.
34
+ config.warnings = true
35
+
36
+ if config.files_to_run.one?
37
+ config.default_formatter = 'doc'
38
+ end
39
+
40
+ config.profile_examples = 2
41
+
42
+ config.order = :random
43
+
44
+ Kernel.srand config.seed
45
+ end
@@ -0,0 +1,135 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Pager::BasicPager, '.page' do
4
+ let(:input) { StringIO.new }
5
+ let(:output) { StringIO.new }
6
+
7
+ it "doesn't paginate empty string" do
8
+ pager = described_class.new(output: output, input: input)
9
+ pager.page("")
10
+ expect(output.string).to eq("")
11
+ end
12
+
13
+ it "doesn't paginate text that fits on screen" do
14
+ text = "I try all things, I achieve what I can.\n"
15
+ pager = described_class.new(output: output, width: 100, height: 10)
16
+ pager.page(text)
17
+ expect(output.string).to eq(text)
18
+ end
19
+
20
+ it "breaks text exceeding terminal width" do
21
+ text = ""
22
+ text << "It is not down on any map; true places never are.\n"
23
+ input << "\n"
24
+ input.rewind
25
+ pager = described_class.new(output: output, input: input,
26
+ width: 10, height: 6)
27
+ pager.page(text)
28
+ expect(output.string).to eq([
29
+ "It is not ",
30
+ "down on ",
31
+ "any map; ",
32
+ "true ",
33
+ "",
34
+ "--- Page -1- Press enter/return to continue (or q to quit) ---",
35
+ "places ",
36
+ "never are.\n"
37
+ ].join("\n"))
38
+ end
39
+
40
+ it "continues paging when enter is pressed" do
41
+ text = ""
42
+ 10.times { text << "I try all things, I achieve what I can.\n"}
43
+ input << "\n\n\n"
44
+ input.rewind
45
+ pager = described_class.new(output: output, input: input,
46
+ width: 100, height: 5)
47
+ pager.page(text)
48
+ expect(output.string).to eq([
49
+ "I try all things, I achieve what I can.",
50
+ "I try all things, I achieve what I can.",
51
+ "I try all things, I achieve what I can.",
52
+ "",
53
+ "--- Page -1- Press enter/return to continue (or q to quit) ---",
54
+ "I try all things, I achieve what I can.",
55
+ "I try all things, I achieve what I can.",
56
+ "I try all things, I achieve what I can.",
57
+ "",
58
+ "--- Page -2- Press enter/return to continue (or q to quit) ---",
59
+ "I try all things, I achieve what I can.",
60
+ "I try all things, I achieve what I can.",
61
+ "I try all things, I achieve what I can.",
62
+ "",
63
+ "--- Page -3- Press enter/return to continue (or q to quit) ---",
64
+ "I try all things, I achieve what I can.\n"
65
+ ].join("\n"))
66
+ end
67
+
68
+ it "stops paging when q is pressed" do
69
+ text = ""
70
+ 10.times { text << "I try all things, I achieve what I can.\n"}
71
+ input << "\nq\n"
72
+ input.rewind
73
+ pager = described_class.new(output: output, input: input,
74
+ width: 100, height: 5)
75
+ pager.page(text)
76
+ expect(output.string).to eq([
77
+ "I try all things, I achieve what I can.",
78
+ "I try all things, I achieve what I can.",
79
+ "I try all things, I achieve what I can.",
80
+ "",
81
+ "--- Page -1- Press enter/return to continue (or q to quit) ---",
82
+ "I try all things, I achieve what I can.",
83
+ "I try all things, I achieve what I can.",
84
+ "I try all things, I achieve what I can.",
85
+ "",
86
+ "--- Page -2- Press enter/return to continue (or q to quit) ---\n",
87
+ ].join("\n"))
88
+ end
89
+
90
+ it "allows to change paging prompt" do
91
+ text = ""
92
+ 5.times { text << "I try all things, I achieve what I can.\n"}
93
+ input << "\nq\n"
94
+ input.rewind
95
+ prompt = proc { |num| output.puts "Page -#{num}-" }
96
+ pager = described_class.new(output: output, input: input,
97
+ width: 100, height: 5, prompt: prompt)
98
+ pager.page(text)
99
+ expect(output.string).to eq([
100
+ "I try all things, I achieve what I can.",
101
+ "I try all things, I achieve what I can.",
102
+ "I try all things, I achieve what I can.",
103
+ "Page -1-",
104
+ "I try all things, I achieve what I can.",
105
+ "I try all things, I achieve what I can.\n",
106
+ ].join("\n"))
107
+ end
108
+
109
+ it "preserves new lines when breaking" do
110
+ text = "a\na\na\na\na\na\na\na\na\na"
111
+ input << "\n\n\n"
112
+ input.rewind
113
+ pager = described_class.new(output: output, input: input,
114
+ width: 1, height: 5)
115
+ pager.page(text)
116
+ expect(output.string).to eq([
117
+ "a",
118
+ "a",
119
+ "a",
120
+ "",
121
+ "--- Page -1- Press enter/return to continue (or q to quit) ---",
122
+ "a",
123
+ "a",
124
+ "a",
125
+ "",
126
+ "--- Page -2- Press enter/return to continue (or q to quit) ---",
127
+ "a",
128
+ "a",
129
+ "a",
130
+ "",
131
+ "--- Page -3- Press enter/return to continue (or q to quit) ---",
132
+ "a"
133
+ ].join("\n"))
134
+ end
135
+ end
@@ -0,0 +1,12 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Pager::NullPager, '.page' do
4
+ let(:output) { StringIO.new }
5
+
6
+ it "doesn't paginate empty string" do
7
+ pager = described_class.new(output: output)
8
+ text = "I try all things, I achieve what I can.\n"
9
+ pager.page(text)
10
+ expect(output.string).to eq(text)
11
+ end
12
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Pager, '.page' do
4
+ let(:output) { StringIO.new }
5
+
6
+ it "selects null pager when disabled" do
7
+ null_pager = spy(:null_pager)
8
+ allow(TTY::Pager::NullPager).to receive(:new) { null_pager }
9
+
10
+ pager = described_class.new(enabled: false)
11
+ text = "I try all things, I achieve what I can.\n"
12
+ pager.page(text)
13
+
14
+ expect(TTY::Pager::NullPager).to have_received(:new)
15
+ end
16
+
17
+ it "selects basic pager on non tty systems" do
18
+ basic_pager = spy(:basic_pager)
19
+ allow(TTY::Pager::SystemPager).to receive(:available?) { false }
20
+ allow(TTY::Pager::BasicPager).to receive(:new) { basic_pager }
21
+
22
+ pager = described_class.new
23
+ text = "I try all things, I achieve what I can.\n"
24
+ pager.page(text)
25
+
26
+ expect(basic_pager).to have_received(:page).with(text)
27
+ end
28
+
29
+ it "selects system pager on systems with tty" do
30
+ system_pager = spy(:system_pager)
31
+ allow(TTY::Pager::SystemPager).to receive(:available?) { true }
32
+ allow(described_class).to receive(:jruby?) { false }
33
+ allow(TTY::Pager::SystemPager).to receive(:new) { system_pager }
34
+
35
+ pager = described_class.new
36
+ text = "I try all things, I achieve what I can.\n"
37
+ pager.page(text)
38
+
39
+ expect(system_pager).to have_received(:page).with(text)
40
+ end
41
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Pager::SystemPager, '#available' do
4
+ let(:execs) { ['less', 'more'] }
5
+
6
+ subject(:pager) { described_class }
7
+
8
+ it 'finds available command' do
9
+ allow(pager).to receive(:executables).and_return(execs)
10
+ allow(pager).to receive(:command_exists?).with('less') { true }
11
+ allow(pager).to receive(:command_exists?).with('more') { false }
12
+ expect(pager.available).to eql('less')
13
+ end
14
+
15
+ it "doesn't find command" do
16
+ allow(pager).to receive(:executables).and_return(execs)
17
+ allow(pager).to receive(:command_exists?) { false }
18
+ expect(pager.available).to be_nil
19
+ end
20
+
21
+ it "takes precedence over other commands" do
22
+ allow(pager).to receive(:command_exists?).with('more') { true }
23
+ expect(pager.available('more')).to eql('more')
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+
3
+ RSpec.describe TTY::Pager::SystemPager, '.page' do
4
+ let(:input) { StringIO.new }
5
+ let(:output) { StringIO.new }
6
+
7
+ it "executes the pager command in a subprocess" do
8
+ text = "I try all things, I achieve what I can.\n"
9
+ pager = described_class.new(output: output, input: input)
10
+
11
+ allow(pager).to receive(:exec)
12
+ allow(Kernel).to receive(:fork).and_return(true)
13
+ allow(pager).to receive(:pager_command).and_return('less')
14
+ allow(IO).to receive(:select)
15
+ allow(input).to receive(:reopen)
16
+
17
+ pager.page(text)
18
+
19
+ expect(IO).to have_received(:select).with([input])
20
+ expect(pager).to have_received(:exec).with('less')
21
+ expect(output.read).to eq('')
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Load gem inside irb console'
4
+ task :console do
5
+ require 'irb'
6
+ require 'irb/completion'
7
+ require File.join(__FILE__, '../../lib/tty-pager')
8
+ ARGV.clear
9
+ IRB.start
10
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ desc 'Measure code coverage'
4
+ task :coverage do
5
+ begin
6
+ original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
7
+ Rake::Task['spec'].invoke
8
+ ensure
9
+ ENV['COVERAGE'] = original
10
+ end
11
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc 'Run all specs'
7
+ RSpec::Core::RakeTask.new(:spec) do |task|
8
+ task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
9
+ end
10
+
11
+ namespace :spec do
12
+ desc 'Run unit specs'
13
+ RSpec::Core::RakeTask.new(:unit) do |task|
14
+ task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
15
+ end
16
+
17
+ desc 'Run integration specs'
18
+ RSpec::Core::RakeTask.new(:integration) do |task|
19
+ task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
20
+ end
21
+ end
22
+
23
+ rescue LoadError
24
+ %w[spec spec:unit spec:integration].each do |name|
25
+ task name do
26
+ $stderr.puts "In order to run #{name}, do `gem install rspec`"
27
+ end
28
+ end
29
+ end
data/tty-pager.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tty/pager/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tty-pager"
8
+ spec.version = TTY::Pager::VERSION
9
+ spec.authors = ["Piotr Murach"]
10
+ spec.email = [""]
11
+ spec.summary = %q{Terminal output paging in a cross-platform way supporting all major ruby interpreters.}
12
+ spec.description = %q{Terminal output paging in a cross-platform way supporting all major ruby interpreters.}
13
+ spec.homepage = "https://github.com/peter-murach/tty-pager"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'tty-screen', '~> 0.2.0'
22
+ spec.add_dependency 'tty-which', '~> 0.1.0'
23
+ spec.add_dependency 'verse', '~> 0.4.0'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.6'
26
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tty-pager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Murach
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tty-screen
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: tty-which
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: verse
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.4.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ description: Terminal output paging in a cross-platform way supporting all major ruby
70
+ interpreters.
71
+ email:
72
+ - ''
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - .rspec
79
+ - .ruby-version
80
+ - .travis.yml
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - lib/tty-pager.rb
86
+ - lib/tty/pager.rb
87
+ - lib/tty/pager/basic.rb
88
+ - lib/tty/pager/null.rb
89
+ - lib/tty/pager/system.rb
90
+ - lib/tty/pager/version.rb
91
+ - spec/spec_helper.rb
92
+ - spec/unit/basic/page_spec.rb
93
+ - spec/unit/null/page_spec.rb
94
+ - spec/unit/page_spec.rb
95
+ - spec/unit/system/available_spec.rb
96
+ - spec/unit/system/page_spec.rb
97
+ - tasks/console.rake
98
+ - tasks/coverage.rake
99
+ - tasks/spec.rake
100
+ - tty-pager.gemspec
101
+ homepage: https://github.com/peter-murach/tty-pager
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.0.3
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Terminal output paging in a cross-platform way supporting all major ruby
125
+ interpreters.
126
+ test_files:
127
+ - spec/spec_helper.rb
128
+ - spec/unit/basic/page_spec.rb
129
+ - spec/unit/null/page_spec.rb
130
+ - spec/unit/page_spec.rb
131
+ - spec/unit/system/available_spec.rb
132
+ - spec/unit/system/page_spec.rb
133
+ has_rdoc: