vendor/highline/lib/highline/system_extensions.rb in radiant-0.7.2 vs vendor/highline/lib/highline/system_extensions.rb in radiant-0.8.0

- old
+ new

@@ -18,46 +18,109 @@ # begin # Cygwin will look like Windows, but we want to treat it like a Posix OS: raise LoadError, "Cygwin is a Posix OS." if RUBY_PLATFORM =~ /\bcygwin\b/i - require "Win32API" # See if we're on Windows. + require "Win32API" # See if we're on Windows. CHARACTER_MODE = "Win32API" # For Debugging purposes only. # # Windows savvy getc(). # - # *WARNING*: This method ignores <tt>input</tt> and reads one - # character from +STDIN+! # def get_character( input = STDIN ) - Win32API.new("crtdll", "_getch", [ ], "L").Call + @stdin_handle ||= GetStdHandle(STD_INPUT_HANDLE) + + begin + SetConsoleEcho(@stdin_handle, false) + input.getbyte + ensure + SetConsoleEcho(@stdin_handle, true) + end end # A Windows savvy method to fetch the console columns, and rows. def terminal_size - m_GetStdHandle = Win32API.new( 'kernel32', - 'GetStdHandle', - ['L'], - 'L' ) - m_GetConsoleScreenBufferInfo = Win32API.new( - 'kernel32', 'GetConsoleScreenBufferInfo', ['L', 'P'], 'L' - ) - - format = 'SSSSSssssSS' - buf = ([0] * format.size).pack(format) - stdout_handle = m_GetStdHandle.call(0xFFFFFFF5) + stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE) - m_GetConsoleScreenBufferInfo.call(stdout_handle, buf) - bufx, bufy, curx, cury, wattr, - left, top, right, bottom, maxx, maxy = buf.unpack(format) + bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy = + GetConsoleScreenBufferInfo(stdout_handle) return right - left + 1, bottom - top + 1 end - rescue LoadError # If we're not on Windows try... + + # windows savvy console echo toggler + def SetConsoleEcho( console_handle, on ) + mode = GetConsoleMode(console_handle) + + # toggle the console echo bit + if on + mode |= ENABLE_ECHO_INPUT + else + mode &= ~ENABLE_ECHO_INPUT + end + + ok = SetConsoleMode(console_handle, mode) + end + + # win32 console APIs + + STD_INPUT_HANDLE = -10 + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + + ENABLE_PROCESSED_INPUT = 0x0001 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_WINDOW_INPUT = 0x0008 + ENABLE_MOUSE_INPUT = 0x0010 + ENABLE_INSERT_MODE = 0x0020 + ENABLE_QUICK_EDIT_MODE = 0x0040 + + @@apiGetStdHandle = nil + @@apiGetConsoleMode = nil + @@apiSetConsoleMode = nil + @@apiGetConsoleScreenBufferInfo = nil + + def GetStdHandle( handle_type ) + @@apiGetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle", + ['L'], 'L' ) + + @@apiGetStdHandle.call( handle_type ) + end + + def GetConsoleMode( console_handle ) + @@apiGetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode", + ['L', 'P'], 'I' ) + + mode = ' ' * 4 + @@apiGetConsoleMode.call(console_handle, mode) + mode.unpack('L')[0] + end + + def SetConsoleMode( console_handle, mode ) + @@apiSetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode", + ['L', 'L'], 'I' ) + + @@apiSetConsoleMode.call(console_handle, mode) != 0 + end + + def GetConsoleScreenBufferInfo( console_handle ) + @@apiGetConsoleScreenBufferInfo ||= + Win32API.new( "kernel32", "GetConsoleScreenBufferInfo", + ['L', 'P'], 'L' ) + + format = 'SSSSSssssSS' + buf = ([0] * format.size).pack(format) + @@apiGetConsoleScreenBufferInfo.call(console_handle, buf) + buf.unpack(format) + end + + rescue LoadError # If we're not on Windows try... begin - require "termios" # Unix, first choice. + require "termios" # Unix, first choice. CHARACTER_MODE = "termios" # For Debugging purposes only. # # Unix savvy getc(). (First choice.) @@ -71,16 +134,16 @@ new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON) new_settings.c_cc[Termios::VMIN] = 1 begin Termios.setattr(input, Termios::TCSANOW, new_settings) - input.getc + input.getbyte ensure Termios.setattr(input, Termios::TCSANOW, old_settings) end end - rescue LoadError # If our first choice fails, default. + rescue LoadError # If our first choice fails, default. CHARACTER_MODE = "stty" # For Debugging purposes only. # # Unix savvy getc(). (Second choice.) # @@ -88,11 +151,11 @@ # def get_character( input = STDIN ) raw_no_echo_mode begin - input.getc + input.getbyte ensure restore_mode end end @@ -101,11 +164,11 @@ # # *WARNING*: This method requires the external "stty" program! # def raw_no_echo_mode @state = `stty -g` - system "stty raw -echo cbreak" + system "stty raw -echo cbreak isig" end # # Restores a previously saved input mode. # @@ -116,10 +179,15 @@ end end # A Unix savvy method to fetch the console columns, and rows. def terminal_size - `stty size`.split.map { |x| x.to_i }.reverse + if /solaris/ =~ RUBY_PLATFORM and + `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/ + [$2, $1].map { |c| x.to_i } + else + `stty size`.split.map { |x| x.to_i }.reverse + end end end end end