class TTY::Prompt::EnumList
A class reponsible for rendering enumerated list menu. Used by {Prompt} to display static choice menu.
@api private
Constants
- INTEGER_MATCHER
Checks type of default parameter to be integer
- PAGE_HELP
Public Class Methods
Create instance of EnumList menu.
@api public
# File lib/tty/prompt/enum_list.rb, line 23 def initialize(prompt, **options) @prompt = prompt @prefix = options.fetch(:prefix) { @prompt.prefix } @enum = options.fetch(:enum) { ")" } @default = options.fetch(:default, nil) @active_color = options.fetch(:active_color) { @prompt.active_color } @help_color = options.fetch(:help_color) { @prompt.help_color } @error_color = options.fetch(:error_color) { @prompt.error_color } @cycle = options.fetch(:cycle, false) @quiet = options.fetch(:quiet) { @prompt.quiet } @symbols = @prompt.symbols.merge(options.fetch(:symbols, {})) @input = nil @done = false @first_render = true @failure = false @active = @default @choices = Choices.new @per_page = options[:per_page] @page_help = options[:page_help] || PAGE_HELP @paginator = BlockPaginator.new @page_active = @default end
Public Instance Methods
Call the list menu by passing question and choices
@param [String] question
@param @api public
# File lib/tty/prompt/enum_list.rb, line 146 def call(question, possibilities, &block) choices(possibilities) @question = question block[self] if block setup_defaults @prompt.subscribe(self) do render end end
Add a single choice
@api public
# File lib/tty/prompt/enum_list.rb, line 118 def choice(*value, &block) if block @choices << (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/enum_list.rb, line 132 def choices(values = (not_set = true)) if not_set @choices else values.each { |val| @choices << val } end end
Set default option selected
@api public
# File lib/tty/prompt/enum_list.rb, line 61 def default(default) @default = default end
Check if default value is set
@return [Boolean]
@api public
# File lib/tty/prompt/enum_list.rb, line 70 def default? !@default.to_s.empty? end
Set selecting active index using number pad
@api public
# File lib/tty/prompt/enum_list.rb, line 104 def enum(value) @enum = value end
# File lib/tty/prompt/enum_list.rb, line 192 def keyleft(*) if (@page_active - page_size) >= 0 @page_active -= page_size elsif @cycle @page_active = @choices.size - 1 end end
# File lib/tty/prompt/enum_list.rb, line 156 def keypress(event) if %i[backspace delete].include?(event.key.name) return if @input.empty? @input.chop! mark_choice_as_active elsif event.value =~ /^\d+$/ @input += event.value mark_choice_as_active end end
# File lib/tty/prompt/enum_list.rb, line 168 def keyreturn(*) @failure = false num = @input.to_i choice_disabled = choices[num - 1] && choices[num - 1].disabled? choice_in_range = num > 0 && num <= @choices.size if choice_in_range && !choice_disabled || @input.empty? @done = true else @input = "" @failure = true end end
# File lib/tty/prompt/enum_list.rb, line 183 def keyright(*) if (@page_active + page_size) <= @choices.size @page_active += page_size elsif @cycle @page_active = 1 end end
@param [String] text
the help text to display per page
@api pbulic
# File lib/tty/prompt/enum_list.rb, line 97 def page_help(text) @page_help = text end
# File lib/tty/prompt/enum_list.rb, line 81 def page_size (@per_page || Paginator::DEFAULT_PAGE_SIZE) end
Check if list is paginated
@return [Boolean]
@api private
# File lib/tty/prompt/enum_list.rb, line 90 def paginated? @choices.size > page_size end
Set number of items per page
@api public
# File lib/tty/prompt/enum_list.rb, line 77 def per_page(value) @per_page = value end
Set quiet mode
@api public
# File lib/tty/prompt/enum_list.rb, line 111 def quiet(value) @quiet = value end
Change symbols used by this prompt
@param [Hash] new_symbols
the new symbols to use
@api public
# File lib/tty/prompt/enum_list.rb, line 52 def symbols(new_symbols = (not_set = true)) return @symbols if not_set @symbols.merge!(new_symbols) end
Private Instance Methods
Find value for the choice selected
@return [nil, Object]
@api private
# File lib/tty/prompt/enum_list.rb, line 306 def answer @choices[@active - 1].value end
Error message when incorrect index chosen
@api private
# File lib/tty/prompt/enum_list.rb, line 340 def error_message error = "Please enter a valid number" "\n" + @prompt.decorate(">>", @error_color) + " " + error end
Find active choice or set to default
@return [nil]
@api private
# File lib/tty/prompt/enum_list.rb, line 207 def mark_choice_as_active next_active = @choices[@input.to_i - 1] if next_active && next_active.disabled? # noop elsif (@input.to_i > 0) && next_active @active = @input.to_i else @active = @default end @page_active = @active end
Pagination help message
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 386 def page_help_message return "" unless paginated? "\n" + @prompt.decorate(@page_help, @help_color) end
Count how many screen lines the question spans
@return [Integer]
@api private
# File lib/tty/prompt/enum_list.rb, line 295 def question_lines_count(question_lines) question_lines.reduce(0) do |acc, line| acc + @prompt.count_screen_lines(line) end end
Determine area of the screen to clear
@param [Integer] lines
the lines to clear
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 318 def refresh(lines) @prompt.clear_lines(lines) + @prompt.cursor.clear_screen_down end
Render a selection list.
By default the result is printed out.
@return [Object] value
return the selected value
@api private
# File lib/tty/prompt/enum_list.rb, line 273 def render @input = "" until @done question = render_question @prompt.print(question) @prompt.print(render_error) if @failure if paginated? && !@done @prompt.print(render_page_help) end @prompt.read_keypress question_lines = question.split($INPUT_RECORD_SEPARATOR, -1) @prompt.print(refresh(question_lines_count(question_lines))) end @prompt.print(render_question) unless @quiet answer end
Render error message and return cursor to position of input
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 350 def render_error error = error_message.dup if !paginated? error << @prompt.cursor.prev_line error << @prompt.cursor.forward(render_footer.size) end error end
Render chosen option
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 364 def render_header return "" unless @done return "" unless @active selected_item = @choices[@active - 1].name.to_s @prompt.decorate(selected_item, @active_color) end
Render page help
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 397 def render_page_help help = page_help_message.dup if @failure help << @prompt.cursor.prev_line end help << @prompt.cursor.prev_line help << @prompt.cursor.forward(render_footer.size) end
Render question with the menu options
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 328 def render_question header = ["#{@prefix}#{@question} #{render_header}\n"] unless @done header << render_menu header << render_footer end header.join end
Setup default option and active selection
@api private
# File lib/tty/prompt/enum_list.rb, line 254 def setup_defaults if @default.to_s.empty? @default = (0..choices.length).find { |i| !choices[i].disabled? } + 1 end validate_defaults if default_choice = choices.find_by(:name, @default) @default = choices.index(default_choice) + 1 end mark_choice_as_active end
Validate default choice name
@return [String]
@api private
# File lib/tty/prompt/enum_list.rb, line 242 def validate_default_name default_choice = choices.find_by(:name, @default.to_s) if default_choice.nil? "no choice found for the default name: #{@default.inspect}" elsif default_choice.disabled? "default name #{@default.inspect} matches disabled choice" end end
Validate default indexes to be within range
@api private
# File lib/tty/prompt/enum_list.rb, line 223 def validate_defaults msg = if @default.nil? || @default.to_s.empty? "default index must be an integer in range (1 - #{choices.size})" elsif @default.to_s !~ INTEGER_MATCHER validate_default_name elsif @default < 1 || @default > @choices.size "default index #{@default} out of range (1 - #{@choices.size})" elsif choices[@default - 1] && choices[@default - 1].disabled? "default index #{@default} matches disabled choice item" end raise(ConfigurationError, msg) if msg end