tty-pager 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: