class TTY::Prompt::List

A class responsible for rendering select list menu Used by {Prompt} to display interactive menu.

@api private

Constants

HELP
PAGE_HELP

Public Class Methods

new(prompt, options = {}) click to toggle source

Create instance of TTY::Prompt::List menu.

@param Hash options

the configuration options

@option options [Symbol] :default

the default active choice, defaults to 1

@option options [Symbol] :color

the color for the selected item, defualts to :green

@option options [Symbol] :marker

the marker for the selected item

@option options [String] :enum

the delimiter for the item index

@api public

# File lib/tty/prompt/list.rb, line 34
def initialize(prompt, options = {})
  @prompt       = prompt
  @prefix       = options.fetch(:prefix) { @prompt.prefix }
  @enum         = options.fetch(:enum) { nil }
  @default      = Array[options.fetch(:default) { 1 }]
  @active       = @default.first
  @choices      = Choices.new
  @active_color = options.fetch(:active_color) { @prompt.active_color }
  @help_color   = options.fetch(:help_color) { @prompt.help_color }
  @marker       = options.fetch(:marker) { symbols[:pointer] }
  @help         = options[:help]
  @first_render = true
  @done         = false
  @per_page     = options[:per_page]
  @page_help    = options[:page_help] || PAGE_HELP
  @paginator    = Paginator.new

  @prompt.subscribe(self)
end

Public Instance Methods

call(question, possibilities, &block) click to toggle source

Call the list menu by passing question and choices

@param [String] question

@param @api public

# File lib/tty/prompt/list.rb, line 150
def call(question, possibilities, &block)
  choices(possibilities)
  @question = question
  block.call(self) if block
  setup_defaults
  render
end
choice(*value, &block) click to toggle source

Add a single choice

@api public

# File lib/tty/prompt/list.rb, line 126
def choice(*value, &block)
  if block
    @choices << (value << block)
  else
    @choices << value
  end
end
choices(values) click to toggle source

Add multiple choices

@param [Array] values

the values to add as choices

@api public

# File lib/tty/prompt/list.rb, line 140
def choices(values)
  Array(values).each { |val| choice(*val) }
end
default(*default_values) click to toggle source

Set default option selected

@api public

# File lib/tty/prompt/list.rb, line 64
def default(*default_values)
  @default = default_values
end
default_help() click to toggle source

Default help text

@api public

# File lib/tty/prompt/list.rb, line 112
def default_help
  self.class::HELP % [enumerate? ? " or number (1-#{@choices.size})" : '']
end
enum(value) click to toggle source

Set selecting active index using number pad

@api public

# File lib/tty/prompt/list.rb, line 119
def enum(value)
  @enum = value
end
enumerate?() click to toggle source

Check if list is enumerated

@return [Boolean]

# File lib/tty/prompt/list.rb, line 161
def enumerate?
  !@enum.nil?
end
help(value = (not_set = true)) click to toggle source

Provide help information

@param [String] value

the new help text

@return [String]

@api public

# File lib/tty/prompt/list.rb, line 103
def help(value = (not_set = true))
  return @help if !@help.nil? && not_set

  @help = (@help.nil? && !not_set) ? value : default_help
end
keydown(*) click to toggle source
# File lib/tty/prompt/list.rb, line 184
def keydown(*)
  @active = (@active == @choices.length) ? 1 : @active + 1
end
Also aliased as: keytab
keynum(event) click to toggle source
# File lib/tty/prompt/list.rb, line 165
def keynum(event)
  return unless enumerate?
  value = event.value.to_i
  return unless (1..@choices.count).cover?(value)
  @active = value
end
keyreturn(*) click to toggle source
# File lib/tty/prompt/list.rb, line 176
def keyreturn(*)
  @done = true
end
keyspace(*) click to toggle source
# File lib/tty/prompt/list.rb, line 172
def keyspace(*)
  @done = true
end
keytab(*)
Alias for: keydown
keyup(*) click to toggle source
# File lib/tty/prompt/list.rb, line 180
def keyup(*)
  @active = (@active == 1) ? @choices.length : @active - 1
end
marker(value) click to toggle source

Set marker

@api public

# File lib/tty/prompt/list.rb, line 57
def marker(value)
  @marker = value
end
page_help(text) click to toggle source

@param [String] text

the help text to display per page

@api pbulic

# File lib/tty/prompt/list.rb, line 91
def page_help(text)
  @page_help = text
end
page_size() click to toggle source
# File lib/tty/prompt/list.rb, line 75
def page_size
  (@per_page || Paginator::DEFAULT_PAGE_SIZE)
end
paginated?() click to toggle source

Check if list is paginated

@return [Boolean]

@api private

# File lib/tty/prompt/list.rb, line 84
def paginated?
  @choices.size > page_size
end
per_page(value) click to toggle source

Set number of items per page

@api public

# File lib/tty/prompt/list.rb, line 71
def per_page(value)
  @per_page = value
end

Private Instance Methods

answer() click to toggle source

Find value for the choice selected

@return [nil, Object]

@api private

# File lib/tty/prompt/list.rb, line 242
def answer
  @choices[@active - 1].value
end
refresh(lines) click to toggle source

Clear screen lines

@param [String]

@api private

# File lib/tty/prompt/list.rb, line 251
def refresh(lines)
  @prompt.clear_lines(lines)
end
render() click to toggle source

Render a selection list.

By default the result is printed out.

@return [Object] value

return the selected value

@api private

# File lib/tty/prompt/list.rb, line 223
def render
  @prompt.print(@prompt.hide)
  until @done
    question = render_question
    @prompt.print(question)
    @prompt.read_keypress
    @prompt.print(refresh(question.lines.count))
  end
  @prompt.print(render_question)
  answer
ensure
  @prompt.print(@prompt.show)
end
render_header() click to toggle source

Render initial help and selected choice

@return [String]

@api private

# File lib/tty/prompt/list.rb, line 274
def render_header
  if @done
    selected_item = "#{@choices[@active - 1].name}"
    @prompt.decorate(selected_item, @active_color)
  elsif @first_render
    @prompt.decorate(help, @help_color)
  end
end
render_menu() click to toggle source

Render menu with choices to select from

@return [String]

@api private

# File lib/tty/prompt/list.rb, line 288
def render_menu
  output = ''
  @paginator.paginate(@choices, @active, @per_page) do |choice, index|
    num = enumerate? ? (index + 1).to_s + @enum + ' ' : ''
    message = if index + 1 == @active
                selected = @marker + ' ' + num + choice.name
                @prompt.decorate("#{selected}", @active_color)
              else
                ' ' * 2 + num + choice.name
              end
    max_index = paginated? ? @paginator.max_index : @choices.size - 1
    newline = (index == max_index) ? '' : "\n"
    output << (message + newline)
  end
  output
end
render_question() click to toggle source

Render question with instructions and menu

@return [String]

@api private

# File lib/tty/prompt/list.rb, line 260
def render_question
  header = "#{@prefix}#{@question} #{render_header}\n"
  @first_render = false
  rendered_menu = render_menu
  rendered_menu << render_footer
  header << rendered_menu unless @done
  header
end
setup_defaults() click to toggle source

Setup default option and active selection

@api private

# File lib/tty/prompt/list.rb, line 194
def setup_defaults
  validate_defaults
  @active = @default.first
end
validate_defaults() click to toggle source

Validate default indexes to be within range

@api private

# File lib/tty/prompt/list.rb, line 202
def validate_defaults
  @default.each do |d|
    if d.nil? || d.to_s.empty?
      raise ConfigurationError,
           "default index must be an integer in range (1 - #{@choices.size})"
    end
    if d < 1 || d > @choices.size
      raise ConfigurationError,
           "default index `#{d}` out of range (1 - #{@choices.size})"
    end
  end
end