tty 0.0.9 → 0.0.10
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.
- data/.rspec +2 -1
- data/.travis.yml +3 -6
- data/README.md +232 -134
- data/lib/tty/plugins/plugin.rb +56 -0
- data/lib/tty/plugins.rb +75 -0
- data/lib/tty/shell/suggestion.rb +102 -0
- data/lib/tty/shell.rb +41 -14
- data/lib/tty/system/editor.rb +111 -0
- data/lib/tty/system/which.rb +13 -1
- data/lib/tty/system.rb +44 -28
- data/lib/tty/table/border/null.rb +0 -9
- data/lib/tty/table/border/row_line.rb +21 -0
- data/lib/tty/table/border.rb +63 -32
- data/lib/tty/table/border_dsl.rb +1 -1
- data/lib/tty/table/column_set.rb +16 -17
- data/lib/tty/table/field.rb +27 -7
- data/lib/tty/table/header.rb +18 -9
- data/lib/tty/table/operation/alignment_set.rb +20 -25
- data/lib/tty/table/operation/escape.rb +30 -0
- data/lib/tty/table/operation/filter.rb +36 -0
- data/lib/tty/table/operation/truncation.rb +22 -11
- data/lib/tty/table/operation/wrapped.rb +21 -10
- data/lib/tty/table/operations.rb +10 -8
- data/lib/tty/table/orientation/horizontal.rb +1 -1
- data/lib/tty/table/renderer/ascii.rb +3 -3
- data/lib/tty/table/renderer/basic.rb +135 -65
- data/lib/tty/table/renderer/color.rb +1 -4
- data/lib/tty/table/renderer/unicode.rb +3 -3
- data/lib/tty/table/renderer.rb +48 -61
- data/lib/tty/table/row.rb +30 -3
- data/lib/tty/table/transformation.rb +38 -0
- data/lib/tty/table/validatable.rb +7 -5
- data/lib/tty/table.rb +78 -99
- data/lib/tty/terminal/color.rb +2 -2
- data/lib/tty/terminal/echo.rb +1 -1
- data/lib/tty/terminal/pager/basic.rb +52 -0
- data/lib/tty/terminal/pager/system.rb +39 -0
- data/lib/tty/terminal/pager.rb +95 -0
- data/lib/tty/terminal.rb +30 -1
- data/lib/tty/version.rb +1 -1
- data/lib/tty.rb +41 -1
- data/spec/spec_helper.rb +20 -0
- data/spec/tty/plugins/find_spec.rb +28 -0
- data/spec/tty/plugins/load_spec.rb +20 -0
- data/spec/tty/plugins/plugin/load_spec.rb +30 -0
- data/spec/tty/plugins/plugin/new_spec.rb +18 -0
- data/spec/tty/shell/suggest_spec.rb +50 -0
- data/spec/tty/support/conversion_spec.rb +3 -3
- data/spec/tty/support/delegatable_spec.rb +1 -1
- data/spec/tty/support/equatable_spec.rb +6 -9
- data/spec/tty/system/editor/available_spec.rb +40 -0
- data/spec/tty/system/editor/build_spec.rb +40 -0
- data/spec/tty/system/editor/command_spec.rb +16 -0
- data/spec/tty/system/editor/executables_spec.rb +13 -0
- data/spec/tty/system/editor/invoke_spec.rb +38 -0
- data/spec/tty/system/editor/open_spec.rb +27 -0
- data/spec/tty/system/platform_spec.rb +4 -6
- data/spec/tty/system/which/which_spec.rb +48 -0
- data/spec/tty/system/which_spec.rb +8 -34
- data/spec/tty/table/border/ascii/rendering_spec.rb +19 -5
- data/spec/tty/table/border/new_spec.rb +1 -1
- data/spec/tty/table/border/null/rendering_spec.rb +24 -8
- data/spec/tty/table/border/unicode/rendering_spec.rb +19 -5
- data/spec/tty/table/column_set/extract_widths_spec.rb +4 -15
- data/spec/tty/table/column_set/total_width_spec.rb +15 -0
- data/spec/tty/table/data_spec.rb +14 -0
- data/spec/tty/table/each_spec.rb +17 -4
- data/spec/tty/table/each_with_index_spec.rb +34 -6
- data/spec/tty/table/field/length_spec.rb +21 -0
- data/spec/tty/table/field/lines_spec.rb +21 -0
- data/spec/tty/table/filter_spec.rb +23 -0
- data/spec/tty/table/header/call_spec.rb +1 -1
- data/spec/tty/table/header/height_spec.rb +27 -0
- data/spec/tty/table/initialize_spec.rb +6 -6
- data/spec/tty/table/operation/alignment_set/call_spec.rb +39 -0
- data/spec/tty/table/operation/escape/call_spec.rb +16 -0
- data/spec/tty/table/operation/filter/call_spec.rb +17 -0
- data/spec/tty/table/operation/truncation/call_spec.rb +15 -10
- data/spec/tty/table/operation/truncation/truncate_spec.rb +1 -1
- data/spec/tty/table/operation/wrapped/call_spec.rb +15 -10
- data/spec/tty/table/operation/wrapped/wrap_spec.rb +1 -1
- data/spec/tty/table/operations/new_spec.rb +4 -4
- data/spec/tty/table/options_spec.rb +0 -28
- data/spec/tty/table/orientation_spec.rb +5 -6
- data/spec/tty/table/properties_spec.rb +1 -4
- data/spec/tty/table/render_spec.rb +57 -0
- data/spec/tty/table/{renders_with_spec.rb → render_with_spec.rb} +29 -10
- data/spec/tty/table/renderer/ascii/render_spec.rb +68 -0
- data/spec/tty/table/renderer/ascii/separator_spec.rb +28 -0
- data/spec/tty/table/renderer/basic/alignment_spec.rb +18 -16
- data/spec/tty/table/renderer/basic/extract_column_widths_spec.rb +17 -12
- data/spec/tty/table/renderer/basic/filter_spec.rb +53 -0
- data/spec/tty/table/renderer/basic/multiline_content_spec.rb +135 -0
- data/spec/tty/table/renderer/basic/new_spec.rb +13 -2
- data/spec/tty/table/renderer/basic/options_spec.rb +48 -0
- data/spec/tty/table/renderer/basic/render_spec.rb +19 -121
- data/spec/tty/table/renderer/basic/separator_spec.rb +14 -48
- data/spec/tty/table/renderer/basic/truncation_spec.rb +35 -0
- data/spec/tty/table/renderer/basic/wrapping_spec.rb +40 -0
- data/spec/tty/table/{border_spec.rb → renderer/border_spec.rb} +17 -20
- data/spec/tty/table/renderer/select_spec.rb +22 -0
- data/spec/tty/table/{border → renderer}/style_spec.rb +13 -14
- data/spec/tty/table/renderer/unicode/render_spec.rb +68 -0
- data/spec/tty/table/renderer/unicode/separator_spec.rb +26 -0
- data/spec/tty/table/rotate_spec.rb +2 -3
- data/spec/tty/table/row/call_spec.rb +1 -1
- data/spec/tty/table/row/each_spec.rb +31 -0
- data/spec/tty/table/row/height_spec.rb +27 -0
- data/spec/tty/table/to_s_spec.rb +3 -3
- data/spec/tty/table/transformation/extract_tuples_spec.rb +35 -0
- data/spec/tty/table/validatable/validate_options_spec.rb +1 -2
- data/spec/tty/terminal/home_spec.rb +3 -3
- data/spec/tty/terminal/page_spec.rb +13 -0
- data/spec/tty/terminal/pager/available_spec.rb +40 -0
- data/spec/tty/terminal/pager/basic/page_spec.rb +54 -0
- data/spec/tty/terminal/pager/command_spec.rb +16 -0
- data/spec/tty/terminal/pager/executables_spec.rb +13 -0
- data/spec/tty/terminal/pager/page_spec.rb +47 -0
- data/spec/tty/terminal/pager/system/page_spec.rb +29 -0
- data/spec/tty/text/distance/distance_spec.rb +12 -0
- data/tty.gemspec +7 -3
- metadata +160 -27
- data/spec/tty/table/operation/alignment_set/align_rows_spec.rb +0 -53
- data/spec/tty/table/renderer/pick_renderer_spec.rb +0 -25
- data/spec/tty/table/renderer_spec.rb +0 -49
data/lib/tty/table.rb
CHANGED
@@ -8,12 +8,12 @@ require 'tty/table/header'
|
|
8
8
|
require 'tty/table/row'
|
9
9
|
|
10
10
|
module TTY
|
11
|
+
|
11
12
|
# A core class intended for storing data in a structured, tabular form.
|
12
13
|
# Once the data is stored in a TTY::Table various operations can be performed
|
13
14
|
# before the information is dumped into a stdout.
|
14
|
-
#
|
15
15
|
class Table
|
16
|
-
include Comparable, Enumerable,
|
16
|
+
include Comparable, Enumerable, Conversion
|
17
17
|
include Validatable, Equatable
|
18
18
|
extend Forwardable
|
19
19
|
|
@@ -30,26 +30,7 @@ module TTY
|
|
30
30
|
#
|
31
31
|
# @api private
|
32
32
|
attr_reader :rows
|
33
|
-
private :rows
|
34
|
-
|
35
|
-
# The table enforced column widths
|
36
|
-
#
|
37
|
-
# @return [Array]
|
38
|
-
#
|
39
|
-
# @api public
|
40
|
-
attr_accessor :column_widths
|
41
|
-
|
42
|
-
# The table column alignments
|
43
|
-
#
|
44
|
-
# @return [Array]
|
45
|
-
#
|
46
|
-
# @api private
|
47
|
-
attr_reader :column_aligns
|
48
|
-
|
49
|
-
# The table border class
|
50
|
-
#
|
51
|
-
# @api private
|
52
|
-
attr_reader :border_class
|
33
|
+
# private :rows
|
53
34
|
|
54
35
|
# The table orientation out of :horizontal and :vertical
|
55
36
|
#
|
@@ -58,18 +39,8 @@ module TTY
|
|
58
39
|
# @api public
|
59
40
|
attr_reader :orientation
|
60
41
|
|
61
|
-
# A callable object used for formatting field content
|
62
|
-
#
|
63
|
-
# @api public
|
64
|
-
attr_accessor :filter
|
65
|
-
|
66
|
-
# The table operations applied to rows
|
67
|
-
#
|
68
|
-
# @api public
|
69
|
-
attr_reader :operations
|
70
|
-
|
71
42
|
# Subset of safe methods that both Array and Hash implement
|
72
|
-
def_delegators(
|
43
|
+
def_delegators(:data, :assoc, :flatten, :include?, :index,
|
73
44
|
:length, :select, :to_a, :values_at, :pretty_print, :rassoc)
|
74
45
|
|
75
46
|
# Create a new Table where each argument is a row
|
@@ -79,7 +50,7 @@ module TTY
|
|
79
50
|
#
|
80
51
|
# @api public
|
81
52
|
def self.[](*rows)
|
82
|
-
self.new(:
|
53
|
+
self.new(rows: rows)
|
83
54
|
end
|
84
55
|
|
85
56
|
# Instantiate a new Table
|
@@ -105,27 +76,12 @@ module TTY
|
|
105
76
|
def self.new(*args, &block)
|
106
77
|
options = Utils.extract_options!(args)
|
107
78
|
if args.size.nonzero?
|
108
|
-
super(extract_tuples(args).merge(options), &block)
|
79
|
+
super(Transformation.extract_tuples(args).merge(options), &block)
|
109
80
|
else
|
110
81
|
super(options, &block)
|
111
82
|
end
|
112
83
|
end
|
113
84
|
|
114
|
-
# Extract header and row tuples from arguments
|
115
|
-
#
|
116
|
-
# @param [Array] args
|
117
|
-
#
|
118
|
-
# @api private
|
119
|
-
def self.extract_tuples(args)
|
120
|
-
rows = args.pop
|
121
|
-
header = args.size.zero? ? nil : args.first
|
122
|
-
if rows.first.is_a?(Hash)
|
123
|
-
header = rows.map(&:keys).flatten.uniq
|
124
|
-
rows = rows.inject([]) { |arr, el| arr + el.values }
|
125
|
-
end
|
126
|
-
{ :header => header, :rows => rows }
|
127
|
-
end
|
128
|
-
|
129
85
|
# Initialize a Table
|
130
86
|
#
|
131
87
|
# @param [Hash] options
|
@@ -134,12 +90,6 @@ module TTY
|
|
134
90
|
# column names to be displayed
|
135
91
|
# @option options [String] :rows
|
136
92
|
# Array of Arrays expressing the rows
|
137
|
-
# @option options [String] :renderer
|
138
|
-
# used to format table output
|
139
|
-
# @option options [String] :column_aligns
|
140
|
-
# used to format table individual column alignment
|
141
|
-
# @option options [String] :column_widths
|
142
|
-
# used to format table individula column width
|
143
93
|
# @option options [Symbol] :orientation
|
144
94
|
# used to transform table orientation
|
145
95
|
#
|
@@ -150,29 +100,21 @@ module TTY
|
|
150
100
|
validate_options! options
|
151
101
|
@header = (value = options[:header]) ? Header.new(value) : nil
|
152
102
|
@rows = coerce(options.fetch(:rows) { Row.new([]) })
|
153
|
-
@renderer = pick_renderer options[:renderer]
|
154
|
-
@border = TTY::Table::BorderOptions.from(options.delete(:border))
|
155
103
|
@orientation = Orientation.coerce(options.fetch(:orientation) { :horizontal })
|
104
|
+
@rotated = false
|
156
105
|
# TODO: assert that row_size is the same as column widths & aligns
|
157
|
-
@column_widths = Array(options.delete(:column_widths)).map(&:to_i)
|
158
|
-
@column_aligns = Array(options.delete(:column_aligns)).map(&:to_sym)
|
159
|
-
@operations = TTY::Table::Operations.new(self)
|
160
|
-
@operations.add_operation(:alignment, Operation::AlignmentSet.new(@column_aligns))
|
161
|
-
@filter = options.fetch(:filter) { nil }
|
162
|
-
@width = options.fetch(:width) { TTY.terminal.width }
|
163
|
-
|
164
106
|
assert_row_sizes @rows
|
165
107
|
@orientation.transform(self)
|
166
|
-
yield_or_eval
|
108
|
+
yield_or_eval(&block) if block_given?
|
167
109
|
end
|
168
110
|
|
169
|
-
#
|
111
|
+
# Provides access to all table data
|
170
112
|
#
|
171
|
-
# @
|
113
|
+
# @return [Array]
|
172
114
|
#
|
173
115
|
# @api public
|
174
|
-
def
|
175
|
-
|
116
|
+
def data
|
117
|
+
(header && !header.empty?) ? [header] + rows : rows
|
176
118
|
end
|
177
119
|
|
178
120
|
# Sets table orientation
|
@@ -225,31 +167,13 @@ module TTY
|
|
225
167
|
end
|
226
168
|
end
|
227
169
|
|
228
|
-
# Store border characters, style and separator for the table rendering
|
229
|
-
#
|
230
|
-
# @param [Hash, BorderOptions] options
|
231
|
-
#
|
232
|
-
# @yield [] block representing border options
|
233
|
-
#
|
234
|
-
# @api public
|
235
|
-
def border(options=(not_set=true), &block)
|
236
|
-
@border = TTY::Table::BorderOptions.new unless @border
|
237
|
-
if block_given?
|
238
|
-
border_dsl = TTY::Table::BorderDSL.new(&block)
|
239
|
-
@border = border_dsl.options
|
240
|
-
elsif !not_set
|
241
|
-
@border = TTY::Table::BorderOptions.from(options)
|
242
|
-
end
|
243
|
-
@border
|
244
|
-
end
|
245
|
-
|
246
170
|
# Lookup element of the table given a row(i) and column(j)
|
247
171
|
#
|
248
172
|
# @api public
|
249
173
|
def [](i, j=false)
|
250
174
|
return row(i) unless j
|
251
175
|
if i >= 0 && j >= 0
|
252
|
-
rows.fetch(i){return nil}[j]
|
176
|
+
rows.fetch(i) { return nil }[j]
|
253
177
|
else
|
254
178
|
raise TTY::Table::TupleMissing.new(i,j)
|
255
179
|
end
|
@@ -284,10 +208,10 @@ module TTY
|
|
284
208
|
# @api public
|
285
209
|
def row(index, &block)
|
286
210
|
if block_given?
|
287
|
-
rows.fetch(index){return self}.each(&block)
|
211
|
+
rows.fetch(index) { return self }.each(&block)
|
288
212
|
self
|
289
213
|
else
|
290
|
-
rows.fetch(index){return nil}
|
214
|
+
rows.fetch(index) { return nil }
|
291
215
|
end
|
292
216
|
end
|
293
217
|
|
@@ -350,7 +274,7 @@ module TTY
|
|
350
274
|
# @api public
|
351
275
|
def each
|
352
276
|
return to_enum unless block_given?
|
353
|
-
|
277
|
+
data.each { |row| yield row }
|
354
278
|
self
|
355
279
|
end
|
356
280
|
|
@@ -365,9 +289,17 @@ module TTY
|
|
365
289
|
# @api public
|
366
290
|
def each_with_index
|
367
291
|
return to_enum unless block_given?
|
292
|
+
start_index = 0
|
293
|
+
if header && !header.empty?
|
294
|
+
header.attributes.each_with_index do |el, col_index|
|
295
|
+
yield el, 0, col_index
|
296
|
+
end
|
297
|
+
start_index = 1
|
298
|
+
end
|
299
|
+
|
368
300
|
rows.each_with_index do |row, row_index|
|
369
|
-
row.each_with_index do |el, col_index|
|
370
|
-
yield el, row_index, col_index
|
301
|
+
row.fields.each_with_index do |el, col_index|
|
302
|
+
yield el, row_index + start_index, col_index
|
371
303
|
end
|
372
304
|
end
|
373
305
|
self
|
@@ -382,7 +314,7 @@ module TTY
|
|
382
314
|
#
|
383
315
|
# @api public
|
384
316
|
def column_size
|
385
|
-
return rows[0].size if
|
317
|
+
return rows[0].size if rows.size > 0
|
386
318
|
return 0
|
387
319
|
end
|
388
320
|
|
@@ -416,7 +348,7 @@ module TTY
|
|
416
348
|
#
|
417
349
|
# @api public
|
418
350
|
def width
|
419
|
-
ColumnSet.new(self).
|
351
|
+
ColumnSet.new(self).total_width
|
420
352
|
end
|
421
353
|
|
422
354
|
# Return true if this is an empty table, i.e. if the number of
|
@@ -429,13 +361,60 @@ module TTY
|
|
429
361
|
column_size == 0 || row_size == 0
|
430
362
|
end
|
431
363
|
|
432
|
-
# Return string representation of table
|
364
|
+
# Return string representation of table using basic renderer.
|
433
365
|
#
|
434
366
|
# @return [String]
|
435
367
|
#
|
436
368
|
# @api public
|
437
369
|
def to_s
|
438
|
-
render(
|
370
|
+
render(:basic)
|
371
|
+
end
|
372
|
+
|
373
|
+
# Render a given table. This method takes options which will be passed
|
374
|
+
# to the renderer prior to rendering, which allows the caller to set any
|
375
|
+
# table rendering variables.
|
376
|
+
#
|
377
|
+
# @param [Symbol] renderer_type
|
378
|
+
# the renderer to be used
|
379
|
+
#
|
380
|
+
# @param [Hash] options
|
381
|
+
#
|
382
|
+
# @yield [renderer]
|
383
|
+
#
|
384
|
+
# @yieldparam [TTY::Table::Renderer] renderer
|
385
|
+
# the renderer for the table
|
386
|
+
#
|
387
|
+
# @return [String]
|
388
|
+
#
|
389
|
+
# @api public
|
390
|
+
def render(*args, &block)
|
391
|
+
render_with(nil, *args, &block)
|
392
|
+
end
|
393
|
+
|
394
|
+
# Render a given table using custom border class.
|
395
|
+
#
|
396
|
+
# @param [TTY::Table::Border]
|
397
|
+
#
|
398
|
+
# @param [Symbol] renderer_type
|
399
|
+
#
|
400
|
+
# @yield [renderer]
|
401
|
+
#
|
402
|
+
# @yieldparam [TTY::Table::Renderer] renderer
|
403
|
+
# the renderer for the table
|
404
|
+
#
|
405
|
+
# @return [String]
|
406
|
+
#
|
407
|
+
# @api public
|
408
|
+
def render_with(border_class, renderer_type=(not_set=true), options={}, &block)
|
409
|
+
unless not_set
|
410
|
+
if renderer_type.respond_to?(:to_hash)
|
411
|
+
options = renderer_type
|
412
|
+
else
|
413
|
+
options[:renderer] = renderer_type
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
Renderer.render_with(border_class, self, options, &block)
|
439
418
|
end
|
440
419
|
|
441
420
|
# Coerce an Enumerable into a Table
|
@@ -453,7 +432,7 @@ module TTY
|
|
453
432
|
rows.map { |row| to_row(row, header) }
|
454
433
|
end
|
455
434
|
|
456
|
-
|
435
|
+
private
|
457
436
|
|
458
437
|
# Evaluate block
|
459
438
|
#
|
data/lib/tty/terminal/color.rb
CHANGED
@@ -76,7 +76,7 @@ module TTY
|
|
76
76
|
#
|
77
77
|
# @api public
|
78
78
|
def set(string, *colors)
|
79
|
-
validate
|
79
|
+
validate(*colors)
|
80
80
|
ansi_colors = colors.map { |color| lookup(color) }
|
81
81
|
"#{ansi_colors.join}#{string}#{CLEAR}"
|
82
82
|
end
|
@@ -108,7 +108,7 @@ module TTY
|
|
108
108
|
#
|
109
109
|
# @api public
|
110
110
|
def code(*colors)
|
111
|
-
validate
|
111
|
+
validate(*colors)
|
112
112
|
colors.map { |color| lookup(color) }
|
113
113
|
end
|
114
114
|
|
data/lib/tty/terminal/echo.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Terminal
|
5
|
+
|
6
|
+
# A class responsible for paging text
|
7
|
+
class BasicPager < Pager
|
8
|
+
|
9
|
+
PROMPT_HEIGHT = 3
|
10
|
+
|
11
|
+
PAGE_BREAK = "--- Press enter/return to continue (or q to quit) ---"
|
12
|
+
|
13
|
+
# Use ruby to page output text
|
14
|
+
#
|
15
|
+
# @api public
|
16
|
+
def page
|
17
|
+
text_lines = text.lines.to_a
|
18
|
+
|
19
|
+
text_lines.each_slice(page_size) do |chunk|
|
20
|
+
TTY.shell.say chunk.join
|
21
|
+
break if chunk.size < page_size
|
22
|
+
break if !continue?(text_lines)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Check whether to progress with paging
|
29
|
+
#
|
30
|
+
# @param [Array[String]] text_lines
|
31
|
+
#
|
32
|
+
# @return [Boolean]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
def continue?(text_lines)
|
36
|
+
if text_lines.size > page_size
|
37
|
+
question = TTY.shell.ask "\n#{PAGE_BREAK}"
|
38
|
+
return false if question.read_string[/q/i]
|
39
|
+
end
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
|
43
|
+
# Determine current page size
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
def page_size
|
47
|
+
@page_size ||= TTY.terminal.height - PROMPT_HEIGHT
|
48
|
+
end
|
49
|
+
|
50
|
+
end # BasicPager
|
51
|
+
end # Terminal
|
52
|
+
end # TTY
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Terminal
|
5
|
+
|
6
|
+
# A class responsible for paging text
|
7
|
+
class SystemPager < Pager
|
8
|
+
|
9
|
+
# Use system command to page output text
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
def page
|
13
|
+
read_io, write_io = IO.pipe
|
14
|
+
|
15
|
+
if Kernel.fork
|
16
|
+
# parent process
|
17
|
+
TTY.shell.input.reopen(read_io)
|
18
|
+
read_io.close
|
19
|
+
write_io.close
|
20
|
+
|
21
|
+
# Wait until we have input before we start the pager
|
22
|
+
Kernel.select [TTY.shell.stdin]
|
23
|
+
|
24
|
+
begin
|
25
|
+
Kernel.exec(Pager.command)
|
26
|
+
rescue
|
27
|
+
Kernel.exec "/bin/sh", "-c", command
|
28
|
+
end
|
29
|
+
else
|
30
|
+
# child process
|
31
|
+
write_io.write(text)
|
32
|
+
write_io.close
|
33
|
+
read_io.close
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end # SystemPager
|
38
|
+
end # Terminal
|
39
|
+
end # TTY
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Terminal
|
5
|
+
|
6
|
+
# A class responsible for paging text inside terminal
|
7
|
+
class Pager
|
8
|
+
|
9
|
+
attr_accessor :enabled
|
10
|
+
|
11
|
+
attr_reader :text
|
12
|
+
|
13
|
+
# Initialize a Pager
|
14
|
+
#
|
15
|
+
# @param [String] text
|
16
|
+
# the text to page
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
def initialize(text=nil)
|
20
|
+
@text = text
|
21
|
+
@enabled = true
|
22
|
+
end
|
23
|
+
|
24
|
+
# Check if pager is enabled
|
25
|
+
#
|
26
|
+
# @return [Boolean]
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
def enabled?
|
30
|
+
!!@enabled
|
31
|
+
end
|
32
|
+
|
33
|
+
# List possible executables for output paging
|
34
|
+
#
|
35
|
+
# @return [Array[String]]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
def self.executables
|
39
|
+
[ ENV['GIT_PAGER'], `git config --get-all core.pager`.split.first,
|
40
|
+
ENV['PAGER'], 'less -isr', 'more', 'cat', 'pager' ]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Find first available system command for paging
|
44
|
+
#
|
45
|
+
# @param [Array[String]] commands
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
def self.available(*commands)
|
51
|
+
commands = commands.empty? ? self.executables : commands
|
52
|
+
commands.compact.uniq.find { |cmd| System.exists?(cmd) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Check if paging command exists
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def self.available?
|
59
|
+
!!available
|
60
|
+
end
|
61
|
+
|
62
|
+
# Finds command to execute pager from shell commands unless configured is provided.
|
63
|
+
#
|
64
|
+
# @param [Array[String]] commands
|
65
|
+
#
|
66
|
+
# @return [String]
|
67
|
+
#
|
68
|
+
# @api private
|
69
|
+
def self.command(*commands)
|
70
|
+
@command = if (@command && commands.empty?)
|
71
|
+
@command
|
72
|
+
else
|
73
|
+
available(*commands)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Pages output using configured pager
|
78
|
+
#
|
79
|
+
# @param [String] text
|
80
|
+
# the text to page
|
81
|
+
#
|
82
|
+
# @api public
|
83
|
+
def self.page(text)
|
84
|
+
return unless TTY.shell.tty?
|
85
|
+
|
86
|
+
if System.unix? && available?
|
87
|
+
SystemPager.new(text).page
|
88
|
+
else
|
89
|
+
BasicPager.new(text).page
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Pager
|
94
|
+
end # Terminal
|
95
|
+
end # TTY
|
data/lib/tty/terminal.rb
CHANGED
@@ -26,9 +26,17 @@ module TTY
|
|
26
26
|
# @api public
|
27
27
|
attr_reader :color
|
28
28
|
|
29
|
+
# Output pager
|
30
|
+
#
|
31
|
+
# @return [Pager]
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
attr_reader :pager
|
35
|
+
|
29
36
|
def initialize
|
30
37
|
@color = TTY::Terminal::Color.new(self.color?)
|
31
38
|
@echo = TTY::Terminal::Echo.new
|
39
|
+
@pager = TTY::Terminal::Pager
|
32
40
|
@default_width = 80
|
33
41
|
@default_height = 24
|
34
42
|
end
|
@@ -149,14 +157,24 @@ module TTY
|
|
149
157
|
%x{tput colors 2>/dev/null}.to_i > 2
|
150
158
|
end
|
151
159
|
|
160
|
+
# Switch echo on
|
161
|
+
#
|
162
|
+
# @api public
|
152
163
|
def echo_on
|
153
164
|
@echo.on
|
154
165
|
end
|
155
166
|
|
167
|
+
# Switch echo off
|
168
|
+
#
|
169
|
+
# @api public
|
156
170
|
def echo_off
|
157
171
|
@echo.off
|
158
172
|
end
|
159
173
|
|
174
|
+
# Echo given block
|
175
|
+
#
|
176
|
+
# @param [Boolean] is_on
|
177
|
+
#
|
160
178
|
# @api public
|
161
179
|
def echo(is_on=true, &block)
|
162
180
|
@echo.echo(is_on, &block)
|
@@ -168,7 +186,18 @@ module TTY
|
|
168
186
|
#
|
169
187
|
# @api public
|
170
188
|
def home
|
171
|
-
@home ||= Home.new
|
189
|
+
@home ||= Home.new
|
190
|
+
@home.home
|
191
|
+
end
|
192
|
+
|
193
|
+
# Run text through a dynamically chosen pager
|
194
|
+
#
|
195
|
+
# @param [String] text
|
196
|
+
# the text to page
|
197
|
+
#
|
198
|
+
# @api public
|
199
|
+
def page(text)
|
200
|
+
@pager.page(text)
|
172
201
|
end
|
173
202
|
|
174
203
|
end # Terminal
|
data/lib/tty/version.rb
CHANGED
data/lib/tty.rb
CHANGED
@@ -17,6 +17,9 @@ require 'tty/vector'
|
|
17
17
|
require 'tty/shell'
|
18
18
|
require 'tty/coercer'
|
19
19
|
require 'tty/logger'
|
20
|
+
require 'tty/plugins'
|
21
|
+
|
22
|
+
require 'tty/plugins/plugin'
|
20
23
|
|
21
24
|
require 'tty/coercer/range'
|
22
25
|
require 'tty/coercer/integer'
|
@@ -28,14 +31,19 @@ require 'tty/shell/question'
|
|
28
31
|
require 'tty/shell/question/validation'
|
29
32
|
require 'tty/shell/question/modifier'
|
30
33
|
require 'tty/shell/statement'
|
34
|
+
require 'tty/shell/suggestion'
|
31
35
|
require 'tty/shell/reader'
|
32
36
|
require 'tty/shell/response'
|
33
37
|
|
34
38
|
require 'tty/terminal/color'
|
35
39
|
require 'tty/terminal/echo'
|
36
40
|
require 'tty/terminal/home'
|
41
|
+
require 'tty/terminal/pager'
|
42
|
+
require 'tty/terminal/pager/basic'
|
43
|
+
require 'tty/terminal/pager/system'
|
37
44
|
|
38
45
|
require 'tty/system/which'
|
46
|
+
require 'tty/system/editor'
|
39
47
|
|
40
48
|
require 'tty/text/distance'
|
41
49
|
require 'tty/text/truncation'
|
@@ -51,17 +59,21 @@ require 'tty/table/border_options'
|
|
51
59
|
require 'tty/table/border/unicode'
|
52
60
|
require 'tty/table/border/ascii'
|
53
61
|
require 'tty/table/border/null'
|
62
|
+
require 'tty/table/border/row_line'
|
54
63
|
|
55
64
|
require 'tty/table/column_set'
|
56
65
|
require 'tty/table/orientation'
|
57
66
|
require 'tty/table/orientation/horizontal'
|
58
67
|
require 'tty/table/orientation/vertical'
|
68
|
+
require 'tty/table/transformation'
|
59
69
|
|
60
70
|
require 'tty/table/operations'
|
61
71
|
require 'tty/table/operation/alignment_set'
|
62
72
|
require 'tty/table/operation/alignment'
|
63
73
|
require 'tty/table/operation/truncation'
|
64
74
|
require 'tty/table/operation/wrapped'
|
75
|
+
require 'tty/table/operation/filter'
|
76
|
+
require 'tty/table/operation/escape'
|
65
77
|
|
66
78
|
module TTY
|
67
79
|
|
@@ -89,13 +101,15 @@ module TTY
|
|
89
101
|
# Raised when the attribute is unknown
|
90
102
|
class UnknownAttributeError < IndexError; end
|
91
103
|
|
104
|
+
# Raised when command cannot be invoked
|
105
|
+
class CommandInvocationError < StandardError; end
|
92
106
|
|
93
107
|
# An empty array used as a default value
|
94
108
|
EMPTY_ARRAY = Array.new.freeze
|
95
109
|
|
96
110
|
class << self
|
97
111
|
|
98
|
-
# Return terminal instance
|
112
|
+
# Return shared terminal instance
|
99
113
|
#
|
100
114
|
# @return [TTY::Terminal]
|
101
115
|
#
|
@@ -104,6 +118,32 @@ module TTY
|
|
104
118
|
@terminal ||= Terminal.new
|
105
119
|
end
|
106
120
|
|
121
|
+
# Return shared shell instance
|
122
|
+
#
|
123
|
+
# @return [TTY::Shell]
|
124
|
+
#
|
125
|
+
# @api public
|
126
|
+
def shell(input=$stdin, output=$stdout)
|
127
|
+
@shell ||= Shell.new(input, output)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Return shared system object
|
131
|
+
#
|
132
|
+
# @return [TTY::System]
|
133
|
+
#
|
134
|
+
# @api public
|
135
|
+
def system
|
136
|
+
System
|
137
|
+
end
|
138
|
+
|
139
|
+
# Return shared plugins instance
|
140
|
+
#
|
141
|
+
# @return [TTY::Plugins]
|
142
|
+
#
|
143
|
+
# @api public
|
144
|
+
def plugins
|
145
|
+
@plugins ||= Plugins.new
|
146
|
+
end
|
107
147
|
end
|
108
148
|
|
109
149
|
end # TTY
|