class TTY::Prompt::Expander
A class responsible for rendering expanding options Used by {Prompt} to display key options question.
@api private
Constants
- HELP_CHOICE
Public Class Methods
Create instance of Expander
@api public
# File lib/tty/prompt/expander.rb, line 21 def initialize(prompt, options = {}) @prompt = prompt @prefix = options.fetch(:prefix) { @prompt.prefix } @default = options.fetch(:default) { 1 } @active_color = options.fetch(:active_color) { @prompt.active_color } @help_color = options.fetch(:help_color) { @prompt.help_color } @choices = Choices.new @selected = nil @done = false @status = :collapsed @hint = nil @default_key = false @prompt.subscribe(self) end
Public Instance Methods
Execute this prompt
@api public
# File lib/tty/prompt/expander.rb, line 129 def call(message, possibilities, &block) choices(possibilities) @message = message block.call(self) if block setup_defaults choice(HELP_CHOICE) render end
Add a single choice
@api public
# File lib/tty/prompt/expander.rb, line 108 def choice(value, &block) if block @choices << value.update(value: block) else @choices << value end end
Add multiple choices
@param [Array] values
the values to add as choices
@api public
# File lib/tty/prompt/expander.rb, line 122 def choices(values) values.each { |val| choice(val) } end
# File lib/tty/prompt/expander.rb, line 41 def collapsed? @status == :collapsed end
Set default value.
@api public
# File lib/tty/prompt/expander.rb, line 100 def default(value = (not_set = true)) return @default if not_set @default = value end
# File lib/tty/prompt/expander.rb, line 45 def expand @status = :expanded end
# File lib/tty/prompt/expander.rb, line 37 def expanded? @status == :expanded end
Respond to submit event
@api public
# File lib/tty/prompt/expander.rb, line 52 def keyenter(_) if @input.nil? || @input.empty? @input = @choices[@default - 1].key @default_key = true end selected = select_choice(@input) if selected && selected.key.to_s == 'h' expand @selected = nil @input = '' elsif selected @done = true @selected = selected else @input = '' end end
Respond to key press event
@api public
# File lib/tty/prompt/expander.rb, line 76 def keypress(event) if [:backspace, :delete].include?(event.key.name) @input.chop! unless @input.empty? elsif event.value =~ /^[^\e\n\r]/ @input += event.value end @selected = select_choice(@input) if @selected && !@default_key && collapsed? @hint = @selected.name end end
Select choice by given key
@return [Choice]
@api private
# File lib/tty/prompt/expander.rb, line 93 def select_choice(key) @choices.find_by(:key, key) end
Private Instance Methods
@api private
# File lib/tty/prompt/expander.rb, line 171 def answer @selected.value end
Create possible keys with current choice highlighted
@return [String]
@api private
# File lib/tty/prompt/expander.rb, line 145 def possible_keys keys = @choices.pluck(:key) default_key = keys[@default - 1] if @selected index = keys.index(@selected.key) keys[index] = @prompt.decorate(keys[index], @active_color) elsif @input.to_s.empty? && default_key keys[@default - 1] = @prompt.decorate(default_key, @active_color) end keys.join(',') end
# File lib/tty/prompt/expander.rb, line 227 def read_input @prompt.read_keypress end
Refresh the current input
@param [Integer] lines
@return [String]
@api private
# File lib/tty/prompt/expander.rb, line 238 def refresh(lines) if @hint && (!@selected || @done) @hint = nil @prompt.clear_lines(lines, :down) + @prompt.cursor.prev_line elsif expanded? @prompt.clear_lines(lines) else @prompt.clear_line end end
@api private
# File lib/tty/prompt/expander.rb, line 158 def render @input = '' until @done question = render_question @prompt.print(question) read_input @prompt.print(refresh(question.lines.count)) end @prompt.print(render_question) answer end
Render message with options
@return [String]
@api private
# File lib/tty/prompt/expander.rb, line 180 def render_header header = "#{@prefix}#{@message} " if @done selected_item = "#{@selected.name}" header << @prompt.decorate(selected_item, @active_color) elsif collapsed? header << %[(enter "h" for help) ] header << "[#{possible_keys}] " header << @input end header end
Show hint for selected option key
return [String]
@api private
# File lib/tty/prompt/expander.rb, line 198 def render_hint hint = "\n" hint << @prompt.decorate('>> ', @active_color) hint << @hint hint << @prompt.cursor.prev_line hint << @prompt.cursor.forward(@prompt.strip(render_header).size) end
Render question with menu
@return [String]
@api private
# File lib/tty/prompt/expander.rb, line 211 def render_question header = render_header header << render_hint if @hint header << "\n" if @done if !@done && expanded? header << render_menu header << render_footer end header end
# File lib/tty/prompt/expander.rb, line 265 def setup_defaults validate_choices end
# File lib/tty/prompt/expander.rb, line 269 def validate_choices errors = [] keys = [] @choices.each do |choice| if choice.key.nil? errors << "Choice #{choice.name} is missing a :key attribute" next end if choice.key.length != 1 errors << "Choice key `#{choice.key}` is more than one character long." end if choice.key.to_s == 'h' errors << "Choice key `#{choice.key}` is reserved for help menu." end if keys.include?(choice.key) errors << "Choice key `#{choice.key}` is a duplicate." end keys << choice.key if choice.key end errors.each { |err| fail ConfigurationError, err } end