123456789_123456789_123456789_123456789_123456789_

Class: Reline::Windows

Relationships & Source Files
Namespace Children
Classes:
Inherits: Object
Defined in: lib/reline/windows.rb

Constant Summary

Class Attribute Summary

Class Method Summary

Class Attribute Details

.win?Boolean (readonly)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 8

def self.win?
  true
end

Class Method Details

.clear_screen

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 252

def self.clear_screen
  csbi = 0.chr * 22
  return if @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi) == 0
  buffer_width = csbi[0, 2].unpack('S').first
  attributes = csbi[8, 2].unpack('S').first
  _window_left, window_top, _window_right, window_bottom = *csbi[10,8].unpack('S*')
  fill_length = buffer_width * (window_bottom - window_top + 1)
  screen_topleft = window_top * 65536
  written = 0.chr * 4
  @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, fill_length, screen_topleft, written)
  @@FillConsoleOutputAttribute.call(@@hConsoleHandle, attributes, fill_length, screen_topleft, written)
  @@SetConsoleCursorPosition.call(@@hConsoleHandle, screen_topleft)
end

.cursor_pos

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 208

def self.cursor_pos
  csbi = 0.chr * 22
  @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
  x = csbi[4, 2].unpack('s*').first
  y = csbi[6, 2].unpack('s*').first
  Reline::CursorPos.new(x, y)
end

.deprep(otio)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 279

def self.deprep(otio)
  # do nothing
end

.encoding

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 4

def self.encoding
  Encoding::UTF_8
end

.erase_after_cursor

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 236

def self.erase_after_cursor
  csbi = 0.chr * 24
  @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
  cursor = csbi[4, 4].unpack('L').first
  written = 0.chr * 4
  @@FillConsoleOutputCharacter.call(@@hConsoleHandle, 0x20, get_screen_size.last - cursor_pos.x, cursor, written)
end

.get_screen_size

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 202

def self.get_screen_size
  csbi = 0.chr * 22
  @@GetConsoleScreenBufferInfo.call(@@hConsoleHandle, csbi)
  csbi[0, 4].unpack('SS').reverse
end

.getc

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 150

def self.getc
  num_of_events = 0.chr * 8
  while @@GetNumberOfConsoleInputEvents.(@@hConsoleInputHandle, num_of_events) != 0 and num_of_events.unpack('L').first > 0
    input_record = 0.chr * 18
    read_event = 0.chr * 4
    if @@ReadConsoleInput.(@@hConsoleInputHandle, input_record, 1, read_event) != 0
      event = input_record[0, 2].unpack('s*').first
      if event == WINDOW_BUFFER_SIZE_EVENT
        @@winch_handler.()
      end
    end
  end
  unless @@output_buf.empty?
    return @@output_buf.shift
  end
  input = getwch
  meta = (@@GetKeyState.call(VK_LMENU) & 0x80) != 0
  control = (@@GetKeyState.call(VK_CONTROL) & 0x80) != 0
  shift = (@@GetKeyState.call(VK_SHIFT) & 0x80) != 0
  force_enter = !input.instance_of?(Array) && (control or shift) && input == 0x0D
  if force_enter
    # It's treated as Meta+Enter on Windows
    @@output_buf.push("\e".ord)
    @@output_buf.push(input)
  else
    case input
    when 0x00
      meta = false
      @@output_buf.push(input)
      input = getwch
      @@output_buf.push(*input)
    when 0xE0
      @@output_buf.push(input)
      input = getwch
      @@output_buf.push(*input)
    when 0x03
      @@output_buf.push(input)
    else
      @@output_buf.push(input)
    end
  end
  if meta
    "\e".ord
  else
    @@output_buf.shift
  end
end

.getwch

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 124

def self.getwch
  unless @@input_buf.empty?
    return @@input_buf.shift
  end
  while @@kbhit.call == 0
    sleep(0.001)
  end
  until @@kbhit.call == 0
    ret = @@getwch.call
    if ret == 0 or ret == 0xE0
      @@input_buf << ret
      ret = @@getwch.call
      @@input_buf << ret
      return @@input_buf.shift
    end
    begin
      bytes = ret.chr(Encoding::UTF_8).bytes
      @@input_buf.push(*bytes)
    rescue Encoding::UndefinedConversionError
      @@input_buf << ret
      @@input_buf << @@getwch.call if ret == 224
    end
  end
  @@input_buf.shift
end

.move_cursor_column(val)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 216

def self.move_cursor_column(val)
  @@SetConsoleCursorPosition.call(@@hConsoleHandle, cursor_pos.y * 65536 + val)
end

.move_cursor_down(val)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 228

def self.move_cursor_down(val)
  if val > 0
    @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y + val) * 65536 + cursor_pos.x)
  elsif val < 0
    move_cursor_up(-val)
  end
end

.move_cursor_up(val)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 220

def self.move_cursor_up(val)
  if val > 0
    @@SetConsoleCursorPosition.call(@@hConsoleHandle, (cursor_pos.y - val) * 65536 + cursor_pos.x)
  elsif val < 0
    move_cursor_down(-val)
  end
end

.msys_tty?(io = @@hConsoleInputHandle) ⇒ Boolean

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 100

def self.msys_tty?(io=@@hConsoleInputHandle)
  # check if fd is a pipe
  if @@GetFileType.call(io) != FILE_TYPE_PIPE
    return false
  end

  bufsize = 1024
  p_buffer = "\0" * bufsize
  res = @@GetFileInformationByHandleEx.call(io, FILE_NAME_INFO, p_buffer, bufsize - 2)
  return false if res == 0

  # get pipe name: p_buffer layout is:
  #   struct _FILE_NAME_INFO {
  #     DWORD FileNameLength;
  #     WCHAR FileName[1];
  #   } FILE_NAME_INFO
  len = p_buffer[0, 4].unpack("L")[0]
  name = p_buffer[4, len].encode(Encoding::UTF_8, Encoding::UTF_16LE, invalid: :replace)

  # Check if this could be a MSYS2 pty pipe ('\msys-XXXX-ptyN-XX')
  # or a cygwin pty pipe ('\cygwin-XXXX-ptyN-XX')
  name =~ /(msys-|cygwin-).*-pty/ ? true : false
end

.prep

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 274

def self.prep
  # do nothing
  nil
end

.scroll_down(val)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 244

def self.scroll_down(val)
  return if val.zero?
  scroll_rectangle = [0, val, get_screen_size.last, get_screen_size.first].pack('s4')
  destination_origin = 0 # y * 65536 + x
  fill = [' '.ord, 0].pack('SS')
  @@ScrollConsoleScreenBuffer.call(@@hConsoleHandle, scroll_rectangle, nil, destination_origin, fill)
end

.set_screen_size(rows, columns)

Raises:

  • (NotImplementedError)
[ GitHub ]

  
# File 'lib/reline/windows.rb', line 266

def self.set_screen_size(rows, columns)
  raise NotImplementedError
end

.set_winch_handler(&handler)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 270

def self.set_winch_handler(&handler)
  @@winch_handler = handler
end

.ungetc(c)

[ GitHub ]

  
# File 'lib/reline/windows.rb', line 198

def self.ungetc(c)
  @@output_buf.unshift(c)
end