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