-
Notifications
You must be signed in to change notification settings - Fork 0
/
choose.rb
59 lines (54 loc) · 1.85 KB
/
choose.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
require 'clin'
# Handle a choose question
class Clin::ShellInteraction::Choose < Clin::ShellInteraction
def run(statement, choices, default: nil, allow_initials: false)
choices = convert_choices(choices)
question = prepare_question(statement, choices, default: default, initials: allow_initials)
loop do
answer = @shell.ask(question, default: default)
unless answer.nil?
choices.each do |choice, _|
if choice.casecmp(answer) == 0 || (allow_initials && choice[0].casecmp(answer[0]) == 0)
return choice
end
end
end
print_choices_help(choices, allow_initials: allow_initials)
end
end
protected def choice_message(choices, default: nil, initials: false)
choices = choices.keys.map { |x| x == default ? x.to_s.upcase : x }
msg = if initials
choices.map { |x| x[0] }.join('')
else
choices.join(',')
end
"[#{msg}]"
end
protected def prepare_question(statement, choices, default: nil, initials: false)
"#{statement} #{choice_message(choices, default: default, initials: initials)}"
end
# Convert the choices to a hash with key being the choice and value the description
protected def convert_choices(choices)
if choices.is_a? Array
Hash[*choices.map { |k| [k, ''] }.flatten]
elsif choices.is_a? Hash
choices
end
end
protected def print_choices_help(choices, allow_initials: false)
puts 'Choose from:'
used_initials = Set.new
choices.each do |choice, description|
suf = choice.to_s
suf += ", #{description}" unless description.blank?
line = if allow_initials && !used_initials.include?(choice[0])
used_initials << choice[0]
" #{choice[0]} - #{suf}"
else
" #{suf}"
end
puts line
end
end
end