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/column_set.rb
CHANGED
@@ -6,12 +6,12 @@ module TTY
|
|
6
6
|
# A class that represents table columns properties.
|
7
7
|
class ColumnSet
|
8
8
|
include Equatable
|
9
|
-
extend Delegatable
|
10
9
|
|
11
10
|
attr_reader :table
|
12
11
|
|
13
|
-
|
14
|
-
|
12
|
+
# Initialize a ColumnSet
|
13
|
+
#
|
14
|
+
# @api public
|
15
15
|
def initialize(table)
|
16
16
|
@table = table
|
17
17
|
end
|
@@ -22,7 +22,7 @@ module TTY
|
|
22
22
|
#
|
23
23
|
# @api public
|
24
24
|
def total_width
|
25
|
-
|
25
|
+
extract_widths.reduce(:+)
|
26
26
|
end
|
27
27
|
|
28
28
|
# Calcualte maximum column widths
|
@@ -30,15 +30,11 @@ module TTY
|
|
30
30
|
# @return [Array] column widths
|
31
31
|
#
|
32
32
|
# @api private
|
33
|
-
def extract_widths
|
34
|
-
|
35
|
-
|
36
|
-
rows = table.to_a
|
37
|
-
data = table.header ? rows + [table.header] : rows
|
33
|
+
def extract_widths
|
34
|
+
data = table.data
|
38
35
|
colcount = data.max { |row_a, row_b| row_a.size <=> row_b.size }.size
|
39
36
|
|
40
|
-
|
41
|
-
self
|
37
|
+
self.class.find_maximas(colcount, data)
|
42
38
|
end
|
43
39
|
|
44
40
|
private
|
@@ -51,25 +47,28 @@ module TTY
|
|
51
47
|
# the table's header and rows
|
52
48
|
#
|
53
49
|
# @api private
|
54
|
-
def find_maximas(colcount, data)
|
50
|
+
def self.find_maximas(colcount, data)
|
55
51
|
maximas = []
|
56
52
|
start = 0
|
57
53
|
|
58
|
-
start.upto(colcount - 1) do |
|
59
|
-
maximas << find_maximum(data,
|
54
|
+
start.upto(colcount - 1) do |col_index|
|
55
|
+
maximas << find_maximum(data, col_index)
|
60
56
|
end
|
61
57
|
maximas
|
62
58
|
end
|
63
59
|
|
64
|
-
# Find a maximum column width.
|
60
|
+
# Find a maximum column width. The calculation takes into account
|
61
|
+
# wether the content is escaped or not.
|
65
62
|
#
|
66
63
|
# @param [Array] data
|
64
|
+
# the table data
|
67
65
|
#
|
68
66
|
# @param [Integer] index
|
67
|
+
# the column index
|
69
68
|
#
|
70
69
|
# @api private
|
71
|
-
def find_maximum(data, index)
|
72
|
-
data.map { |row| row
|
70
|
+
def self.find_maximum(data, index)
|
71
|
+
data.map { |row| (value=row.call(index)) ? value.length : 0 }.max
|
73
72
|
end
|
74
73
|
|
75
74
|
end # ColumnSet
|
data/lib/tty/table/field.rb
CHANGED
@@ -69,20 +69,40 @@ module TTY
|
|
69
69
|
@height
|
70
70
|
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
# Return number of lines this value spans
|
72
|
+
# Return number of lines this value spans. A distinction is being made
|
73
|
+
# between escaped and non-escaped strings.
|
74
|
+
#
|
75
|
+
# @return [Array[String]]
|
77
76
|
#
|
77
|
+
# @api public
|
78
78
|
def lines
|
79
|
-
value.to_s.
|
79
|
+
escaped = value.to_s.scan(/(\\n|\\t|\\r)/)
|
80
|
+
escaped.empty? ? value.to_s.split(/\n/) : [value.to_s]
|
80
81
|
end
|
81
82
|
|
82
|
-
|
83
|
+
# If the string contains unescaped new lines then the longest token
|
84
|
+
# deterimines the actual field length.
|
85
|
+
#
|
86
|
+
# @return [Integer]
|
87
|
+
#
|
88
|
+
# @api public
|
89
|
+
def length
|
83
90
|
lines.max_by(&:length).size
|
84
91
|
end
|
85
92
|
|
93
|
+
# Extract the number of lines this value spans
|
94
|
+
#
|
95
|
+
# @return [Integer]
|
96
|
+
#
|
97
|
+
# @api public
|
98
|
+
def height
|
99
|
+
lines.size
|
100
|
+
end
|
101
|
+
|
102
|
+
def chars
|
103
|
+
value.chars
|
104
|
+
end
|
105
|
+
|
86
106
|
# Render value inside this field box
|
87
107
|
#
|
88
108
|
# @api public
|
data/lib/tty/table/header.rb
CHANGED
@@ -28,6 +28,7 @@ module TTY
|
|
28
28
|
#
|
29
29
|
# @api private
|
30
30
|
attr_reader :attributes
|
31
|
+
alias :fields :attributes
|
31
32
|
|
32
33
|
# Initialize a Header
|
33
34
|
#
|
@@ -46,13 +47,6 @@ module TTY
|
|
46
47
|
Field.new(options)
|
47
48
|
end
|
48
49
|
|
49
|
-
# Filter header names including styling background,
|
50
|
-
# text color and capitalization
|
51
|
-
#
|
52
|
-
#
|
53
|
-
def filter
|
54
|
-
end
|
55
|
-
|
56
50
|
# Lookup a column in the header given a name
|
57
51
|
#
|
58
52
|
# @api public
|
@@ -66,7 +60,13 @@ module TTY
|
|
66
60
|
end
|
67
61
|
end
|
68
62
|
end
|
69
|
-
|
63
|
+
|
64
|
+
# Lookup attribute without evaluation
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
def call(attribute)
|
68
|
+
@attributes[attribute]
|
69
|
+
end
|
70
70
|
|
71
71
|
# Set value at index
|
72
72
|
#
|
@@ -86,11 +86,20 @@ module TTY
|
|
86
86
|
end
|
87
87
|
alias :length :size
|
88
88
|
|
89
|
+
# Find maximum header height
|
90
|
+
#
|
91
|
+
# @return [Integer]
|
92
|
+
#
|
93
|
+
# @api public
|
94
|
+
def height
|
95
|
+
attributes.map { |field| field.height }.max
|
96
|
+
end
|
97
|
+
|
89
98
|
# Convert the Header into an Array
|
90
99
|
#
|
91
100
|
# @api public
|
92
101
|
def to_ary
|
93
|
-
attributes.map { |attr| attr.value if attr
|
102
|
+
attributes.map { |attr| attr.value if attr }
|
94
103
|
end
|
95
104
|
|
96
105
|
# Check if this header is equivalent to another header
|
@@ -7,6 +7,13 @@ module TTY
|
|
7
7
|
# A class which responsiblity is to align table rows and header.
|
8
8
|
class AlignmentSet < Vector
|
9
9
|
|
10
|
+
attr_reader :widths
|
11
|
+
|
12
|
+
def initialize(aligns, widths=nil)
|
13
|
+
@elements = convert_to_array(aligns)
|
14
|
+
@widths = widths
|
15
|
+
end
|
16
|
+
|
10
17
|
# Lookup an alignment by index
|
11
18
|
#
|
12
19
|
# @param [Integer]
|
@@ -34,44 +41,32 @@ module TTY
|
|
34
41
|
# @param [Hash] options
|
35
42
|
# the table options
|
36
43
|
#
|
37
|
-
# @return [
|
44
|
+
# @return [TTY::Table::Field]
|
38
45
|
#
|
39
46
|
# @api public
|
40
|
-
def call(row,
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
# Align the supplied rows with the correct alignment.
|
45
|
-
#
|
46
|
-
# @param [Array] rows
|
47
|
-
#
|
48
|
-
# @return [Array[Array]]
|
49
|
-
# the aligned rows
|
50
|
-
#
|
51
|
-
# @api private
|
52
|
-
def align_rows(rows, options={})
|
53
|
-
rows.map { |row| align_row(row, options) }
|
47
|
+
def call(field, row, col)
|
48
|
+
align_field(field, col)
|
54
49
|
end
|
55
50
|
|
56
51
|
private
|
57
52
|
|
58
53
|
# Align each field in a row
|
59
54
|
#
|
60
|
-
# @param [
|
55
|
+
# @param [TTY::Table::Field] field
|
56
|
+
# the table field
|
57
|
+
#
|
58
|
+
# @param [Integer] col
|
59
|
+
# the table column index
|
61
60
|
#
|
62
61
|
# @param [Hash] options
|
63
62
|
#
|
64
|
-
# @return [
|
63
|
+
# @return [TTY::Table::Field]
|
65
64
|
#
|
66
65
|
# @api private
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
alignment = Alignment.new(field.align || self[index])
|
72
|
-
index += 1
|
73
|
-
alignment.format(field, column_width)
|
74
|
-
end
|
66
|
+
def align_field(field, col)
|
67
|
+
column_width = widths[col]
|
68
|
+
alignment = Alignment.new(field.align || self[col])
|
69
|
+
field.value = alignment.format(field, column_width)
|
75
70
|
end
|
76
71
|
|
77
72
|
end # AlignmentSet
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Table
|
5
|
+
module Operation
|
6
|
+
|
7
|
+
# A class responsible for escaping special chars in a table field
|
8
|
+
class Escape
|
9
|
+
|
10
|
+
# Escape special characters in a table field
|
11
|
+
#
|
12
|
+
# @param [TTY::Table::Field] field
|
13
|
+
#
|
14
|
+
# @param [Integer] row
|
15
|
+
# the field row index
|
16
|
+
#
|
17
|
+
# @param [Integer] col
|
18
|
+
# the field column index
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
def call(field, row, col)
|
22
|
+
field.value = field.value.gsub(/(\t|\r|\n)/) do |val|
|
23
|
+
val.dump.gsub('"', '')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end # Escape
|
28
|
+
end # Operation
|
29
|
+
end # Table
|
30
|
+
end # TTY
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Table
|
5
|
+
module Operation
|
6
|
+
|
7
|
+
# A class responsible for transforming table field
|
8
|
+
class Filter
|
9
|
+
|
10
|
+
# Initialize a Filter
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
def initialize(filter)
|
14
|
+
@filter = filter
|
15
|
+
end
|
16
|
+
|
17
|
+
# Apply filer to the provided table field
|
18
|
+
#
|
19
|
+
# @param [TTY::Table::Field] field
|
20
|
+
#
|
21
|
+
# @param [Integer] row
|
22
|
+
# the field row index
|
23
|
+
#
|
24
|
+
# @param [Integer] col
|
25
|
+
# the field column index
|
26
|
+
#
|
27
|
+
# @api public
|
28
|
+
def call(field, row, col)
|
29
|
+
field.value = @filter.call(field.value, row, col)
|
30
|
+
end
|
31
|
+
|
32
|
+
end # Filter
|
33
|
+
|
34
|
+
end # Operation
|
35
|
+
end # Table
|
36
|
+
end # TTY
|
@@ -7,21 +7,32 @@ module TTY
|
|
7
7
|
# A class responsible for shortening text.
|
8
8
|
class Truncation
|
9
9
|
|
10
|
-
|
10
|
+
attr_reader :widths
|
11
|
+
|
12
|
+
# Initialize a Truncation
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
def initialize(widths)
|
16
|
+
@widths = widths
|
17
|
+
end
|
18
|
+
|
19
|
+
# Apply truncation to a field
|
20
|
+
#
|
21
|
+
# @param [TTY::Table::Field] field
|
22
|
+
# the table field
|
23
|
+
#
|
24
|
+
# @param [Integer] row
|
25
|
+
# the field row index
|
11
26
|
#
|
12
|
-
# @param [
|
13
|
-
# the
|
27
|
+
# @param [Integer] col
|
28
|
+
# the field column index
|
14
29
|
#
|
15
|
-
# @return [
|
30
|
+
# @return [TTY::Table::Field]
|
16
31
|
#
|
17
32
|
# @api public
|
18
|
-
def call(row,
|
19
|
-
|
20
|
-
|
21
|
-
width = options.fetch(:column_widths, {})[index] || field.width
|
22
|
-
index += 1
|
23
|
-
field.value = truncate(field.value, width)
|
24
|
-
end
|
33
|
+
def call(field, row, col)
|
34
|
+
width = widths[col] || field.width
|
35
|
+
field.value = truncate(field.value, width)
|
25
36
|
end
|
26
37
|
|
27
38
|
# Shorten given string with traling character.
|
@@ -7,21 +7,32 @@ module TTY
|
|
7
7
|
# A class responsible for wrapping text.
|
8
8
|
class Wrapped
|
9
9
|
|
10
|
-
|
10
|
+
attr_reader :widths
|
11
|
+
|
12
|
+
# Initialize a Wrapped
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
def initialize(widths)
|
16
|
+
@widths = widths
|
17
|
+
end
|
18
|
+
|
19
|
+
# Apply wrapping to a field
|
20
|
+
#
|
21
|
+
# @param [TTY::Table::Field] field
|
22
|
+
# the table field
|
23
|
+
#
|
24
|
+
# @param [Integer] row
|
25
|
+
# the field row index
|
11
26
|
#
|
12
|
-
# @param [
|
13
|
-
# the
|
27
|
+
# @param [Integer] col
|
28
|
+
# the field column index
|
14
29
|
#
|
15
30
|
# @return [Array[String]]
|
16
31
|
#
|
17
32
|
# @api public
|
18
|
-
def call(row,
|
19
|
-
|
20
|
-
|
21
|
-
width = options.fetch(:column_widths, {})[index] || field.width
|
22
|
-
index += 1
|
23
|
-
field.value = wrap(field.value, width)
|
24
|
-
end
|
33
|
+
def call(field, row, col)
|
34
|
+
width = widths[col] || field.width
|
35
|
+
field.value = wrap(field.value, width)
|
25
36
|
end
|
26
37
|
|
27
38
|
# Wrap a long string according to the width.
|
data/lib/tty/table/operations.rb
CHANGED
@@ -49,19 +49,21 @@ module TTY
|
|
49
49
|
|
50
50
|
# Apply operations to a table row
|
51
51
|
#
|
52
|
-
# @param [Symbol]
|
53
|
-
# the operation
|
54
|
-
# @param [#to_ary, Row] row
|
55
|
-
# the row to apply operation to
|
52
|
+
# @param [Array[Symbol]] types
|
53
|
+
# the operation types
|
56
54
|
# @param [Hash] options
|
57
55
|
# the options for the row
|
58
56
|
#
|
59
|
-
# @return [
|
57
|
+
# @return [TTY::Table]
|
60
58
|
#
|
61
59
|
# @api public
|
62
|
-
def run_operations(
|
63
|
-
|
64
|
-
|
60
|
+
def run_operations(*args)
|
61
|
+
types = args
|
62
|
+
table.each_with_index do |val, row, col|
|
63
|
+
types.each do |type|
|
64
|
+
operations[type].each { |op| op.call(val, row, col) }
|
65
|
+
end
|
66
|
+
end
|
65
67
|
end
|
66
68
|
|
67
69
|
end # Operations
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module TTY
|
4
4
|
class Table
|
5
|
-
|
5
|
+
class Renderer
|
6
6
|
class ASCII < Basic
|
7
7
|
|
8
|
-
def
|
9
|
-
super
|
8
|
+
def initialize(table, options={})
|
9
|
+
super(table, options.merge(:border_class => TTY::Table::Border::ASCII))
|
10
10
|
end
|
11
11
|
|
12
12
|
end # ASCII
|