tty 0.0.6 → 0.0.7
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/README.md +78 -12
- data/benchmarks/shell.rb +26 -0
- data/benchmarks/table.rb +35 -0
- data/lib/tty.rb +23 -1
- data/lib/tty/coercer.rb +13 -0
- data/lib/tty/coercer/boolean.rb +39 -0
- data/lib/tty/coercer/float.rb +23 -0
- data/lib/tty/coercer/integer.rb +23 -0
- data/lib/tty/coercer/range.rb +33 -0
- data/lib/tty/shell.rb +6 -2
- data/lib/tty/shell/question.rb +158 -138
- data/lib/tty/shell/reader.rb +92 -0
- data/lib/tty/shell/response.rb +219 -0
- data/lib/tty/shell/response_delegation.rb +53 -0
- data/lib/tty/table.rb +90 -16
- data/lib/tty/table/border.rb +34 -8
- data/lib/tty/table/border/ascii.rb +16 -25
- data/lib/tty/table/border/null.rb +0 -6
- data/lib/tty/table/border/unicode.rb +16 -25
- data/lib/tty/table/column_set.rb +1 -1
- data/lib/tty/table/error.rb +10 -0
- data/lib/tty/table/operation/wrapped.rb +0 -6
- data/lib/tty/table/orientation.rb +57 -0
- data/lib/tty/table/orientation/horizontal.rb +19 -0
- data/lib/tty/table/orientation/vertical.rb +19 -0
- data/lib/tty/table/renderer.rb +7 -0
- data/lib/tty/table/renderer/ascii.rb +1 -1
- data/lib/tty/table/renderer/basic.rb +2 -2
- data/lib/tty/table/renderer/unicode.rb +1 -1
- data/lib/tty/table/validatable.rb +20 -0
- data/lib/tty/terminal.rb +15 -14
- data/lib/tty/terminal/color.rb +1 -1
- data/lib/tty/terminal/echo.rb +41 -0
- data/lib/tty/terminal/home.rb +31 -0
- data/lib/tty/text.rb +85 -0
- data/lib/tty/text/truncation.rb +83 -0
- data/lib/tty/text/wrapping.rb +96 -0
- data/lib/tty/version.rb +1 -1
- data/spec/tty/coercer/boolean/coerce_spec.rb +113 -0
- data/spec/tty/coercer/float/coerce_spec.rb +32 -0
- data/spec/tty/coercer/integer/coerce_spec.rb +39 -0
- data/spec/tty/coercer/range/coerce_spec.rb +73 -0
- data/spec/tty/shell/ask_spec.rb +14 -1
- data/spec/tty/shell/question/argument_spec.rb +30 -0
- data/spec/tty/shell/question/character_spec.rb +16 -0
- data/spec/tty/shell/question/default_spec.rb +25 -0
- data/spec/tty/shell/question/in_spec.rb +23 -0
- data/spec/tty/shell/question/initialize_spec.rb +11 -211
- data/spec/tty/shell/question/modifier/whitespace_spec.rb +1 -1
- data/spec/tty/shell/question/modify_spec.rb +44 -0
- data/spec/tty/shell/question/valid_spec.rb +46 -0
- data/spec/tty/shell/question/validate_spec.rb +30 -0
- data/spec/tty/shell/reader/getc_spec.rb +40 -0
- data/spec/tty/shell/response/read_bool_spec.rb +41 -0
- data/spec/tty/shell/response/read_char_spec.rb +17 -0
- data/spec/tty/shell/response/read_date_spec.rb +20 -0
- data/spec/tty/shell/response/read_email_spec.rb +43 -0
- data/spec/tty/shell/response/read_multiple_spec.rb +24 -0
- data/spec/tty/shell/response/read_number_spec.rb +29 -0
- data/spec/tty/shell/response/read_range_spec.rb +29 -0
- data/spec/tty/shell/response/read_spec.rb +68 -0
- data/spec/tty/shell/response/read_string_spec.rb +19 -0
- data/spec/tty/table/access_spec.rb +6 -0
- data/spec/tty/table/border/new_spec.rb +3 -3
- data/spec/tty/table/initialize_spec.rb +17 -1
- data/spec/tty/table/options_spec.rb +7 -1
- data/spec/tty/table/orientation_spec.rb +98 -0
- data/spec/tty/table/renders_with_spec.rb +76 -0
- data/spec/tty/table/rotate_spec.rb +72 -0
- data/spec/tty/table/to_s_spec.rb +13 -1
- data/spec/tty/table/validatable/validate_options_spec.rb +34 -0
- data/spec/tty/terminal/color/remove_spec.rb +34 -1
- data/spec/tty/terminal/echo_spec.rb +22 -0
- data/spec/tty/text/truncate_spec.rb +13 -0
- data/spec/tty/text/truncation/initialize_spec.rb +29 -0
- data/spec/tty/text/truncation/truncate_spec.rb +73 -0
- data/spec/tty/text/wrap_spec.rb +14 -0
- data/spec/tty/text/wrapping/initialize_spec.rb +25 -0
- data/spec/tty/text/wrapping/wrap_spec.rb +80 -0
- data/tty.gemspec +1 -0
- metadata +101 -8
data/lib/tty/table/border.rb
CHANGED
@@ -7,8 +7,6 @@ module TTY
|
|
7
7
|
class Border
|
8
8
|
include Unicode
|
9
9
|
|
10
|
-
NEWLINE = "\n"
|
11
|
-
|
12
10
|
# The row cell widths
|
13
11
|
#
|
14
12
|
# @api private
|
@@ -21,26 +19,53 @@ module TTY
|
|
21
19
|
attr_reader :row
|
22
20
|
private :row
|
23
21
|
|
22
|
+
class << self
|
23
|
+
# Store characters for border
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
attr_accessor :characters
|
27
|
+
end
|
28
|
+
|
24
29
|
# Instantiate a new object
|
25
30
|
#
|
26
31
|
# @return [Object]
|
27
32
|
#
|
28
33
|
# @api private
|
29
|
-
def initialize(
|
34
|
+
def initialize(row=nil)
|
30
35
|
if self.class == Border
|
31
36
|
raise NotImplementedError, "#{self} is an abstract class"
|
32
37
|
else
|
33
|
-
|
38
|
+
@row = row
|
39
|
+
@widths = row.map { |cell| cell.chars.to_a.size }
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
43
|
+
# Define border characters
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def self.def_border(&block)
|
47
|
+
@characters = block
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retrive individula character by type
|
51
|
+
#
|
52
|
+
# @param [String] type
|
53
|
+
# the character type
|
54
|
+
#
|
55
|
+
# @return [String]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def [](type)
|
59
|
+
self.class.characters.call[type] || ''
|
60
|
+
end
|
61
|
+
|
37
62
|
# A line spanning all columns marking top of a table.
|
38
63
|
#
|
39
64
|
# @return [String]
|
40
65
|
#
|
41
66
|
# @api private
|
42
67
|
def top_line
|
43
|
-
render :
|
68
|
+
(result = render(:top)).empty? ? nil : result
|
44
69
|
end
|
45
70
|
|
46
71
|
# A line spanning all columns delemeting rows in a table.
|
@@ -49,7 +74,7 @@ module TTY
|
|
49
74
|
#
|
50
75
|
# @api private
|
51
76
|
def separator
|
52
|
-
render :
|
77
|
+
(result = render(:mid)).empty? ? nil : result
|
53
78
|
end
|
54
79
|
|
55
80
|
# A line spanning all columns delemeting cells in a row.
|
@@ -58,7 +83,8 @@ module TTY
|
|
58
83
|
#
|
59
84
|
# @api private
|
60
85
|
def row_line
|
61
|
-
self['left'] + row.join(self['right']) + self['right']
|
86
|
+
result = self['left'] + row.join(self['right']) + self['right']
|
87
|
+
result.empty? ? nil : result
|
62
88
|
end
|
63
89
|
|
64
90
|
# A line spannig all columns marking bottom of a table.
|
@@ -67,7 +93,7 @@ module TTY
|
|
67
93
|
#
|
68
94
|
# @api private
|
69
95
|
def bottom_line
|
70
|
-
render :
|
96
|
+
(result = render(:bottom)).empty? ? nil : result
|
71
97
|
end
|
72
98
|
|
73
99
|
protected
|
@@ -7,32 +7,23 @@ module TTY
|
|
7
7
|
# A class that represents an ascii border.
|
8
8
|
class ASCII < Border
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
10
|
+
def_border do
|
11
|
+
{
|
12
|
+
'top' => '-',
|
13
|
+
'top_mid' => '+',
|
14
|
+
'top_left' => '+',
|
15
|
+
'top_right' => '+',
|
16
|
+
'bottom' => '-',
|
17
|
+
'bottom_mid' => '+',
|
18
|
+
'bottom_left' => '+',
|
19
|
+
'bottom_right' => '+',
|
20
|
+
'mid' => '-',
|
21
|
+
'mid_mid' => '+',
|
22
|
+
'mid_left' => '+',
|
23
|
+
'mid_right' => '+',
|
24
|
+
'left' => '|',
|
25
|
+
'right' => '|'
|
25
26
|
}
|
26
|
-
|
27
|
-
# @api private
|
28
|
-
def [](type)
|
29
|
-
BORDER_TYPE[type]
|
30
|
-
end
|
31
|
-
|
32
|
-
# @api private
|
33
|
-
def initialize(row)
|
34
|
-
@row = row
|
35
|
-
@widths = row.map { |cell| cell.chars.to_a.size }
|
36
27
|
end
|
37
28
|
|
38
29
|
end # ASCII
|
@@ -7,32 +7,23 @@ module TTY
|
|
7
7
|
# A class that represents a unicode border.
|
8
8
|
class Unicode < Border
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
10
|
+
def_border do
|
11
|
+
{
|
12
|
+
'top' => '─',
|
13
|
+
'top_mid' => '┬',
|
14
|
+
'top_left' => '┌',
|
15
|
+
'top_right' => '┐',
|
16
|
+
'bottom' => '─',
|
17
|
+
'bottom_mid' => '┴',
|
18
|
+
'bottom_left' => '└',
|
19
|
+
'bottom_right' => '┘',
|
20
|
+
'mid' => '─',
|
21
|
+
'mid_mid' => '┼',
|
22
|
+
'mid_left' => '├',
|
23
|
+
'mid_right' => '┤',
|
24
|
+
'left' => '│',
|
25
|
+
'right' => '│'
|
25
26
|
}
|
26
|
-
|
27
|
-
# @api private
|
28
|
-
def [](type)
|
29
|
-
BORDER_TYPE[type]
|
30
|
-
end
|
31
|
-
|
32
|
-
# @api private
|
33
|
-
def initialize(row)
|
34
|
-
@row = row
|
35
|
-
@widths = row.map { |cell| cell.chars.to_a.size }
|
36
27
|
end
|
37
28
|
|
38
29
|
end # Unicode
|
data/lib/tty/table/column_set.rb
CHANGED
data/lib/tty/table/error.rb
CHANGED
@@ -6,5 +6,15 @@ module TTY
|
|
6
6
|
# Raised when inserting into table with a mismatching row(s)
|
7
7
|
class DimensionMismatchError < ArgumentError; end
|
8
8
|
|
9
|
+
# Raised when reading non-existent element from a table
|
10
|
+
class TupleMissing < IndexError
|
11
|
+
attr_reader :i, :j
|
12
|
+
|
13
|
+
def initialize(i, j)
|
14
|
+
@i, @j = i, j
|
15
|
+
super("element at(#{i},#{j}) not found")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
9
19
|
end # Table
|
10
20
|
end # TTY
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Table
|
5
|
+
|
6
|
+
# A class representing table orientation
|
7
|
+
class Orientation
|
8
|
+
|
9
|
+
# The name for the orientation
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
# Initialize an Orientation
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
def initialize(name)
|
18
|
+
@name = name
|
19
|
+
end
|
20
|
+
|
21
|
+
# Coerce the name argument into an orientation
|
22
|
+
#
|
23
|
+
# @param [Symbol] name
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def self.coerce(name)
|
27
|
+
case name.to_s
|
28
|
+
when /h|horiz(ontal)?/i
|
29
|
+
Horizontal.new :horizontal
|
30
|
+
when /v|ert(ical)?/i
|
31
|
+
Vertical.new :vertical
|
32
|
+
else
|
33
|
+
raise InvalidOrientationError, "orientation must be one of :horizontal, :vertical"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Check if orientation is vertical
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def vertical?
|
43
|
+
name == :vertical
|
44
|
+
end
|
45
|
+
|
46
|
+
# Check if orientation is horizontal
|
47
|
+
#
|
48
|
+
# @return [Boolean]
|
49
|
+
#
|
50
|
+
# @api public
|
51
|
+
def horizontal?
|
52
|
+
name == :horizontal
|
53
|
+
end
|
54
|
+
|
55
|
+
end # Orientation
|
56
|
+
end # Table
|
57
|
+
end # TTY
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Table
|
5
|
+
|
6
|
+
# A class representing table orientation
|
7
|
+
class Orientation
|
8
|
+
|
9
|
+
class Horizontal < Orientation
|
10
|
+
|
11
|
+
def transform(table)
|
12
|
+
table.rotate_horizontal
|
13
|
+
end
|
14
|
+
|
15
|
+
end # Horizontal
|
16
|
+
|
17
|
+
end # Orientation
|
18
|
+
end # Table
|
19
|
+
end # TTY
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Table
|
5
|
+
|
6
|
+
# A class representing table orientation
|
7
|
+
class Orientation
|
8
|
+
|
9
|
+
class Vertical < Orientation
|
10
|
+
|
11
|
+
def transform(table)
|
12
|
+
table.rotate_vertical
|
13
|
+
end
|
14
|
+
|
15
|
+
end # Vertical
|
16
|
+
|
17
|
+
end # Orientation
|
18
|
+
end # Table
|
19
|
+
end # TTY
|
data/lib/tty/table/renderer.rb
CHANGED
@@ -80,6 +80,13 @@ module TTY
|
|
80
80
|
@renderer = renderer
|
81
81
|
end
|
82
82
|
|
83
|
+
# Add custom border for the renderer
|
84
|
+
#
|
85
|
+
# @api public
|
86
|
+
def renders_with(klass)
|
87
|
+
@border_class = klass
|
88
|
+
end
|
89
|
+
|
83
90
|
delegatable_method :renderer, *RENDERER_DELEGATED_METHODS
|
84
91
|
|
85
92
|
end # Renderer
|
@@ -87,7 +87,7 @@ module TTY
|
|
87
87
|
# @api public
|
88
88
|
def render(table, border_class=Border::Null)
|
89
89
|
@table = table
|
90
|
-
@border_class = border_class
|
90
|
+
@border_class = table.border_class || border_class
|
91
91
|
|
92
92
|
return if table.to_a.empty?
|
93
93
|
# setup(options)
|
@@ -113,7 +113,7 @@ module TTY
|
|
113
113
|
# @api private
|
114
114
|
def render_header
|
115
115
|
header = table.header
|
116
|
-
if header
|
116
|
+
if header && !header.empty?
|
117
117
|
aligned = alignments.align_header header,
|
118
118
|
:column_widths => column_widths
|
119
119
|
border = border_class.new(aligned)
|
@@ -29,6 +29,26 @@ module TTY
|
|
29
29
|
def assert_string_values(rows)
|
30
30
|
end
|
31
31
|
|
32
|
+
# Check if options are of required type
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
def validate_options!(options)
|
36
|
+
if (header = options[:header]) &&
|
37
|
+
(!header.kind_of?(Array) || header.empty?)
|
38
|
+
raise InvalidArgument, ":header must be a non-empty array"
|
39
|
+
end
|
40
|
+
|
41
|
+
if (rows = options[:rows]) &&
|
42
|
+
!(rows.kind_of?(Array) || rows.kind_of?(Hash))
|
43
|
+
raise InvalidArgument, ":rows must be a non-empty array or hash"
|
44
|
+
end
|
45
|
+
|
46
|
+
if (column_widths = options[:column_widths]) &&
|
47
|
+
(!column_widths.kind_of?(Array) || column_widths.empty?)
|
48
|
+
raise InvalidArgument, ":column_widths must be a non-empty array"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
32
52
|
end # Validatable
|
33
53
|
end # Table
|
34
54
|
end # TTY
|
data/lib/tty/terminal.rb
CHANGED
@@ -28,6 +28,7 @@ module TTY
|
|
28
28
|
|
29
29
|
def initialize
|
30
30
|
@color = TTY::Terminal::Color.new(self.color?)
|
31
|
+
@echo = TTY::Terminal::Echo.new
|
31
32
|
@default_width = 80
|
32
33
|
@default_height = 24
|
33
34
|
end
|
@@ -148,26 +149,26 @@ module TTY
|
|
148
149
|
%x{tput colors 2>/dev/null}.to_i > 2
|
149
150
|
end
|
150
151
|
|
152
|
+
def echo_on
|
153
|
+
@echo.on
|
154
|
+
end
|
155
|
+
|
156
|
+
def echo_off
|
157
|
+
@echo.off
|
158
|
+
end
|
159
|
+
|
160
|
+
# @api public
|
161
|
+
def echo(is_on=true, &block)
|
162
|
+
@echo.echo(is_on, &block)
|
163
|
+
end
|
164
|
+
|
151
165
|
# Find user home directory
|
152
166
|
#
|
153
167
|
# @return [String]
|
154
168
|
#
|
155
169
|
# @api public
|
156
170
|
def home
|
157
|
-
@home ||=
|
158
|
-
env_home
|
159
|
-
else
|
160
|
-
begin
|
161
|
-
require 'etc'
|
162
|
-
File.expand_path("~#{Etc.getlogin}")
|
163
|
-
rescue
|
164
|
-
if TTY::System.windows?
|
165
|
-
"C:/"
|
166
|
-
else
|
167
|
-
"/"
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
+
@home ||= Home.new.home
|
171
172
|
end
|
172
173
|
|
173
174
|
end # Terminal
|