lib/tty/reader/win_console.rb
# frozen_string_literal: true
require_relative "keys"
module TTY
class Reader
class WinConsole
ESC = "\e"
NUL_HEX = "\x00"
EXT_HEX = "\xE0"
# Key codes
#
# @return [Hash[Symbol]]
#
# @api public
attr_reader :keys
# Escape codes
#
# @return [Array[Integer]]
#
# @api public
attr_reader :escape_codes
def initialize(input)
require_relative "win_api"
@input = input
@keys = Keys.ctrl_keys.merge(Keys.win_keys)
@escape_codes = [[NUL_HEX.ord], [ESC.ord], EXT_HEX.bytes.to_a]
end
# Get a character from console blocking for input
#
# @param [Boolean] echo
# whether to echo input back or not, defaults to true
# @param [Boolean] raw
# whether to use raw mode or not, defaults to false
# @param [Boolean] nonblock
# whether to wait for input or not, defaults to false
#
# @return [String]
#
# @api private
def get_char(echo: true, raw: false, nonblock: false)
if raw && echo
if nonblock
get_char_echo_non_blocking
else
get_char_echo_blocking
end
elsif raw && !echo
nonblock ? get_char_non_blocking : get_char_blocking
elsif !raw && !echo
nonblock ? get_char_non_blocking : get_char_blocking
else
@input.getc
end
end
# Get the char for last key pressed, or if no keypress return nil
#
# @api private
def get_char_non_blocking
input_ready? ? get_char_blocking : nil
end
def get_char_echo_non_blocking
input_ready? ? get_char_echo_blocking : nil
end
def get_char_blocking
WinAPI.getch.chr
end
def get_char_echo_blocking
WinAPI.getche.chr
end
# Check if IO has user input
#
# @return [Boolean]
#
# @api private
def input_ready?
!WinAPI.kbhit.zero?
end
end # Console
end # Reader
end # TTY