PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/termtter/system_extensions/windows.rb

https://github.com/Epictetus/termtter
Ruby | 86 lines | 78 code | 6 blank | 2 comment | 0 complexity | aac6c29a9b8c9dba70e44718d8194e26 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. require 'iconv'
  3. require 'Win32API'
  4. $wGetACP = Win32API.new('kernel32','GetACP','','I')
  5. module Readline
  6. $iconv_sj_to_u8 = Iconv.new('UTF-8', "CP#{$wGetACP.call()}")
  7. alias :old_readline :readline
  8. def readline(*a)
  9. str = old_readline(*a)
  10. out = ''
  11. loop do
  12. begin
  13. out << $iconv_sj_to_u8.iconv(str)
  14. break
  15. rescue Iconv::Failure
  16. out << "#{$!.success}?"
  17. str = $!.failed[1..-1]
  18. end
  19. end
  20. return out
  21. end
  22. module_function :old_readline, :readline
  23. end
  24. $wSetConsoleTextAttribute = Win32API.new('kernel32','SetConsoleTextAttribute','II','I')
  25. $wGetConsoleScreenBufferInfo = Win32API.new("kernel32", "GetConsoleScreenBufferInfo", ['l', 'p'], 'i')
  26. $wGetStdHandle = Win32API.new('kernel32','GetStdHandle','I','I')
  27. $wGetACP = Win32API.new('kernel32','GetACP','','I')
  28. $hStdOut = $wGetStdHandle.call(0xFFFFFFF5)
  29. lpBuffer = ' ' * 22
  30. $wGetConsoleScreenBufferInfo.call($hStdOut, lpBuffer)
  31. $oldColor = lpBuffer.unpack('SSSSSssssSS')[4]
  32. $colorMap = {
  33. 0 => 0x07|0x00|0x00|0x00, # black/white
  34. 37 => 0x08|0x00|0x00|0x00, # white/intensity
  35. 31 => 0x04|0x08|0x00|0x00, # red/red
  36. 32 => 0x02|0x08|0x00|0x00, # green/green
  37. 33 => 0x06|0x08|0x00|0x00, # yellow/yellow
  38. 34 => 0x01|0x08|0x00|0x00, # blue/blue
  39. 35 => 0x05|0x08|0x00|0x00, # magenta/purple
  40. 36 => 0x03|0x08|0x00|0x00, # cyan/aqua
  41. 39 => 0x07, # default
  42. 40 => 0x00|0x00|0xf0|0x00, # background:white
  43. 41 => 0x07|0x00|0x40|0x00, # background:red
  44. 42 => 0x07|0x00|0x20|0x00, # background:green
  45. 43 => 0x07|0x00|0x60|0x00, # background:yellow
  46. 44 => 0x07|0x00|0x10|0x00, # background:blue
  47. 45 => 0x07|0x00|0x50|0x80, # background:magenta
  48. 46 => 0x07|0x00|0x30|0x80, # background:cyan
  49. 47 => 0x07|0x00|0x70|0x80, # background:gray
  50. 49 => 0x70, # default
  51. 90 => 0x07|0x00|0x00|0x00, # erase/white
  52. }
  53. $iconv_u8_to_sj = Iconv.new("CP#{$wGetACP.call()}", 'UTF-8')
  54. def print(str)
  55. str.to_s.gsub("\xef\xbd\x9e", "\xe3\x80\x9c").split(/(\e\[\d*[a-zA-Z])/).each do |token|
  56. case token
  57. when /\e\[(\d+)m/
  58. color = $1.to_i > 90 ? ($1.to_i % 60) : $1.to_i
  59. $wSetConsoleTextAttribute.call $hStdOut, $colorMap[color].to_i
  60. when /\e\[\d*[a-zA-Z]/
  61. # do nothing
  62. else
  63. loop do
  64. begin
  65. STDOUT.print $iconv_u8_to_sj.iconv(token)
  66. break
  67. rescue Iconv::Failure
  68. STDOUT.print "#{$!.success}?"
  69. token = $!.failed[1..-1]
  70. end
  71. end
  72. end
  73. end
  74. $wSetConsoleTextAttribute.call $hStdOut, $oldColor
  75. $iconv_u8_to_sj.iconv(nil)
  76. end
  77. def puts(str)
  78. print str
  79. STDOUT.puts
  80. end