class PhusionPassenger::Utils::TerminalChoiceMenu
def [](name)
def [](name) return @index[name] end
def clear_screen
def clear_screen number_of_lines = render_to_string.split("\n").size display("\r") (number_of_lines - 1).times do display(move_up) end end
def display(str)
def display(str) STDOUT.write(str) STDOUT.flush end
def display_choices
def display_choices display(render_to_string) end
def getchar(io)
def getchar(io) char = io.getc char = char.chr if char.is_a?(Integer) return char end
def hide_cursor
def hide_cursor display("\x1b[?25l") end
def index_choices
def index_choices index = {} @choices.each do |choice| index[choice.name] = choice end return index end
def initialize(choices)
def initialize(choices) @choices = choices.map { |choice| Choice.create(choice) } @pointer = 0 @index = index_choices end
def maybe_utf8(utf8, plain)
def maybe_utf8(utf8, plain) if ENV['UTF8_MENUS'] == '0' return plain else return utf8 end end
def move_up
def move_up return "\x1b[0A" end
def process_cursor_move
def process_cursor_move if getchar(STDIN) == "[" case getchar(STDIN) when "A" # up @pointer = [@pointer - 1, 0].max when "B" # down @pointer = [@pointer + 1, @choices.size - 1].min end end end
def process_disable_utf8
def process_disable_utf8 ENV['UTF8_MENUS'] = '0' end
def process_input
def process_input case getchar(STDIN) when "\x1b" process_cursor_move return false when " " process_toggle return false when "!" process_disable_utf8 return false when "\r" return true else return false end end
def process_toggle
def process_toggle @choices[@pointer].toggle! end
def query
def query if STDIN.tty? done = false begin raw_no_echo_mode hide_cursor while !done display_choices done = process_input clear_screen if !done end ensure restore_mode show_cursor puts end else display_choices puts end end
def raw_no_echo_mode
def raw_no_echo_mode input = STDIN.to_inputstream output = STDOUT.to_outputstream @console = ConsoleReader.new(input, output) @console.set_history_enabled(false) @console.set_bell_enabled(true) @console.set_pagination_enabled(false) @terminal_state = @console.getEchoCharacter @console.setEchoCharacter(0) end
def raw_no_echo_mode
def raw_no_echo_mode @terminal_state = `stty -g` system("stty raw -echo -icanon isig") end
def render_checkbox(checked)
def render_checkbox(checked) return checked ? maybe_utf8("⬢", "(*)") : maybe_utf8("⬡", "( )") end
def render_pointer(index)
def render_pointer(index) return @pointer == index ? maybe_utf8("‣", ">") : " " end
def render_to_string
def render_to_string str = "" @choices.each_with_index do |choice, i| pointer = render_pointer(i) checkbox = render_checkbox(choice.checked) str << " #{pointer} #{checkbox} #{choice.name}\r\n" end str.chomp! return str end
def restore_mode
def restore_mode @console.setEchoCharacter(@terminal_state) @console.get_terminal.restore end
def restore_mode
def restore_mode system("stty #{@terminal_state}") end
def selected_choices
def selected_choices @choices.find_all{ |c| c.checked? }.map{ |c| c.name } end
def show_cursor
def show_cursor display("\x1b[?25h") end