tty 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|