tty-pager 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8dcb93333dbebd8cc1f528d51a3c4e28e39a90840d24b0e85bef6ba99dbee65
4
- data.tar.gz: 6b874380df90294f03af9dc7a6c68c078bfcd4a078f31da6a6379fc3b15f8b88
3
+ metadata.gz: adbdf02c80e21f7b2c2fc7723af3a00d268c8a57bffd321e8ed5126e6b7cc120
4
+ data.tar.gz: 4ff28aeef0acff9e54343e498e890bb2ffde576b771b4172326ef3dcdda67fc3
5
5
  SHA512:
6
- metadata.gz: b5e6eae2130ce1d007d86d76c9dac6fa8a023e8d1c9148a5bab0690d65cbcc205d1c6ace4bd4e8053bb25f63875fe24f2c22a926cfeb5fc11571f0ae5ba3e226
7
- data.tar.gz: d89926ee6548e078c7036cdb22f2bd398011e8f88b422433db7835e777ac939111fc6ffcfc14247b4376754f2a84ddcb003878ad1ecddd424e8a54de56264449
6
+ metadata.gz: 5614a278d417950a369489d6480203150da012ea19c1d2e1c564ac989d3f3c32074ce5f7ae61952536ec758f7602512415b63027f891e73b4d96151a6e9b02e4
7
+ data.tar.gz: ec0c2b331343284877e199e1f1672776e967f58f58b1b608ae73653f84905c6214b30990bb928b3f912f1d345dfce42dcfcc5947fd1fdd4f13330705844accaa
@@ -1,5 +1,27 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.13.0] - 2020-05-30
4
+
5
+ ### Added
6
+ * Add support for streaming by Andrew Radev(@AndrewRadev)
7
+ * Add SystemPager integration tests by Andrew Radev(@AndrewRadev)
8
+
9
+ ### Changed
10
+ * Change Pager structure and extract TTY::Pager::Abstract for the null, basic and
11
+ system pagers
12
+ * Change BasicPager paging prompt to return only formatted prompt text and
13
+ account for terminal height
14
+ * Change BasicPager to quit with a single keystroke
15
+ * Change BasicPager internals to increase readability
16
+ * Change SystemPager#command_exist? to search path
17
+ * Change tests structure for ease of maintenance by Andrew Radev(@AndrewRadev)
18
+ * Change gemspec to add metadata, remove test artefacts and dev dependencies
19
+ * Update strings & tty-screen dependencies
20
+ * Remove tty-which dependency
21
+
22
+ ### Fixed
23
+ * Fix SystemPager to run command test silently via Open3 and thus work on JRuby
24
+
3
25
  ## [v0.12.1] - 2019-03-16
4
26
 
5
27
  ### Fixed
@@ -106,6 +128,8 @@
106
128
 
107
129
  * Initial release
108
130
 
131
+ [v0.13.0]: https://github.com/piotrmurach/tty-pager/compare/v0.12.1...v0.13.0
132
+ [v0.12.1]: https://github.com/piotrmurach/tty-pager/compare/v0.12.0...v0.12.1
109
133
  [v0.12.0]: https://github.com/piotrmurach/tty-pager/compare/v0.11.0...v0.12.0
110
134
  [v0.11.0]: https://github.com/piotrmurach/tty-pager/compare/v0.10.0...v0.11.0
111
135
  [v0.10.0]: https://github.com/piotrmurach/tty-pager/compare/v0.9.0...v0.10.0
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://cdn.rawgit.com/piotrmurach/tty/master/images/tty.png" alt="tty logo" /></a>
2
+ <a href="https://piotrmurach.github.io/tty" target="_blank"><img width="130" src="https://github.com/piotrmurach/tty/raw/master/images/tty.png" alt="tty logo" /></a>
3
3
  </div>
4
4
 
5
5
  # TTY::Pager [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
@@ -19,9 +19,9 @@
19
19
  [coverage]: https://coveralls.io/github/piotrmurach/tty-pager
20
20
  [inchpages]: http://inch-ci.org/github/piotrmurach/tty-pager
21
21
 
22
- > Terminal output paging in a cross-platform way supporting all major ruby interpreters.
22
+ > A cross-platform terminal pager that works on all major Ruby interpreters.
23
23
 
24
- **TTY::Pager** provides independent terminal output paging component for [TTY](https://github.com/piotrmurach/tty) toolkit.
24
+ **TTY::Pager** provides independent terminal pager component for [TTY](https://github.com/piotrmurach/tty) toolkit.
25
25
 
26
26
  ## Installation
27
27
 
@@ -40,84 +40,286 @@ Or install it yourself as:
40
40
 
41
41
  ## Overview
42
42
 
43
- The **TTY::Pager** on initialization will choose the best available pager out of `SystemPager`, `BasicPager` or `NullPager`. If paging is disabled then a `NullPager` is used, which either returns text as is or simply prints it out to stdout on tty devices. Otherwise a check is performed to find paging command to page text with `SystemPager`. However, if no paging command is found, a `BasicPager` is used which is a pure Ruby implementation that is guaranteed to work with any ruby interpreter and any platform.
43
+ 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.
44
+
45
+ ## Contents
46
+
47
+ * [1. Usage](#1-usage)
48
+ * [2. API](#2-api)
49
+ * [2.1 new](#21-new)
50
+ * [2.1.1 :enabled](#211-enabled)
51
+ * [2.1.2 :command](#212-command)
52
+ * [2.1.3 :width](#213-width)
53
+ * [2.1.4 :prompt](#214-prompt)
54
+ * [2.2 page](#22-page)
55
+ * [2.3 write](#23-write)
56
+ * [2.4 try_write](#24-try_write)
57
+ * [2.5 puts](#25-puts)
58
+ * [2.6 close](#26-close)
59
+ * [2.7 ENV](#27-env)
44
60
 
45
61
  ## 1. Usage
46
62
 
47
- In order to let **TTY::Pager** pick the best paging mechanism automatically do:
63
+ The **TTY::Pager** will pick the best paging mechanism available on your system when initialized:
48
64
 
49
65
  ```ruby
50
66
  pager = TTY::Pager.new
51
67
  ```
52
68
 
53
- Then to perform actual content pagination invoke `page` method with the content to paginate as the argument:
69
+ Then to start paginating text call the `page` method with the content as the first argument:
54
70
 
55
71
  ```ruby
56
72
  pager.page("Very long text...")
57
73
  ```
58
74
 
59
- If you want to use specific pager you can do so by invoking it directly:
75
+ This will launch a pager in the background and wait until the user is done.
76
+
77
+ Alternatively, you can pass the `:path` keyword to specify a file path:
78
+
79
+ ```ruby
80
+ pager.page(path: "/path/to/filename.txt")
81
+ ```
82
+
83
+ If instead you'd like to paginate a long-running operation, you could use the block form of the pager:
84
+
85
+ ```ruby
86
+ TTY::Pager.page do |pager|
87
+ File.open("file_with_lots_of_lines.txt", "r").each_line do |line|
88
+ # do some work with the line
89
+
90
+ pager.write(line) # send it to the pager
91
+ end
92
+ end
93
+ ```
94
+
95
+ After block finishes, the pager is automatically closed.
96
+
97
+ For more control, you can translate the block form into separate `write` and `close` calls:
98
+
99
+ ```ruby
100
+ begin
101
+ pager = TTY::Pager.new
102
+
103
+ File.open("file_with_lots_of_lines.txt", "r").each_line do |line|
104
+ # do some work with the line
105
+
106
+ pager.write(line) # send it to the pager
107
+ end
108
+ rescue TTY::Pager::PagerClosed
109
+ # the user closed the paginating tool
110
+ ensure
111
+ pager.close
112
+ end
113
+ ```
114
+
115
+ If you want to use a specific pager you can do so by invoking it directly:
60
116
 
61
117
  ```ruby
62
118
  pager = TTY::Pager::BasicPager.new
119
+ # or
120
+ pager = TTY::Pager::SystemPager.new
121
+ # or
122
+ pager = TTY::Pager::NullPager.new
63
123
  ```
64
124
 
65
- ## 2. Interface
125
+ ## 2. API
126
+
127
+ ### 2.1 new
128
+
129
+ 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.
130
+
131
+ For example, to disable a pager in CI you could do:
132
+
133
+ ```ruby
134
+ pager = TTY::Pager.new(enabled: false)
135
+ ````
66
136
 
67
- ### :enabled
137
+ #### 2.1.1 :enabled
68
138
 
69
- If you want to disable the pager pass the `:enabled` option set to `false`:
139
+ If you want to disable the paging use the `:enabled` option set to `false`:
70
140
 
71
141
  ```ruby
72
142
  pager = TTY::Pager.new(enabled: false)
73
143
  ```
74
144
 
75
- ### :width
145
+ 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.
76
146
 
77
- The `BasicPager` allows to wrap content at given width:
147
+ #### 2.1.2 :command
148
+
149
+ To force `TTY::Pager` to always use a specific paging tool(s), use the `:command` option:
150
+
151
+ ```ruby
152
+ TTY::Pager.new(command: "less -R")
153
+ ```
154
+
155
+ The `:command` also accepts an array of pagers to use:
156
+
157
+ ```ruby
158
+ pager = TTY::Pager.new(command: ["less -r", "more -r"])
159
+ ```
160
+
161
+ If the provided pager command or commands don't exist on user's system, the pager will fallback automatically on a basic Ruby implementation.
162
+
163
+ To skip automatic detection of pager and always use a system pager do:
164
+
165
+ ```ruby
166
+ TTY::Pager::SystemPager.new(command: "less -R")
167
+ ```
168
+
169
+ #### 2.1.3 :width
170
+
171
+ Only the `BasicPager` allows you to wrap content at given terminal width:
78
172
 
79
173
  ```ruby
80
174
  pager = TTY::Pager.new(width: 80)
175
+ ```
176
+
177
+ This option doesn't affect the `SystemPager`.
178
+
179
+ To directly use `BasicPager` do:
180
+
181
+ ```ruby
81
182
  pager = TTY::Pager::BasicPager.new(width: 80)
82
183
  ```
83
184
 
84
- ### :prompt
185
+ #### 2.1.4 :prompt
186
+
187
+ To change the `BasicPager` page break prompt display, use the `:prompt` option:
188
+
189
+ ```ruby
190
+ prompt = -> (page) { "Page -#{page_num}- Press enter to continue" }
191
+ pager = TTY::Pager.new(prompt: prompt)
192
+ ```
193
+
194
+ ### 2.2 page
195
+
196
+ To start paging use the `page` method. It can be invoked on an instance or a class.
197
+
198
+ The class-level `page` is a convenient shortcut. To page some text you only need to do:
199
+
200
+ ```ruby
201
+ TTY::Pager.page("Some long text...")
202
+ ````
203
+
204
+ You can also include extra initialization parameters. For example, if you prefer to use a specific command do this:
205
+
206
+ ```ruby
207
+ TTY::Pager.page("Some long text...", command: "less -R")
208
+ ````
209
+
210
+ The instance equivalent would be:
211
+
212
+ ```ruby
213
+ pager = TTY::Pager.new(command: "less -R")
214
+ pager.page("Some long text...")
215
+ ````
216
+
217
+ Apart from text, you can page file content by passing the `:path` option:
218
+
219
+ ```ruby
220
+ TTY::Pager.page(path: "/path/to/filename.txt")
221
+ ````
222
+
223
+ 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:
224
+
225
+ ```ruby
226
+ TTY::Pager.page do |pager|
227
+ File.foreach("filename.txt") do |line|
228
+ # do some work with the line
229
+
230
+ pager.write(line) # write line to the pager
231
+ end
232
+ end
233
+ ```
234
+
235
+ The instance equivalent of the block version would be:
236
+
237
+ ```ruby
238
+ pager = TTY::Pager.new
239
+ begin
240
+ File.foreach("filename.txt") do |line|
241
+ # do some work with the line
242
+
243
+ pager.write(line) # write line to the pager
244
+ end
245
+ rescue TTY::Pager::PagerClosed
246
+ ensure
247
+ pager.close
248
+ end
249
+ ```
250
+
251
+ ### 2.3 write
252
+
253
+ To stream content to the pager use the `write` method.
254
+
255
+ ```ruby
256
+ pager.write("Some text")
257
+ ```
85
258
 
86
- For the `BasicPager` you can pass a `:prompt` option to change the page break text:
259
+ You can pass in any number of arguments:
87
260
 
88
261
  ```ruby
89
- prompt = -> (page_num) { output.puts "Page -#{page_num}- Press enter to continue" }
90
- pager = TTY::Pager::BasicPager.new(prompt: prompt)
262
+ pager.write("one", "two", "three")
91
263
  ```
92
264
 
93
- ### :command
265
+ ### 2.4 try_write
94
266
 
95
- You can force `SystemPager` to always use a specific paging tool(s) by passing the `:command` option:
267
+ To check if a write has been successful use `try_write`:
96
268
 
97
269
  ```ruby
98
- TTY::Pager.new(command: 'less -R')
99
- TTY::Pager::SystemPager.new(command: 'less -R')
270
+ pager.try_write("Some text")
271
+ # => true
100
272
  ```
101
273
 
102
- You also specify an array of pagers to use:
274
+ ### 2.5 puts
275
+
276
+ To write a line of text and end it with a new line use `puts` call:
103
277
 
104
278
  ```ruby
105
- pager = TTY::Pager.new(command: ['less -r', 'more -r'])
279
+ pager.puts("Single line of content")
106
280
  ```
107
281
 
108
- ### PAGER
282
+ ### 2.6 close
283
+
284
+ When you're done streaming content manually use `close` to finish paging.
109
285
 
110
- By default the `SystemPager` will check the `PAGER` environment variable, if not set it will try one of the `less`, `more`, `cat`, `pager`. Therefore, if you wish to set your preferred pager you can either set up your shell like so:
286
+ All interactions with a pager can raise an exception for various reasons, so wrap your code using the following pattern:
287
+
288
+ ```ruby
289
+ pager = TTY::Pager.new
290
+
291
+ begin
292
+ # ... perform pager writes
293
+ rescue TTY::Pager::PagerClosed
294
+ # the user closed the paginating tool
295
+ ensure
296
+ pager.close
297
+ end
298
+ ```
299
+
300
+ Alternatively use the class-level `page` call with a block to automatically close the pager:
301
+
302
+ ```ruby
303
+ TTY::Pager.page do |pager|
304
+ # ... perform pager writes
305
+ end
306
+ ```
307
+
308
+ ### 2.7 ENV
309
+
310
+ 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`.
311
+
312
+ Therefore, if you wish to set your preferred pager you can either set up your shell like so:
111
313
 
112
314
  ```bash
113
- PAGER=less
315
+ PAGER=less -R
114
316
  export PAGER
115
317
  ```
116
318
 
117
- or set `PAGER` in Ruby script:
319
+ Or set `PAGER` in Ruby script:
118
320
 
119
321
  ```ruby
120
- ENV['PAGER']='less'
322
+ ENV["PAGER"]="less -R"
121
323
  ```
122
324
 
123
325
  ## Contributing
@@ -130,6 +332,10 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/piotrm
130
332
  4. Push to the branch (`git push origin my-new-feature`)
131
333
  5. Create a new Pull Request
132
334
 
335
+ ## Code of Conduct
336
+
337
+ Everyone interacting in the TTY::Pager project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/piotrmurach/tty-pager/blob/master/CODE_OF_CONDUCT.md).
338
+
133
339
  ## Copyright
134
340
 
135
341
  Copyright (c) 2015 Piotr Murach. See LICENSE for further details.
@@ -1 +1 @@
1
- require_relative 'tty/pager'
1
+ require_relative "tty/pager"
@@ -1,103 +1,101 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'tty-screen'
4
-
5
- require_relative 'pager/basic'
6
- require_relative 'pager/null'
7
- require_relative 'pager/system'
8
- require_relative 'pager/version'
3
+ require_relative "pager/basic"
4
+ require_relative "pager/null"
5
+ require_relative "pager/system"
6
+ require_relative "pager/version"
9
7
 
10
8
  module TTY
11
- class Pager
9
+ module Pager
12
10
  Error = Class.new(StandardError)
13
11
 
14
- # Select an appriopriate pager
15
- #
16
- # If the user disabled paging then a NullPager is returned,
17
- # otherwise a check is performed to find native system
18
- # command to perform pagination with SystemPager. Finally,
19
- # if no system command is found, a BasicPager is used which
20
- # is a pure Ruby implementation known to work on any platform.
21
- #
22
- # @api private
23
- def self.select_pager(enabled, commands)
24
- if !enabled
25
- NullPager
26
- elsif SystemPager.exec_available?(*commands)
27
- SystemPager
28
- else
29
- BasicPager
30
- end
31
- end
12
+ # Raised when pager is closed
13
+ PagerClosed = Class.new(Error)
32
14
 
33
- # Create a pager
34
- #
35
- # @param [Hash] options
36
- # @option options [Proc] :prompt
37
- # a proc object that accepts page number
38
- # @option options [IO] :input
39
- # the object to send input to
40
- # @option options [IO] :output
41
- # the object to send output to
42
- # @option options [Boolean] :enabled
43
- # disable/enable text paging
44
- #
45
- # @api public
46
- def initialize(**options)
47
- @input = options.fetch(:input) { $stdin }
48
- @output = options.fetch(:output) { $stdout }
49
- @enabled = options.fetch(:enabled) { true }
50
- commands = Array(options[:command])
15
+ # Raised when user provides unnexpected argument
16
+ InvalidArgument = Class.new(Error)
51
17
 
52
- if self.class == TTY::Pager
53
- @pager = self.class.select_pager(@enabled, commands).new(options)
18
+ module ClassMethods
19
+ # Create a pager
20
+ #
21
+ # @param [Boolean] :enabled
22
+ # disable/enable text paging
23
+ # @param [String] :command
24
+ # the paging command
25
+ # @param [IO] :input
26
+ # the object to send input to
27
+ # @param [IO] :output
28
+ # the object to send output to
29
+ # @param [Proc] :prompt
30
+ # a proc object that accepts page number
31
+ # @param [Integer] :width
32
+ # the terminal width
33
+ # @param [Integer] :height
34
+ # the terminal height
35
+ #
36
+ # @api public
37
+ def new(enabled: true, command: nil, **options)
38
+ select_pager(enabled: enabled, command: command).new(
39
+ enabled: enabled, command: command, **options)
54
40
  end
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
41
 
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
42
+ # Paginate content through null, basic or system pager.
43
+ #
44
+ # @example
45
+ # TTY::Pager.page do |pager|
46
+ # pager.write "some text"
47
+ # end
48
+ #
49
+ # @param [String] :text
50
+ # an optional blob of content
51
+ # @param [String] :path
52
+ # a path to a file
53
+ # @param [Boolean] :enabled
54
+ # whether or not to use null pager
55
+ # @param [String] :command
56
+ # the paging command
57
+ # @param [IO] :input
58
+ # the object to send input to
59
+ # @param [IO] :output
60
+ # the object to send output to
61
+ #
62
+ # @api public
63
+ def page(text = nil, path: nil, enabled: true, command: nil,
64
+ **options, &block)
65
+ select_pager(enabled: enabled, command: command).
66
+ page(text, path: path, enabled: enabled, command: command,
67
+ **options, &block)
68
+ end
80
69
 
81
- # The terminal height
82
- #
83
- # @api public
84
- def page_height
85
- TTY::Screen.height
86
- end
70
+ # Select an appriopriate pager
71
+ #
72
+ # If the user disabled paging then a NullPager is returned,
73
+ # otherwise a check is performed to find native system
74
+ # command to perform pagination with SystemPager. Finally,
75
+ # if no system command is found, a BasicPager is used which
76
+ # is a pure Ruby implementation known to work on any platform.
77
+ #
78
+ # @param [Boolean] enabled
79
+ # whether or not to allow paging
80
+ # @param [String] command
81
+ # the command to run if available
82
+ #
83
+ # @api private
84
+ def select_pager(enabled: true, command: nil)
85
+ commands = Array(command)
87
86
 
88
- # The terminal width
89
- #
90
- # @api public
91
- def page_width
92
- TTY::Screen.width
87
+ if !enabled
88
+ NullPager
89
+ elsif SystemPager.exec_available?(*commands)
90
+ SystemPager
91
+ else
92
+ BasicPager
93
+ end
94
+ end
93
95
  end
94
96
 
95
- protected
96
-
97
- attr_reader :output
98
-
99
- attr_reader :input
97
+ extend ClassMethods
100
98
 
101
- attr_reader :pager
99
+ private_class_method :select_pager
102
100
  end # Pager
103
101
  end # TTY