tty-prompt 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +30 -0
- data/README.md +39 -9
- data/examples/echo.rb +5 -1
- data/examples/inputs.rb +10 -0
- data/examples/mask.rb +6 -2
- data/examples/multi_select.rb +1 -1
- data/examples/multi_select_paged.rb +9 -0
- data/examples/select.rb +5 -5
- data/examples/slider.rb +1 -1
- data/lib/tty-prompt.rb +2 -36
- data/lib/tty/prompt.rb +49 -8
- data/lib/tty/prompt/choices.rb +2 -0
- data/lib/tty/prompt/confirm_question.rb +6 -1
- data/lib/tty/prompt/converter_dsl.rb +9 -6
- data/lib/tty/prompt/converter_registry.rb +27 -19
- data/lib/tty/prompt/converters.rb +16 -22
- data/lib/tty/prompt/enum_list.rb +8 -4
- data/lib/tty/prompt/enum_paginator.rb +2 -0
- data/lib/tty/prompt/evaluator.rb +1 -1
- data/lib/tty/prompt/expander.rb +1 -1
- data/lib/tty/prompt/list.rb +21 -11
- data/lib/tty/prompt/mask_question.rb +15 -6
- data/lib/tty/prompt/multi_list.rb +12 -10
- data/lib/tty/prompt/question.rb +38 -36
- data/lib/tty/prompt/question/modifier.rb +2 -0
- data/lib/tty/prompt/question/validation.rb +5 -4
- data/lib/tty/prompt/reader.rb +104 -58
- data/lib/tty/prompt/reader/codes.rb +103 -63
- data/lib/tty/prompt/reader/console.rb +57 -0
- data/lib/tty/prompt/reader/key_event.rb +51 -88
- data/lib/tty/prompt/reader/mode.rb +5 -5
- data/lib/tty/prompt/reader/win_api.rb +29 -0
- data/lib/tty/prompt/reader/win_console.rb +49 -0
- data/lib/tty/prompt/slider.rb +10 -6
- data/lib/tty/prompt/suggestion.rb +1 -1
- data/lib/tty/prompt/symbols.rb +52 -10
- data/lib/tty/prompt/version.rb +1 -1
- data/lib/tty/{prompt/test.rb → test_prompt.rb} +2 -1
- data/spec/unit/ask_spec.rb +8 -16
- data/spec/unit/converters/convert_bool_spec.rb +1 -2
- data/spec/unit/converters/on_error_spec.rb +9 -0
- data/spec/unit/enum_paginator_spec.rb +16 -0
- data/spec/unit/enum_select_spec.rb +69 -25
- data/spec/unit/expand_spec.rb +14 -14
- data/spec/unit/mask_spec.rb +66 -29
- data/spec/unit/multi_select_spec.rb +120 -74
- data/spec/unit/new_spec.rb +5 -3
- data/spec/unit/paginator_spec.rb +16 -0
- data/spec/unit/question/default_spec.rb +2 -4
- data/spec/unit/question/echo_spec.rb +2 -3
- data/spec/unit/question/in_spec.rb +9 -14
- data/spec/unit/question/modifier/letter_case_spec.rb +32 -11
- data/spec/unit/question/modifier/whitespace_spec.rb +41 -15
- data/spec/unit/question/required_spec.rb +9 -13
- data/spec/unit/question/validate_spec.rb +7 -10
- data/spec/unit/reader/key_event_spec.rb +36 -50
- data/spec/unit/reader/publish_keypress_event_spec.rb +5 -3
- data/spec/unit/reader/read_keypress_spec.rb +8 -7
- data/spec/unit/reader/read_line_spec.rb +9 -9
- data/spec/unit/reader/read_multiline_spec.rb +8 -7
- data/spec/unit/select_spec.rb +85 -25
- data/spec/unit/slider_spec.rb +43 -16
- data/spec/unit/yes_no_spec.rb +14 -28
- data/tasks/console.rake +1 -0
- data/tty-prompt.gemspec +2 -2
- metadata +14 -7
@@ -2,27 +2,34 @@
|
|
2
2
|
|
3
3
|
module TTY
|
4
4
|
class Prompt
|
5
|
+
# Immutable collection of converters for type transformation
|
6
|
+
#
|
7
|
+
# @api private
|
5
8
|
class ConverterRegistry
|
6
|
-
|
7
|
-
|
9
|
+
# Create a registry of conversions
|
10
|
+
#
|
11
|
+
# @param [Hash] registry
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
def initialize(registry = {})
|
15
|
+
@_registry = registry.dup.freeze
|
16
|
+
freeze
|
8
17
|
end
|
9
18
|
|
10
19
|
# Register converter
|
11
20
|
#
|
21
|
+
# @param [Symbol] name
|
22
|
+
# the converter name
|
23
|
+
#
|
12
24
|
# @api public
|
13
|
-
def register(
|
14
|
-
|
15
|
-
item = block
|
16
|
-
else
|
17
|
-
item = contents
|
18
|
-
end
|
25
|
+
def register(name, contents = nil, &block)
|
26
|
+
item = block_given? ? block : contents
|
19
27
|
|
20
|
-
if key?(
|
21
|
-
|
22
|
-
|
23
|
-
@_registry[key] = item
|
28
|
+
if key?(name)
|
29
|
+
raise ArgumentError,
|
30
|
+
"Converter for #{name.inspect} already registered"
|
24
31
|
end
|
25
|
-
self
|
32
|
+
self.class.new(@_registry.merge(name => item))
|
26
33
|
end
|
27
34
|
|
28
35
|
# Check if converter is registered
|
@@ -37,16 +44,17 @@ module TTY
|
|
37
44
|
# Execute converter
|
38
45
|
#
|
39
46
|
# @api public
|
40
|
-
def call(
|
41
|
-
if
|
42
|
-
converter =
|
47
|
+
def call(name, input)
|
48
|
+
if name.respond_to?(:call)
|
49
|
+
converter = name
|
43
50
|
else
|
44
|
-
converter = @_registry.fetch(
|
45
|
-
|
51
|
+
converter = @_registry.fetch(name) do
|
52
|
+
raise ArgumentError, "#{name.inspect} is not registered"
|
46
53
|
end
|
47
54
|
end
|
48
|
-
converter
|
55
|
+
converter[input]
|
49
56
|
end
|
57
|
+
alias [] call
|
50
58
|
|
51
59
|
def inspect
|
52
60
|
@_registry.inspect
|
@@ -2,30 +2,29 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'necromancer'
|
5
|
-
|
5
|
+
|
6
|
+
require_relative 'converter_dsl'
|
6
7
|
|
7
8
|
module TTY
|
8
9
|
class Prompt
|
9
10
|
module Converters
|
10
11
|
extend ConverterDSL
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Converters.converter_registry
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
13
|
+
# Delegate Necromancer errors
|
14
|
+
#
|
15
|
+
# @api private
|
20
16
|
def self.on_error
|
21
|
-
|
17
|
+
if block_given?
|
18
|
+
yield
|
19
|
+
else
|
20
|
+
raise ArgumentError, 'You need to provide a block argument.'
|
21
|
+
end
|
22
22
|
rescue Necromancer::ConversionTypeError => e
|
23
23
|
raise ConversionError, e.message
|
24
24
|
end
|
25
25
|
|
26
26
|
converter(:bool) do |input|
|
27
|
-
|
28
|
-
on_error { converter.convert(input).to(:boolean, strict: true) }
|
27
|
+
on_error { Necromancer.convert(input).to(:boolean, strict: true) }
|
29
28
|
end
|
30
29
|
|
31
30
|
converter(:string) do |input|
|
@@ -37,28 +36,23 @@ module TTY
|
|
37
36
|
end
|
38
37
|
|
39
38
|
converter(:date) do |input|
|
40
|
-
|
41
|
-
on_error { converter.convert(input).to(:date, strict: true) }
|
39
|
+
on_error { Necromancer.convert(input).to(:date, strict: true) }
|
42
40
|
end
|
43
41
|
|
44
42
|
converter(:datetime) do |input|
|
45
|
-
|
46
|
-
on_error { converter.convert(input).to(:datetime, strict: true) }
|
43
|
+
on_error { Necromancer.convert(input).to(:datetime, strict: true) }
|
47
44
|
end
|
48
45
|
|
49
46
|
converter(:int) do |input|
|
50
|
-
|
51
|
-
on_error { converter.convert(input).to(:integer, strict: true) }
|
47
|
+
on_error { Necromancer.convert(input).to(:integer, strict: true) }
|
52
48
|
end
|
53
49
|
|
54
50
|
converter(:float) do |input|
|
55
|
-
|
56
|
-
on_error { converter.convert(input).to(:float, strict: true) }
|
51
|
+
on_error { Necromancer.convert(input).to(:float, strict: true) }
|
57
52
|
end
|
58
53
|
|
59
54
|
converter(:range) do |input|
|
60
|
-
|
61
|
-
on_error { converter.convert(input).to(:range, strict: true) }
|
55
|
+
on_error { Necromancer.convert(input).to(:range, strict: true) }
|
62
56
|
end
|
63
57
|
|
64
58
|
converter(:regexp) do |input|
|
data/lib/tty/prompt/enum_list.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require_relative 'choices'
|
4
|
+
require_relative 'enum_paginator'
|
5
|
+
require_relative 'paginator'
|
6
|
+
|
3
7
|
module TTY
|
4
8
|
class Prompt
|
5
9
|
# A class reponsible for rendering enumerated list menu.
|
@@ -58,7 +62,7 @@ module TTY
|
|
58
62
|
#
|
59
63
|
# @api private
|
60
64
|
def paginated?
|
61
|
-
@choices.size
|
65
|
+
@choices.size > page_size
|
62
66
|
end
|
63
67
|
|
64
68
|
# @param [String] text
|
@@ -157,7 +161,7 @@ module TTY
|
|
157
161
|
#
|
158
162
|
# @api private
|
159
163
|
def mark_choice_as_active
|
160
|
-
if (@input.to_i >
|
164
|
+
if (@input.to_i > 0) && !@choices[@input.to_i - 1].nil?
|
161
165
|
@active = @input.to_i
|
162
166
|
else
|
163
167
|
@active = @default
|
@@ -308,8 +312,8 @@ module TTY
|
|
308
312
|
def render_menu
|
309
313
|
output = ''
|
310
314
|
@paginator.paginate(@choices, @page_active, @per_page) do |choice, index|
|
311
|
-
num = (index + 1).to_s + @enum +
|
312
|
-
selected =
|
315
|
+
num = (index + 1).to_s + @enum + ' '
|
316
|
+
selected = ' ' * 2 + num + choice.name
|
313
317
|
output << if index + 1 == @active
|
314
318
|
@prompt.decorate(selected.to_s, @active_color)
|
315
319
|
else
|
data/lib/tty/prompt/evaluator.rb
CHANGED
data/lib/tty/prompt/expander.rb
CHANGED
data/lib/tty/prompt/list.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require_relative 'choices'
|
4
|
+
require_relative 'paginator'
|
5
|
+
require_relative 'symbols'
|
6
|
+
|
3
7
|
module TTY
|
4
8
|
class Prompt
|
5
9
|
# A class responsible for rendering select list menu
|
@@ -7,6 +11,8 @@ module TTY
|
|
7
11
|
#
|
8
12
|
# @api private
|
9
13
|
class List
|
14
|
+
include Symbols
|
15
|
+
|
10
16
|
HELP = '(Use arrow%s keys, press Enter to select)'
|
11
17
|
|
12
18
|
PAGE_HELP = '(Move up or down to reveal more choices)'
|
@@ -34,7 +40,7 @@ module TTY
|
|
34
40
|
@choices = Choices.new
|
35
41
|
@active_color = options.fetch(:active_color) { @prompt.active_color }
|
36
42
|
@help_color = options.fetch(:help_color) { @prompt.help_color }
|
37
|
-
@marker = options.fetch(:marker) {
|
43
|
+
@marker = options.fetch(:marker) { symbols[:pointer] }
|
38
44
|
@help = options[:help]
|
39
45
|
@first_render = true
|
40
46
|
@done = false
|
@@ -66,13 +72,17 @@ module TTY
|
|
66
72
|
@per_page = value
|
67
73
|
end
|
68
74
|
|
75
|
+
def page_size
|
76
|
+
(@per_page || Paginator::DEFAULT_PAGE_SIZE)
|
77
|
+
end
|
78
|
+
|
69
79
|
# Check if list is paginated
|
70
80
|
#
|
71
81
|
# @return [Boolean]
|
72
82
|
#
|
73
83
|
# @api private
|
74
84
|
def paginated?
|
75
|
-
@choices.size
|
85
|
+
@choices.size > page_size
|
76
86
|
end
|
77
87
|
|
78
88
|
# @param [String] text
|
@@ -134,7 +144,7 @@ module TTY
|
|
134
144
|
def keynum(event)
|
135
145
|
return unless enumerate?
|
136
146
|
value = event.value.to_i
|
137
|
-
return unless (1..@choices.count).
|
147
|
+
return unless (1..@choices.count).cover?(value)
|
138
148
|
@active = value
|
139
149
|
end
|
140
150
|
|
@@ -171,11 +181,11 @@ module TTY
|
|
171
181
|
def validate_defaults
|
172
182
|
@default.each do |d|
|
173
183
|
if d.nil? || d.to_s.empty?
|
174
|
-
|
184
|
+
raise ConfigurationError,
|
175
185
|
"default index must be an integer in range (1 - #{@choices.size})"
|
176
186
|
end
|
177
187
|
if d < 1 || d > @choices.size
|
178
|
-
|
188
|
+
raise ConfigurationError,
|
179
189
|
"default index `#{d}` out of range (1 - #{@choices.size})"
|
180
190
|
end
|
181
191
|
end
|
@@ -197,10 +207,9 @@ module TTY
|
|
197
207
|
refresh(lines)
|
198
208
|
end
|
199
209
|
render_question
|
200
|
-
|
210
|
+
render_answer
|
201
211
|
ensure
|
202
212
|
@prompt.print(@prompt.show)
|
203
|
-
answer
|
204
213
|
end
|
205
214
|
|
206
215
|
# Find value for the choice selected
|
@@ -266,14 +275,15 @@ module TTY
|
|
266
275
|
def render_menu
|
267
276
|
output = ''
|
268
277
|
@paginator.paginate(@choices, @active, @per_page) do |choice, index|
|
269
|
-
num = enumerate? ? (index + 1).to_s + @enum +
|
278
|
+
num = enumerate? ? (index + 1).to_s + @enum + ' ' : ''
|
270
279
|
message = if index + 1 == @active
|
271
|
-
selected = @marker +
|
280
|
+
selected = @marker + ' ' + num + choice.name
|
272
281
|
@prompt.decorate("#{selected}", @active_color)
|
273
282
|
else
|
274
|
-
|
283
|
+
' ' * 2 + num + choice.name
|
275
284
|
end
|
276
|
-
|
285
|
+
max_index = paginated? ? @paginator.max_index : @choices.size - 1
|
286
|
+
newline = (index == max_index) ? '' : "\n"
|
277
287
|
output << (message + newline)
|
278
288
|
end
|
279
289
|
output
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require_relative 'question'
|
4
|
+
require_relative 'symbols'
|
5
|
+
|
3
6
|
module TTY
|
4
7
|
class Prompt
|
5
8
|
class MaskQuestion < Question
|
@@ -11,7 +14,7 @@ module TTY
|
|
11
14
|
# @api public
|
12
15
|
def initialize(prompt, options = {})
|
13
16
|
super
|
14
|
-
@mask = options.fetch(:mask) { Symbols
|
17
|
+
@mask = options.fetch(:mask) { Symbols.symbols[:dot] }
|
15
18
|
@done_masked = false
|
16
19
|
@failure = false
|
17
20
|
@prompt.subscribe(self)
|
@@ -54,15 +57,19 @@ module TTY
|
|
54
57
|
masked = "#{@mask * "#{@input}".length}"
|
55
58
|
if @done_masked && !@failure
|
56
59
|
masked = @prompt.decorate(masked, @active_color)
|
60
|
+
elsif @done_masked && @failure
|
61
|
+
masked = @prompt.decorate(masked, @error_color)
|
57
62
|
end
|
58
63
|
header += masked
|
59
64
|
end
|
60
65
|
@prompt.print(header)
|
61
|
-
@prompt.
|
66
|
+
@prompt.puts if @done
|
67
|
+
|
68
|
+
header.lines.count + (@done ? 1 : 0)
|
62
69
|
end
|
63
70
|
|
64
|
-
def
|
65
|
-
@failure =
|
71
|
+
def render_error(errors)
|
72
|
+
@failure = !errors.empty?
|
66
73
|
super
|
67
74
|
end
|
68
75
|
|
@@ -71,13 +78,15 @@ module TTY
|
|
71
78
|
# @private
|
72
79
|
def read_input
|
73
80
|
@done_masked = false
|
81
|
+
@failure = false
|
74
82
|
@input = ''
|
83
|
+
|
75
84
|
until @done_masked
|
76
|
-
@prompt.read_keypress
|
85
|
+
@prompt.read_keypress
|
77
86
|
@prompt.print(@prompt.clear_line)
|
78
87
|
render_question
|
79
88
|
end
|
80
|
-
@prompt.
|
89
|
+
@prompt.puts
|
81
90
|
@input
|
82
91
|
end
|
83
92
|
end # MaskQuestion
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'list'
|
4
4
|
|
5
5
|
module TTY
|
6
6
|
class Prompt
|
@@ -22,6 +22,7 @@ module TTY
|
|
22
22
|
@selected = []
|
23
23
|
@help = options[:help]
|
24
24
|
@default = Array(options[:default])
|
25
|
+
@echo = options.fetch(:echo, true)
|
25
26
|
end
|
26
27
|
|
27
28
|
# Callback fired when space key is pressed
|
@@ -61,9 +62,9 @@ module TTY
|
|
61
62
|
# @api private
|
62
63
|
def render_header
|
63
64
|
instructions = @prompt.decorate(help, :bright_black)
|
64
|
-
if @done
|
65
|
+
if @done && @echo
|
65
66
|
@prompt.decorate(selected_names, @active_color)
|
66
|
-
elsif @selected.size.nonzero?
|
67
|
+
elsif @selected.size.nonzero? && @echo
|
67
68
|
selected_names + (@first_render ? " #{instructions}" : '')
|
68
69
|
elsif @first_render
|
69
70
|
instructions
|
@@ -85,16 +86,17 @@ module TTY
|
|
85
86
|
def render_menu
|
86
87
|
output = ''
|
87
88
|
@paginator.paginate(@choices, @active, @per_page) do |choice, index|
|
88
|
-
num = enumerate? ? (index + 1).to_s + @enum +
|
89
|
-
indicator = (index + 1 == @active) ? @marker :
|
90
|
-
indicator +=
|
89
|
+
num = enumerate? ? (index + 1).to_s + @enum + ' ' : ''
|
90
|
+
indicator = (index + 1 == @active) ? @marker : ' '
|
91
|
+
indicator += ' '
|
91
92
|
message = if @selected.include?(choice)
|
92
|
-
selected = @prompt.decorate(
|
93
|
-
selected +
|
93
|
+
selected = @prompt.decorate(symbols[:radio_on], @active_color)
|
94
|
+
selected + ' ' + num + choice.name
|
94
95
|
else
|
95
|
-
|
96
|
+
symbols[:radio_off] + ' ' + num + choice.name
|
96
97
|
end
|
97
|
-
|
98
|
+
max_index = paginated? ? @paginator.max_index : @choices.size - 1
|
99
|
+
newline = (index == max_index) ? '' : "\n"
|
98
100
|
output << indicator + message + newline
|
99
101
|
end
|
100
102
|
output
|
data/lib/tty/prompt/question.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require_relative 'converters'
|
4
|
+
require_relative 'evaluator'
|
5
|
+
require_relative 'question/modifier'
|
6
|
+
require_relative 'question/validation'
|
7
|
+
require_relative 'question/checks'
|
8
|
+
require_relative 'utils'
|
8
9
|
|
9
10
|
module TTY
|
10
11
|
# A class responsible for shell prompt interactions.
|
@@ -14,7 +15,6 @@ module TTY
|
|
14
15
|
# @api public
|
15
16
|
class Question
|
16
17
|
include Checks
|
17
|
-
include Converters
|
18
18
|
|
19
19
|
UndefinedSetting = Module.new
|
20
20
|
|
@@ -42,6 +42,7 @@ module TTY
|
|
42
42
|
@convert = options.fetch(:convert) { UndefinedSetting }
|
43
43
|
@active_color = options.fetch(:active_color) { @prompt.active_color }
|
44
44
|
@help_color = options.fetch(:help_color) { @prompt.help_color }
|
45
|
+
@error_color = options.fetch(:error_color) { :red }
|
45
46
|
@messages = Utils.deep_copy(options.fetch(:messages) { { } })
|
46
47
|
@done = false
|
47
48
|
@input = nil
|
@@ -100,12 +101,17 @@ module TTY
|
|
100
101
|
#
|
101
102
|
# @api private
|
102
103
|
def render
|
104
|
+
@errors = []
|
103
105
|
until @done
|
104
|
-
render_question
|
106
|
+
lines = render_question
|
105
107
|
result = process_input
|
106
|
-
|
107
|
-
|
108
|
-
|
108
|
+
if result.failure?
|
109
|
+
@errors = result.errors
|
110
|
+
render_error(result.errors)
|
111
|
+
else
|
112
|
+
@done = true
|
113
|
+
end
|
114
|
+
refresh(lines)
|
109
115
|
end
|
110
116
|
render_question
|
111
117
|
convert_result(result.value)
|
@@ -124,7 +130,9 @@ module TTY
|
|
124
130
|
header += @prompt.decorate("(#{default})", @help_color) + ' '
|
125
131
|
end
|
126
132
|
@prompt.print(header)
|
127
|
-
@prompt.
|
133
|
+
@prompt.puts if @done
|
134
|
+
|
135
|
+
header.lines.count + (@done ? 1 : 0)
|
128
136
|
end
|
129
137
|
|
130
138
|
# Decide how to handle input from user
|
@@ -146,43 +154,37 @@ module TTY
|
|
146
154
|
when :keypress
|
147
155
|
@prompt.read_keypress
|
148
156
|
when :multiline
|
149
|
-
@prompt.read_multiline
|
157
|
+
@prompt.read_multiline.each(&:chomp!)
|
150
158
|
else
|
151
|
-
@prompt.read_line(echo)
|
159
|
+
@prompt.read_line(echo: echo).chomp
|
152
160
|
end
|
153
161
|
end
|
154
162
|
|
155
163
|
# Handle error condition
|
156
164
|
#
|
157
165
|
# @api private
|
158
|
-
def
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
@prompt.print(@prompt.decorate('>>', :red) + ' ' + err)
|
163
|
-
end
|
164
|
-
@prompt.print(@prompt.cursor.up(result.errors.count))
|
165
|
-
else
|
166
|
-
@done = true
|
167
|
-
if result.errors.count.nonzero?
|
168
|
-
@prompt.print(@prompt.cursor.down(result.errors.count))
|
169
|
-
end
|
166
|
+
def render_error(errors)
|
167
|
+
errors.each do |err|
|
168
|
+
newline = (@echo ? '' : "\n")
|
169
|
+
@prompt.print(newline + @prompt.decorate('>>', :red) + ' ' + err)
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
173
173
|
# Determine area of the screen to clear
|
174
174
|
#
|
175
|
-
# @param [
|
175
|
+
# @param [Array[String]] errors
|
176
176
|
#
|
177
177
|
# @api private
|
178
|
-
def refresh(
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
178
|
+
def refresh(lines)
|
179
|
+
if @done
|
180
|
+
if @errors.count.zero? && @echo
|
181
|
+
@prompt.print(@prompt.cursor.up(lines))
|
182
|
+
else
|
183
|
+
lines += @errors.count
|
184
|
+
end
|
185
|
+
else
|
186
|
+
@prompt.print(@prompt.cursor.up(lines))
|
184
187
|
end
|
185
|
-
|
186
188
|
@prompt.print(@prompt.clear_lines(lines))
|
187
189
|
end
|
188
190
|
|
@@ -193,7 +195,7 @@ module TTY
|
|
193
195
|
# @api private
|
194
196
|
def convert_result(value)
|
195
197
|
if convert? & !Utils.blank?(value)
|
196
|
-
|
198
|
+
Converters.convert(@convert, value)
|
197
199
|
else
|
198
200
|
value
|
199
201
|
end
|
@@ -303,10 +305,10 @@ module TTY
|
|
303
305
|
def in(value = (not_set = true), message = nil)
|
304
306
|
messages[:range?] = message if message
|
305
307
|
if in? && !@in.is_a?(Range)
|
306
|
-
@in =
|
308
|
+
@in = Converters.convert(:range, @in)
|
307
309
|
end
|
308
310
|
return @in if not_set
|
309
|
-
@in =
|
311
|
+
@in = Converters.convert(:range, value)
|
310
312
|
end
|
311
313
|
|
312
314
|
# Check if range is set
|