/lib/termtter/system_extensions/windows.rb
Ruby | 86 lines | 78 code | 6 blank | 2 comment | 0 complexity | aac6c29a9b8c9dba70e44718d8194e26 MD5 | raw file
- # -*- coding: utf-8 -*-
- require 'iconv'
- require 'Win32API'
- $wGetACP = Win32API.new('kernel32','GetACP','','I')
- module Readline
- $iconv_sj_to_u8 = Iconv.new('UTF-8', "CP#{$wGetACP.call()}")
- alias :old_readline :readline
- def readline(*a)
- str = old_readline(*a)
- out = ''
- loop do
- begin
- out << $iconv_sj_to_u8.iconv(str)
- break
- rescue Iconv::Failure
- out << "#{$!.success}?"
- str = $!.failed[1..-1]
- end
- end
- return out
- end
- module_function :old_readline, :readline
- end
- $wSetConsoleTextAttribute = Win32API.new('kernel32','SetConsoleTextAttribute','II','I')
- $wGetConsoleScreenBufferInfo = Win32API.new("kernel32", "GetConsoleScreenBufferInfo", ['l', 'p'], 'i')
- $wGetStdHandle = Win32API.new('kernel32','GetStdHandle','I','I')
- $wGetACP = Win32API.new('kernel32','GetACP','','I')
- $hStdOut = $wGetStdHandle.call(0xFFFFFFF5)
- lpBuffer = ' ' * 22
- $wGetConsoleScreenBufferInfo.call($hStdOut, lpBuffer)
- $oldColor = lpBuffer.unpack('SSSSSssssSS')[4]
- $colorMap = {
- 0 => 0x07|0x00|0x00|0x00, # black/white
- 37 => 0x08|0x00|0x00|0x00, # white/intensity
- 31 => 0x04|0x08|0x00|0x00, # red/red
- 32 => 0x02|0x08|0x00|0x00, # green/green
- 33 => 0x06|0x08|0x00|0x00, # yellow/yellow
- 34 => 0x01|0x08|0x00|0x00, # blue/blue
- 35 => 0x05|0x08|0x00|0x00, # magenta/purple
- 36 => 0x03|0x08|0x00|0x00, # cyan/aqua
- 39 => 0x07, # default
- 40 => 0x00|0x00|0xf0|0x00, # background:white
- 41 => 0x07|0x00|0x40|0x00, # background:red
- 42 => 0x07|0x00|0x20|0x00, # background:green
- 43 => 0x07|0x00|0x60|0x00, # background:yellow
- 44 => 0x07|0x00|0x10|0x00, # background:blue
- 45 => 0x07|0x00|0x50|0x80, # background:magenta
- 46 => 0x07|0x00|0x30|0x80, # background:cyan
- 47 => 0x07|0x00|0x70|0x80, # background:gray
- 49 => 0x70, # default
- 90 => 0x07|0x00|0x00|0x00, # erase/white
- }
- $iconv_u8_to_sj = Iconv.new("CP#{$wGetACP.call()}", 'UTF-8')
- def print(str)
- str.to_s.gsub("\xef\xbd\x9e", "\xe3\x80\x9c").split(/(\e\[\d*[a-zA-Z])/).each do |token|
- case token
- when /\e\[(\d+)m/
- color = $1.to_i > 90 ? ($1.to_i % 60) : $1.to_i
- $wSetConsoleTextAttribute.call $hStdOut, $colorMap[color].to_i
- when /\e\[\d*[a-zA-Z]/
- # do nothing
- else
- loop do
- begin
- STDOUT.print $iconv_u8_to_sj.iconv(token)
- break
- rescue Iconv::Failure
- STDOUT.print "#{$!.success}?"
- token = $!.failed[1..-1]
- end
- end
- end
- end
- $wSetConsoleTextAttribute.call $hStdOut, $oldColor
- $iconv_u8_to_sj.iconv(nil)
- end
- def puts(str)
- print str
- STDOUT.puts
- end