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