Skip to content

Commit

Permalink
namespacing - fixes arlimus#14
Browse files Browse the repository at this point in the history
  • Loading branch information
brbrady committed Dec 1, 2015
1 parent 53712b1 commit 2c71aa9
Show file tree
Hide file tree
Showing 11 changed files with 595 additions and 569 deletions.
25 changes: 10 additions & 15 deletions lib/inquirer.rb
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
require 'inquirer/version'
require 'inquirer/utils/iohelper'
require 'inquirer/prompts/list'
require 'inquirer/prompts/checkbox'
require 'inquirer/prompts/input'
require 'inquirer/prompts/confirm'

module Ask
extend self
# implement prompts
def list *args
List.ask *args
end
def checkbox *args
Checkbox.ask *args
module Prompts
PROMPTS = []
end
def input *args
Input.ask *args
end
def confirm *args
Confirm.ask *args
# require prompts after defining Prompts module,
# so prompts can append their names to Prompts::PROMPTS
Dir["#{File.dirname(__FILE__)}/inquirer/prompts/*.rb"].each{|f| require f}
# implement prompts
Prompts::PROMPTS.each do |prompt|
define_method(prompt) do |*args|
Prompts.const_get(prompt.capitalize).ask(*args)
end
end
end
237 changes: 122 additions & 115 deletions lib/inquirer/prompts/checkbox.rb
Original file line number Diff line number Diff line change
@@ -1,135 +1,142 @@
require 'term/ansicolor'
require 'inquirer/style'

# Base rendering for simple lists
module CheckboxRenderer
def render heading = nil, list = [], footer = nil
# render the heading
( heading.nil? ? "" : @heading % heading ) +
# render the list
list.map do |li|
render_item li
end.join("") +
# render the footer
( footer.nil? ? "" : @footer % footer )
end

def renderResponse heading = nil, response = nil
# render the heading
( heading.nil? ? "" : @heading % heading ) +
# render the footer
( response.nil? ? "" : @response % response )
end
module Ask
module Prompts
PROMPTS << :checkbox

# Base rendering for simple lists
module CheckboxRenderer
def render heading = nil, list = [], footer = nil
# render the heading
( heading.nil? ? "" : @heading % heading ) +
# render the list
list.map do |li|
render_item li
end.join("") +
# render the footer
( footer.nil? ? "" : @footer % footer )
end

private
def renderResponse heading = nil, response = nil
# render the heading
( heading.nil? ? "" : @heading % heading ) +
# render the footer
( response.nil? ? "" : @response % response )
end

def render_item x
( x["selected"] ? @selector : " " ) +
( x["active"] ? @checkbox_on : @checkbox_off ) +
" " +
( x["active"] ? @active_item : @item ) % x["value"]
end
private

end
def render_item x
( x["selected"] ? @selector : " " ) +
( x["active"] ? @checkbox_on : @checkbox_off ) +
" " +
( x["active"] ? @active_item : @item ) % x["value"]
end

# Formatting for rendering
class CheckboxDefault
include CheckboxRenderer
C = Term::ANSIColor
def initialize( style )
@heading = "%s:\n"
@footer = "%s\n"
@item = "%s\n"
@active_item = "%s" + "\n"
@selector = C.cyan style.selector
@checkbox_on = C.cyan style.checkbox_on
@checkbox_off = style.checkbox_off
end
end
end

# Default formatting for response
class CheckboxResponseDefault
include CheckboxRenderer
C = Term::ANSIColor
def initialize( style = nil )
@heading = "%s: "
@response = C.cyan("%s") + "\n"
end
end
# Formatting for rendering
class CheckboxDefault
include CheckboxRenderer
C = Term::ANSIColor
def initialize( style )
@heading = "%s:\n"
@footer = "%s\n"
@item = "%s\n"
@active_item = "%s" + "\n"
@selector = C.cyan style.selector
@checkbox_on = C.cyan style.checkbox_on
@checkbox_off = style.checkbox_off
end
end

class Checkbox
def initialize question = nil, elements = [], default = nil, renderer = nil, responseRenderer = nil
@elements = elements
@question = question
@pos = 0
@active = default || elements.map{|i| false}
@prompt = ""
@renderer = renderer || CheckboxDefault.new( Inquirer::Style::Default )
@responseRenderer = responseRenderer = CheckboxResponseDefault.new()
end
# Default formatting for response
class CheckboxResponseDefault
include CheckboxRenderer
C = Term::ANSIColor
def initialize( style = nil )
@heading = "%s: "
@response = C.cyan("%s") + "\n"
end
end

def update_prompt
# transform the list into
# {"value"=>..., "selected"=> true|false, "active"=> true|false }
e = @elements.
# attach the array position
map.with_index(0).
map do |c,pos|
{ "value"=>c, "selected" => pos == @pos, "active" => @active[pos] }
class Checkbox
def initialize question = nil, elements = [], default = nil, renderer = nil, responseRenderer = nil
@elements = elements
@question = question
@pos = 0
@active = default || elements.map{|i| false}
@prompt = ""
@renderer = renderer || CheckboxDefault.new( Inquirer::Style::Default )
@responseRenderer = responseRenderer = CheckboxResponseDefault.new()
end
# call the renderer
@prompt = @renderer.render(@question, e)
end

def update_response
e = @elements
.map.with_index(0)
.select {|f, pos| @active[pos] }
.map {|f, pos| f }
@prompt = @responseRenderer.renderResponse(@question, e.join(", "))
end
def update_prompt
# transform the list into
# {"value"=>..., "selected"=> true|false, "active"=> true|false }
e = @elements.
# attach the array position
map.with_index(0).
map do |c,pos|
{ "value"=>c, "selected" => pos == @pos, "active" => @active[pos] }
end
# call the renderer
@prompt = @renderer.render(@question, e)
end

# Run the list selection, wait for the user to select an item and return
# the selected index
# Params:
# +clear+:: +Bool+ whether to clear the selection prompt once this is done
# defaults to true; set it to false if you want the prompt to remain after
# the user is done with selecting
# +response+:: +Bool+ whether show the rendered response when this is done
# defaults to true; set it to false if you want the prompt to remain after
# the user is done with selecting
def run clear, response
# finish if there's nothing to do
return @active if Array(@elements).empty?

# hides the cursor while prompting
IOHelper.without_cursor do
# render the
IOHelper.render( update_prompt )
# loop through user input
IOHelper.read_key_while do |key|
@pos = (@pos - 1) % @elements.length if key == "up"
@pos = (@pos + 1) % @elements.length if key == "down"
@active[@pos] = !@active[@pos] if key == "space"
IOHelper.rerender( update_prompt )
# we are done if the user hits return
key != "return"
def update_response
e = @elements
.map.with_index(0)
.select {|f, pos| @active[pos] }
.map {|f, pos| f }
@prompt = @responseRenderer.renderResponse(@question, e.join(", "))
end
end

# clear the final prompt and the line
IOHelper.clear if clear
# Run the list selection, wait for the user to select an item and return
# the selected index
# Params:
# +clear+:: +Bool+ whether to clear the selection prompt once this is done
# defaults to true; set it to false if you want the prompt to remain after
# the user is done with selecting
# +response+:: +Bool+ whether show the rendered response when this is done
# defaults to true; set it to false if you want the prompt to remain after
# the user is done with selecting
def run clear, response
# finish if there's nothing to do
return @active if Array(@elements).empty?

# hides the cursor while prompting
IOHelper.without_cursor do
# render the
IOHelper.render( update_prompt )
# loop through user input
IOHelper.read_key_while do |key|
@pos = (@pos - 1) % @elements.length if key == "up"
@pos = (@pos + 1) % @elements.length if key == "down"
@active[@pos] = !@active[@pos] if key == "space"
IOHelper.rerender( update_prompt )
# we are done if the user hits return
key != "return"
end
end

# clear the final prompt and the line
IOHelper.clear if clear

# show the answer
IOHelper.render( update_response ) if response

# return the index of the selected item
@active
end

# show the answer
IOHelper.render( update_response ) if response
def self.ask question = nil, elements = [], opts = {}
l = Checkbox.new question, elements, opts[:default], opts[:renderer], opts[:rendererResponse]
l.run opts.fetch(:clear, true), opts.fetch(:response, true)
end

# return the index of the selected item
@active
end
end

def self.ask question = nil, elements = [], opts = {}
l = Checkbox.new question, elements, opts[:default], opts[:renderer], opts[:rendererResponse]
l.run opts.fetch(:clear, true), opts.fetch(:response, true)
end

end
Loading

0 comments on commit 2c71aa9

Please sign in to comment.