tty-prompt 0.19.0 → 0.23.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +81 -0
- data/LICENSE.txt +1 -1
- data/README.md +485 -233
- data/lib/tty-prompt.rb +1 -2
- data/lib/tty/prompt.rb +159 -147
- data/lib/tty/prompt/answers_collector.rb +5 -5
- data/lib/tty/prompt/block_paginator.rb +1 -1
- data/lib/tty/prompt/choice.rb +31 -13
- data/lib/tty/prompt/choices.rb +30 -12
- data/lib/tty/prompt/confirm_question.rb +42 -16
- data/lib/tty/prompt/const.rb +17 -0
- data/lib/tty/prompt/converter_dsl.rb +6 -7
- data/lib/tty/prompt/converter_registry.rb +31 -26
- data/lib/tty/prompt/converters.rb +139 -32
- data/lib/tty/prompt/enum_list.rb +58 -25
- data/lib/tty/prompt/errors.rb +31 -0
- data/lib/tty/prompt/evaluator.rb +2 -2
- data/lib/tty/prompt/expander.rb +27 -15
- data/lib/tty/prompt/keypress.rb +5 -3
- data/lib/tty/prompt/list.rb +101 -38
- data/lib/tty/prompt/mask_question.rb +9 -5
- data/lib/tty/prompt/multi_list.rb +108 -29
- data/lib/tty/prompt/multiline.rb +9 -7
- data/lib/tty/prompt/paginator.rb +1 -1
- data/lib/tty/prompt/question.rb +67 -36
- data/lib/tty/prompt/question/checks.rb +20 -2
- data/lib/tty/prompt/question/modifier.rb +4 -2
- data/lib/tty/prompt/question/validation.rb +3 -3
- data/lib/tty/prompt/selected_choices.rb +77 -0
- data/lib/tty/prompt/slider.rb +110 -23
- data/lib/tty/prompt/statement.rb +3 -3
- data/lib/tty/prompt/suggestion.rb +7 -6
- data/lib/tty/prompt/symbols.rb +58 -58
- data/lib/tty/prompt/test.rb +36 -0
- data/lib/tty/prompt/utils.rb +1 -3
- data/lib/tty/prompt/version.rb +1 -1
- metadata +27 -196
- data/Rakefile +0 -8
- data/examples/ask.rb +0 -7
- data/examples/ask_blank.rb +0 -9
- data/examples/ask_valid.rb +0 -12
- data/examples/collect.rb +0 -21
- data/examples/echo.rb +0 -11
- data/examples/enum_select.rb +0 -7
- data/examples/enum_select_disabled.rb +0 -16
- data/examples/enum_select_paged.rb +0 -9
- data/examples/enum_select_wrapped.rb +0 -15
- data/examples/expand.rb +0 -29
- data/examples/expand_auto.rb +0 -29
- data/examples/in.rb +0 -9
- data/examples/inputs.rb +0 -10
- data/examples/key_events.rb +0 -15
- data/examples/keypress.rb +0 -9
- data/examples/mask.rb +0 -13
- data/examples/multi_select.rb +0 -8
- data/examples/multi_select_disabled.rb +0 -17
- data/examples/multi_select_disabled_paged.rb +0 -22
- data/examples/multi_select_paged.rb +0 -9
- data/examples/multi_select_wrapped.rb +0 -15
- data/examples/multiline.rb +0 -9
- data/examples/pause.rb +0 -9
- data/examples/select.rb +0 -24
- data/examples/select_disabled.rb +0 -18
- data/examples/select_disabled_paged.rb +0 -22
- data/examples/select_enum.rb +0 -8
- data/examples/select_filtered.rb +0 -11
- data/examples/select_paginated.rb +0 -11
- data/examples/select_wrapped.rb +0 -15
- data/examples/slider.rb +0 -6
- data/examples/validation.rb +0 -9
- data/examples/yes_no.rb +0 -7
- data/lib/tty/prompt/messages.rb +0 -49
- data/lib/tty/test_prompt.rb +0 -20
- data/spec/spec_helper.rb +0 -61
- data/spec/unit/ask_spec.rb +0 -173
- data/spec/unit/block_paginator_spec.rb +0 -84
- data/spec/unit/choice/eql_spec.rb +0 -22
- data/spec/unit/choice/from_spec.rb +0 -112
- data/spec/unit/choices/add_spec.rb +0 -12
- data/spec/unit/choices/each_spec.rb +0 -13
- data/spec/unit/choices/find_by_spec.rb +0 -10
- data/spec/unit/choices/new_spec.rb +0 -10
- data/spec/unit/choices/pluck_spec.rb +0 -9
- data/spec/unit/collect_spec.rb +0 -96
- data/spec/unit/converters/convert_bool_spec.rb +0 -58
- data/spec/unit/converters/convert_char_spec.rb +0 -11
- data/spec/unit/converters/convert_custom_spec.rb +0 -14
- data/spec/unit/converters/convert_date_spec.rb +0 -34
- data/spec/unit/converters/convert_file_spec.rb +0 -18
- data/spec/unit/converters/convert_number_spec.rb +0 -39
- data/spec/unit/converters/convert_path_spec.rb +0 -15
- data/spec/unit/converters/convert_range_spec.rb +0 -22
- data/spec/unit/converters/convert_regex_spec.rb +0 -12
- data/spec/unit/converters/convert_string_spec.rb +0 -21
- data/spec/unit/converters/on_error_spec.rb +0 -9
- data/spec/unit/distance/distance_spec.rb +0 -73
- data/spec/unit/enum_select_spec.rb +0 -518
- data/spec/unit/error_spec.rb +0 -20
- data/spec/unit/evaluator_spec.rb +0 -67
- data/spec/unit/expand_spec.rb +0 -290
- data/spec/unit/keypress_spec.rb +0 -66
- data/spec/unit/mask_spec.rb +0 -140
- data/spec/unit/multi_select_spec.rb +0 -741
- data/spec/unit/multiline_spec.rb +0 -77
- data/spec/unit/new_spec.rb +0 -20
- data/spec/unit/ok_spec.rb +0 -10
- data/spec/unit/paginator_spec.rb +0 -92
- data/spec/unit/question/checks_spec.rb +0 -97
- data/spec/unit/question/default_spec.rb +0 -31
- data/spec/unit/question/echo_spec.rb +0 -38
- data/spec/unit/question/in_spec.rb +0 -115
- data/spec/unit/question/initialize_spec.rb +0 -12
- data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
- data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
- data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
- data/spec/unit/question/modify_spec.rb +0 -41
- data/spec/unit/question/required_spec.rb +0 -92
- data/spec/unit/question/validate_spec.rb +0 -115
- data/spec/unit/question/validation/call_spec.rb +0 -31
- data/spec/unit/question/validation/coerce_spec.rb +0 -30
- data/spec/unit/result_spec.rb +0 -40
- data/spec/unit/say_spec.rb +0 -67
- data/spec/unit/select_spec.rb +0 -942
- data/spec/unit/slider_spec.rb +0 -142
- data/spec/unit/statement/initialize_spec.rb +0 -15
- data/spec/unit/subscribe_spec.rb +0 -22
- data/spec/unit/suggest_spec.rb +0 -28
- data/spec/unit/timer_spec.rb +0 -29
- data/spec/unit/warn_spec.rb +0 -21
- data/spec/unit/yes_no_spec.rb +0 -251
- data/tasks/console.rake +0 -11
- data/tasks/coverage.rake +0 -11
- data/tasks/spec.rake +0 -29
- data/tty-prompt.gemspec +0 -31
@@ -1,74 +1,181 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require_relative 'converter_dsl'
|
3
|
+
require_relative "const"
|
4
|
+
require_relative "converter_dsl"
|
7
5
|
|
8
6
|
module TTY
|
9
7
|
class Prompt
|
10
8
|
module Converters
|
11
9
|
extend ConverterDSL
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
11
|
+
TRUE_VALUES = /^(t(rue)?|y(es)?|on|1)$/i.freeze
|
12
|
+
FALSE_VALUES = /^(f(alse)?|n(o)?|off|0)$/i.freeze
|
13
|
+
|
14
|
+
SINGLE_DIGIT_MATCHER = /^(?<digit>\-?\d+(\.\d+)?)$/.freeze
|
15
|
+
DIGIT_MATCHER = /^(?<open>-?\d+(\.\d+)?)
|
16
|
+
\s*(?<sep>(\.\s*){2,3}|-|,)\s*
|
17
|
+
(?<close>-?\d+(\.\d+)?)$
|
18
|
+
/x.freeze
|
19
|
+
LETTER_MATCHER = /^(?<open>\w)
|
20
|
+
\s*(?<sep>(\.\s*){2,3}|-|,)\s*
|
21
|
+
(?<close>\w)$
|
22
|
+
/x.freeze
|
23
|
+
|
24
|
+
converter(:boolean, :bool) do |input|
|
25
|
+
case input.to_s
|
26
|
+
when TRUE_VALUES then true
|
27
|
+
when FALSE_VALUES then false
|
28
|
+
else Const::Undefined
|
21
29
|
end
|
22
|
-
rescue Necromancer::ConversionTypeError => e
|
23
|
-
raise ConversionError, e.message
|
24
|
-
end
|
25
|
-
|
26
|
-
converter(:bool) do |input|
|
27
|
-
on_error { Necromancer.convert(input).to(:boolean, strict: true) }
|
28
30
|
end
|
29
31
|
|
30
|
-
converter(:string) do |input|
|
32
|
+
converter(:string, :str) do |input|
|
31
33
|
String(input).chomp
|
32
34
|
end
|
33
35
|
|
34
|
-
converter(:symbol) do |input|
|
36
|
+
converter(:symbol, :sym) do |input|
|
35
37
|
input.to_sym
|
36
38
|
end
|
37
39
|
|
40
|
+
converter(:char) do |input|
|
41
|
+
String(input).chars.to_a[0]
|
42
|
+
end
|
43
|
+
|
38
44
|
converter(:date) do |input|
|
39
|
-
|
45
|
+
begin
|
46
|
+
require "date" unless defined?(::Date)
|
47
|
+
::Date.parse(input)
|
48
|
+
rescue ArgumentError
|
49
|
+
Const::Undefined
|
50
|
+
end
|
40
51
|
end
|
41
52
|
|
42
53
|
converter(:datetime) do |input|
|
43
|
-
|
54
|
+
begin
|
55
|
+
require "date" unless defined?(::Date)
|
56
|
+
::DateTime.parse(input.to_s)
|
57
|
+
rescue ArgumentError
|
58
|
+
Const::Undefined
|
59
|
+
end
|
44
60
|
end
|
45
61
|
|
46
|
-
converter(:
|
47
|
-
|
62
|
+
converter(:time) do |input|
|
63
|
+
begin
|
64
|
+
require "time"
|
65
|
+
::Time.parse(input.to_s)
|
66
|
+
rescue ArgumentError
|
67
|
+
Const::Undefined
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
converter(:integer, :int) do |input|
|
72
|
+
begin
|
73
|
+
Integer(input)
|
74
|
+
rescue ArgumentError
|
75
|
+
Const::Undefined
|
76
|
+
end
|
48
77
|
end
|
49
78
|
|
50
79
|
converter(:float) do |input|
|
51
|
-
|
80
|
+
begin
|
81
|
+
Float(input)
|
82
|
+
rescue TypeError, ArgumentError
|
83
|
+
Const::Undefined
|
84
|
+
end
|
52
85
|
end
|
53
86
|
|
87
|
+
# Convert string number to integer or float
|
88
|
+
#
|
89
|
+
# @return [Integer,Float,Const::Undefined]
|
90
|
+
#
|
91
|
+
# @api private
|
92
|
+
def cast_to_num(num)
|
93
|
+
([convert(:int, num), convert(:float, num)] - [Const::Undefined]).first ||
|
94
|
+
Const::Undefined
|
95
|
+
end
|
96
|
+
module_function :cast_to_num
|
97
|
+
|
54
98
|
converter(:range) do |input|
|
55
|
-
|
99
|
+
if input.is_a?(::Range)
|
100
|
+
input
|
101
|
+
elsif match = input.to_s.match(SINGLE_DIGIT_MATCHER)
|
102
|
+
digit = cast_to_num(match[:digit])
|
103
|
+
::Range.new(digit, digit)
|
104
|
+
elsif match = input.to_s.match(DIGIT_MATCHER)
|
105
|
+
open = cast_to_num(match[:open])
|
106
|
+
close = cast_to_num(match[:close])
|
107
|
+
::Range.new(open, close, match[:sep].gsub(/\s*/, "") == "...")
|
108
|
+
elsif match = input.to_s.match(LETTER_MATCHER)
|
109
|
+
::Range.new(match[:open], match[:close],
|
110
|
+
match[:sep].gsub(/\s*/, "") == "...")
|
111
|
+
else Const::Undefined
|
112
|
+
end
|
56
113
|
end
|
57
114
|
|
58
115
|
converter(:regexp) do |input|
|
59
116
|
Regexp.new(input)
|
60
117
|
end
|
61
118
|
|
62
|
-
converter(:file) do |input|
|
63
|
-
::File.
|
119
|
+
converter(:filepath, :file) do |input|
|
120
|
+
::File.expand_path(input)
|
64
121
|
end
|
65
122
|
|
66
|
-
converter(:path) do |input|
|
67
|
-
|
123
|
+
converter(:pathname, :path) do |input|
|
124
|
+
require "pathname" unless defined?(::Pathname)
|
125
|
+
::Pathname.new(input)
|
68
126
|
end
|
69
127
|
|
70
|
-
converter(:
|
71
|
-
|
128
|
+
converter(:uri) do |input|
|
129
|
+
require "uri" unless defined?(::URI)
|
130
|
+
::URI.parse(input)
|
131
|
+
end
|
132
|
+
|
133
|
+
converter(:list, :array) do |val|
|
134
|
+
(val.respond_to?(:to_a) ? val : val.split(/(?<!\\),/))
|
135
|
+
.map { |v| v.strip.gsub(/\\,/, ",") }
|
136
|
+
.reject(&:empty?)
|
137
|
+
end
|
138
|
+
|
139
|
+
converter(:hash, :map) do |val|
|
140
|
+
values = val.respond_to?(:to_a) ? val : val.split(/[& ]/)
|
141
|
+
values.each_with_object({}) do |pair, pairs|
|
142
|
+
key, value = pair.split(/[=:]/, 2)
|
143
|
+
if (current = pairs[key.to_sym])
|
144
|
+
pairs[key.to_sym] = Array(current) << value
|
145
|
+
else
|
146
|
+
pairs[key.to_sym] = value
|
147
|
+
end
|
148
|
+
pairs
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
converter_registry.keys.each do |type|
|
153
|
+
next if type =~ /list|array|map|hash/
|
154
|
+
|
155
|
+
[:"#{type}_list", :"#{type}_array", :"#{type}s"].each do |new_type|
|
156
|
+
converter(new_type) do |val|
|
157
|
+
converter_registry[:array].(val).map do |obj|
|
158
|
+
converter_registry[type].(obj)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
[:"#{type}_map", :"#{type}_hash"].each do |new_type|
|
164
|
+
converter(new_type) do |val|
|
165
|
+
converter_registry[:hash].(val).each_with_object({}) do |(k, v), h|
|
166
|
+
h[k] = converter_registry[type].(v)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
[:"string_#{type}_map", :"str_#{type}_map",
|
172
|
+
:"string_#{type}_hash", :"str_#{type}_hash"].each do |new_type|
|
173
|
+
converter(new_type) do |val|
|
174
|
+
converter_registry[:hash].(val).each_with_object({}) do |(k, v), h|
|
175
|
+
h[converter_registry[:string].(k)] = converter_registry[type].(v)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
72
179
|
end
|
73
180
|
end # Converters
|
74
181
|
end # Prompt
|
data/lib/tty/prompt/enum_list.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "English"
|
4
4
|
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
5
|
+
require_relative "choices"
|
6
|
+
require_relative "block_paginator"
|
7
|
+
require_relative "paginator"
|
8
8
|
|
9
9
|
module TTY
|
10
10
|
class Prompt
|
@@ -13,7 +13,10 @@ module TTY
|
|
13
13
|
#
|
14
14
|
# @api private
|
15
15
|
class EnumList
|
16
|
-
PAGE_HELP =
|
16
|
+
PAGE_HELP = "(Press tab/right or left to reveal more choices)"
|
17
|
+
|
18
|
+
# Checks type of default parameter to be integer
|
19
|
+
INTEGER_MATCHER = /\A[-+]?\d+\Z/.freeze
|
17
20
|
|
18
21
|
# Create instance of EnumList menu.
|
19
22
|
#
|
@@ -21,12 +24,13 @@ module TTY
|
|
21
24
|
def initialize(prompt, **options)
|
22
25
|
@prompt = prompt
|
23
26
|
@prefix = options.fetch(:prefix) { @prompt.prefix }
|
24
|
-
@enum = options.fetch(:enum) {
|
25
|
-
@default = options.fetch(:default)
|
27
|
+
@enum = options.fetch(:enum) { ")" }
|
28
|
+
@default = options.fetch(:default, nil)
|
26
29
|
@active_color = options.fetch(:active_color) { @prompt.active_color }
|
27
30
|
@help_color = options.fetch(:help_color) { @prompt.help_color }
|
28
31
|
@error_color = options.fetch(:error_color) { @prompt.error_color }
|
29
|
-
@cycle = options.fetch(:cycle
|
32
|
+
@cycle = options.fetch(:cycle, false)
|
33
|
+
@quiet = options.fetch(:quiet) { @prompt.quiet }
|
30
34
|
@symbols = @prompt.symbols.merge(options.fetch(:symbols, {}))
|
31
35
|
@input = nil
|
32
36
|
@done = false
|
@@ -48,6 +52,7 @@ module TTY
|
|
48
52
|
# @api public
|
49
53
|
def symbols(new_symbols = (not_set = true))
|
50
54
|
return @symbols if not_set
|
55
|
+
|
51
56
|
@symbols.merge!(new_symbols)
|
52
57
|
end
|
53
58
|
|
@@ -64,7 +69,7 @@ module TTY
|
|
64
69
|
#
|
65
70
|
# @api public
|
66
71
|
def default?
|
67
|
-
|
72
|
+
!@default.to_s.empty?
|
68
73
|
end
|
69
74
|
|
70
75
|
# Set number of items per page
|
@@ -101,6 +106,13 @@ module TTY
|
|
101
106
|
@enum = value
|
102
107
|
end
|
103
108
|
|
109
|
+
# Set quiet mode
|
110
|
+
#
|
111
|
+
# @api public
|
112
|
+
def quiet(value)
|
113
|
+
@quiet = value
|
114
|
+
end
|
115
|
+
|
104
116
|
# Add a single choice
|
105
117
|
#
|
106
118
|
# @api public
|
@@ -145,6 +157,7 @@ module TTY
|
|
145
157
|
def keypress(event)
|
146
158
|
if %i[backspace delete].include?(event.key.name)
|
147
159
|
return if @input.empty?
|
160
|
+
|
148
161
|
@input.chop!
|
149
162
|
mark_choice_as_active
|
150
163
|
elsif event.value =~ /^\d+$/
|
@@ -162,7 +175,7 @@ module TTY
|
|
162
175
|
if choice_in_range && !choice_disabled || @input.empty?
|
163
176
|
@done = true
|
164
177
|
else
|
165
|
-
@input =
|
178
|
+
@input = ""
|
166
179
|
@failure = true
|
167
180
|
end
|
168
181
|
end
|
@@ -187,7 +200,6 @@ module TTY
|
|
187
200
|
|
188
201
|
private
|
189
202
|
|
190
|
-
|
191
203
|
# Find active choice or set to default
|
192
204
|
#
|
193
205
|
# @return [nil]
|
@@ -212,6 +224,8 @@ module TTY
|
|
212
224
|
def validate_defaults
|
213
225
|
msg = if @default.nil? || @default.to_s.empty?
|
214
226
|
"default index must be an integer in range (1 - #{choices.size})"
|
227
|
+
elsif @default.to_s !~ INTEGER_MATCHER
|
228
|
+
validate_default_name
|
215
229
|
elsif @default < 1 || @default > @choices.size
|
216
230
|
"default index #{@default} out of range (1 - #{@choices.size})"
|
217
231
|
elsif choices[@default - 1] && choices[@default - 1].disabled?
|
@@ -221,14 +235,31 @@ module TTY
|
|
221
235
|
raise(ConfigurationError, msg) if msg
|
222
236
|
end
|
223
237
|
|
238
|
+
# Validate default choice name
|
239
|
+
#
|
240
|
+
# @return [String]
|
241
|
+
#
|
242
|
+
# @api private
|
243
|
+
def validate_default_name
|
244
|
+
default_choice = choices.find_by(:name, @default.to_s)
|
245
|
+
if default_choice.nil?
|
246
|
+
"no choice found for the default name: #{@default.inspect}"
|
247
|
+
elsif default_choice.disabled?
|
248
|
+
"default name #{@default.inspect} matches disabled choice"
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
224
252
|
# Setup default option and active selection
|
225
253
|
#
|
226
254
|
# @api private
|
227
255
|
def setup_defaults
|
228
|
-
if
|
229
|
-
@default = (0..choices.length).find {|i| !choices[i].disabled? } + 1
|
256
|
+
if @default.to_s.empty?
|
257
|
+
@default = (0..choices.length).find { |i| !choices[i].disabled? } + 1
|
230
258
|
end
|
231
259
|
validate_defaults
|
260
|
+
if default_choice = choices.find_by(:name, @default)
|
261
|
+
@default = choices.index(default_choice) + 1
|
262
|
+
end
|
232
263
|
mark_choice_as_active
|
233
264
|
end
|
234
265
|
|
@@ -241,7 +272,7 @@ module TTY
|
|
241
272
|
#
|
242
273
|
# @api private
|
243
274
|
def render
|
244
|
-
@input =
|
275
|
+
@input = ""
|
245
276
|
until @done
|
246
277
|
question = render_question
|
247
278
|
@prompt.print(question)
|
@@ -253,7 +284,7 @@ module TTY
|
|
253
284
|
question_lines = question.split($INPUT_RECORD_SEPARATOR, -1)
|
254
285
|
@prompt.print(refresh(question_lines_count(question_lines)))
|
255
286
|
end
|
256
|
-
@prompt.print(render_question)
|
287
|
+
@prompt.print(render_question) unless @quiet
|
257
288
|
answer
|
258
289
|
end
|
259
290
|
|
@@ -308,8 +339,8 @@ module TTY
|
|
308
339
|
#
|
309
340
|
# @api private
|
310
341
|
def error_message
|
311
|
-
error =
|
312
|
-
"\n" + @prompt.decorate(
|
342
|
+
error = "Please enter a valid number"
|
343
|
+
"\n" + @prompt.decorate(">>", @error_color) + " " + error
|
313
344
|
end
|
314
345
|
|
315
346
|
# Render error message and return cursor to position of input
|
@@ -332,8 +363,9 @@ module TTY
|
|
332
363
|
#
|
333
364
|
# @api private
|
334
365
|
def render_header
|
335
|
-
return
|
336
|
-
return
|
366
|
+
return "" unless @done
|
367
|
+
return "" unless @active
|
368
|
+
|
337
369
|
selected_item = @choices[@active - 1].name.to_s
|
338
370
|
@prompt.decorate(selected_item, @active_color)
|
339
371
|
end
|
@@ -353,7 +385,8 @@ module TTY
|
|
353
385
|
#
|
354
386
|
# @api private
|
355
387
|
def page_help_message
|
356
|
-
return
|
388
|
+
return "" unless paginated?
|
389
|
+
|
357
390
|
"\n" + @prompt.decorate(@page_help, @help_color)
|
358
391
|
end
|
359
392
|
|
@@ -380,15 +413,15 @@ module TTY
|
|
380
413
|
output = []
|
381
414
|
|
382
415
|
@paginator.paginate(@choices, @page_active, @per_page) do |choice, index|
|
383
|
-
num = (index + 1).to_s + @enum +
|
416
|
+
num = (index + 1).to_s + @enum + " "
|
384
417
|
selected = num.to_s + choice.name.to_s
|
385
418
|
output << if index + 1 == @active && !choice.disabled?
|
386
|
-
(
|
419
|
+
(" " * 2) + @prompt.decorate(selected, @active_color)
|
387
420
|
elsif choice.disabled?
|
388
|
-
@prompt.decorate(@symbols[:cross], :red) +
|
389
|
-
selected +
|
421
|
+
@prompt.decorate(@symbols[:cross], :red) + " " +
|
422
|
+
selected + " " + choice.disabled.to_s
|
390
423
|
else
|
391
|
-
(
|
424
|
+
(" " * 2) + selected
|
392
425
|
end
|
393
426
|
output << "\n"
|
394
427
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Prompt
|
5
|
+
Error = Class.new(StandardError)
|
6
|
+
|
7
|
+
# Raised when wrong parameter is used to configure prompt
|
8
|
+
ConfigurationError = Class.new(Error)
|
9
|
+
|
10
|
+
# Raised when type conversion cannot be performed
|
11
|
+
ConversionError = Class.new(Error)
|
12
|
+
|
13
|
+
# Raised when the passed in validation argument is of wrong type
|
14
|
+
ValidationCoercion = Class.new(Error)
|
15
|
+
|
16
|
+
# Raised when the required argument is not supplied
|
17
|
+
ArgumentRequired = Class.new(Error)
|
18
|
+
|
19
|
+
# Raised when the argument validation fails
|
20
|
+
ArgumentValidation = Class.new(Error)
|
21
|
+
|
22
|
+
# Raised when the argument is not expected
|
23
|
+
InvalidArgument = Class.new(Error)
|
24
|
+
|
25
|
+
# Raised when overriding already defined conversion
|
26
|
+
ConversionAlreadyDefined = Class.new(Error)
|
27
|
+
|
28
|
+
# Raised when conversion type isn't registered
|
29
|
+
UnsupportedConversion = Class.new(Error)
|
30
|
+
end # Prompt
|
31
|
+
end # TTY
|