Module: ANSI::Terminal

Defined in:
lib/ansi/terminal.rb,
lib/ansi/terminal/stty.rb,
lib/ansi/terminal/win32.rb,
lib/ansi/terminal/curses.rb,
lib/ansi/terminal/termios.rb

Overview

Terminal

This library is based of HighLine’s SystemExtensions by James Edward Gray II.

Copyright 2006 Gray Productions

Distributed under the tems of the Ruby software license.

Constant Summary collapse

STD_INPUT_HANDLE =

win32 console APIs

-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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_character(input = STDIN) ⇒ Object

Unix savvy getc(). (First choice.)

WARNING: This method requires the “termios” library!



16
17
18
19
20
21
22
23
24
# File 'lib/ansi/terminal/stty.rb', line 16

def get_character(input = STDIN)
  raw_no_echo_mode

  begin
    input.getc
  ensure
    restore_mode
  end
end

.GetConsoleMode(console_handle) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/ansi/terminal/win32.rb', line 78

def GetConsoleMode( console_handle )
  @@apiGetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode",
                                        ['L', 'P'], 'I' )

  mode = ' ' * 4
  @@apiGetConsoleMode.call(console_handle, mode)
  mode.unpack('L')[0]
end

.GetConsoleScreenBufferInfo(console_handle) ⇒ Object



94
95
96
97
98
99
100
101
102
103
# File 'lib/ansi/terminal/win32.rb', line 94

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

.GetStdHandle(handle_type) ⇒ Object



71
72
73
74
75
76
# File 'lib/ansi/terminal/win32.rb', line 71

def GetStdHandle( handle_type )
  @@apiGetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle",
                                      ['L'], 'L' )

  @@apiGetStdHandle.call( handle_type )
end

.raw_no_echo_modeObject

Switched the input mode to raw and disables echo.

WARNING: This method requires the external “stty” program!



31
32
33
34
# File 'lib/ansi/terminal/stty.rb', line 31

def raw_no_echo_mode
  @state = `stty -g`
  system "stty raw -echo cbreak isig"
end

.restore_modeObject

Restores a previously saved input mode.

WARNING: This method requires the external “stty” program!



41
42
43
# File 'lib/ansi/terminal/stty.rb', line 41

def restore_mode
  system "stty #{@state}"
end

.screen_width(out = STDERR) ⇒ Object

Console screen width (taken from progress bar)

NOTE: Don’t know how portable #screen_width is. TODO: How to fit into system?



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ansi/terminal/termios.rb', line 50

def screen_width(out=STDERR)
  default_width = ENV['COLUMNS'] || 76
  begin
    tiocgwinsz = 0x5413
    data = [0, 0, 0, 0].pack("SSSS")
    if out.ioctl(tiocgwinsz, data) >= 0 then
      rows, cols, xpixels, ypixels = data.unpack("SSSS")
      if cols >= 0 then cols else default_width end
    else
      default_width
    end
  rescue Exception
    default_width
  end
end

.SetConsoleEcho(console_handle, on) ⇒ Object

windows savvy console echo toggler



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/ansi/terminal/win32.rb', line 38

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

.SetConsoleMode(console_handle, mode) ⇒ Object



87
88
89
90
91
92
# File 'lib/ansi/terminal/win32.rb', line 87

def SetConsoleMode( console_handle, mode )
  @@apiSetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode",
                                        ['L', 'L'], 'I' )

  @@apiSetConsoleMode.call(console_handle, mode) != 0
end

.terminal_heightObject

Get the height of the terminal window.



37
38
39
# File 'lib/ansi/terminal.rb', line 37

def terminal_height
  terminal_size.last
end

.terminal_sizeObject

A Unix savvy method to fetch the console columns, and rows.



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ansi/terminal/stty.rb', line 46

def terminal_size
  if /solaris/ =~ RUBY_PLATFORM && (`stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/)
    w, r = [$2, $1]
  else
    w, r = `stty size`.split.reverse
  end
  w = `tput cols` unless w  # last ditch effort to at least get width

  w = w.to_i if w
  r = r.to_i if r

  return w, r
end

.terminal_widthObject

Get the width of the terminal window.



32
33
34
# File 'lib/ansi/terminal.rb', line 32

def terminal_width
  terminal_size.first
end

Instance Method Details

#get_character(input = STDIN) ⇒ Object (private)

Unix savvy getc(). (First choice.)

WARNING: This method requires the “termios” library!



16
17
18
19
20
21
22
23
24
# File 'lib/ansi/terminal/stty.rb', line 16

def get_character(input = STDIN)
  raw_no_echo_mode

  begin
    input.getc
  ensure
    restore_mode
  end
end

#GetConsoleMode(console_handle) ⇒ Object (private)



78
79
80
81
82
83
84
85
# File 'lib/ansi/terminal/win32.rb', line 78

def GetConsoleMode( console_handle )
  @@apiGetConsoleMode ||= Win32API.new( "kernel32", "GetConsoleMode",
                                        ['L', 'P'], 'I' )

  mode = ' ' * 4
  @@apiGetConsoleMode.call(console_handle, mode)
  mode.unpack('L')[0]
end

#GetConsoleScreenBufferInfo(console_handle) ⇒ Object (private)



94
95
96
97
98
99
100
101
102
103
# File 'lib/ansi/terminal/win32.rb', line 94

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

#GetStdHandle(handle_type) ⇒ Object (private)



71
72
73
74
75
76
# File 'lib/ansi/terminal/win32.rb', line 71

def GetStdHandle( handle_type )
  @@apiGetStdHandle ||= Win32API.new( "kernel32", "GetStdHandle",
                                      ['L'], 'L' )

  @@apiGetStdHandle.call( handle_type )
end

#raw_no_echo_modeObject (private)

Switched the input mode to raw and disables echo.

WARNING: This method requires the external “stty” program!



31
32
33
34
# File 'lib/ansi/terminal/stty.rb', line 31

def raw_no_echo_mode
  @state = `stty -g`
  system "stty raw -echo cbreak isig"
end

#restore_modeObject (private)

Restores a previously saved input mode.

WARNING: This method requires the external “stty” program!



41
42
43
# File 'lib/ansi/terminal/stty.rb', line 41

def restore_mode
  system "stty #{@state}"
end

#screen_width(out = STDERR) ⇒ Object (private)

Console screen width (taken from progress bar)

NOTE: Don’t know how portable #screen_width is. TODO: How to fit into system?



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ansi/terminal/termios.rb', line 50

def screen_width(out=STDERR)
  default_width = ENV['COLUMNS'] || 76
  begin
    tiocgwinsz = 0x5413
    data = [0, 0, 0, 0].pack("SSSS")
    if out.ioctl(tiocgwinsz, data) >= 0 then
      rows, cols, xpixels, ypixels = data.unpack("SSSS")
      if cols >= 0 then cols else default_width end
    else
      default_width
    end
  rescue Exception
    default_width
  end
end

#SetConsoleEcho(console_handle, on) ⇒ Object (private)

windows savvy console echo toggler



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/ansi/terminal/win32.rb', line 38

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

#SetConsoleMode(console_handle, mode) ⇒ Object (private)



87
88
89
90
91
92
# File 'lib/ansi/terminal/win32.rb', line 87

def SetConsoleMode( console_handle, mode )
  @@apiSetConsoleMode ||= Win32API.new( "kernel32", "SetConsoleMode",
                                        ['L', 'L'], 'I' )

  @@apiSetConsoleMode.call(console_handle, mode) != 0
end

#terminal_heightObject (private)

Get the height of the terminal window.



37
38
39
# File 'lib/ansi/terminal.rb', line 37

def terminal_height
  terminal_size.last
end

#terminal_sizeObject (private)

A Unix savvy method to fetch the console columns, and rows.



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ansi/terminal/stty.rb', line 46

def terminal_size
  if /solaris/ =~ RUBY_PLATFORM && (`stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/)
    w, r = [$2, $1]
  else
    w, r = `stty size`.split.reverse
  end
  w = `tput cols` unless w  # last ditch effort to at least get width

  w = w.to_i if w
  r = r.to_i if r

  return w, r
end

#terminal_widthObject (private)

Get the width of the terminal window.



32
33
34
# File 'lib/ansi/terminal.rb', line 32

def terminal_width
  terminal_size.first
end