1#!/usr/bin/env ruby 2# 3# irbtkw.rb : IRB console with Ruby/Tk 4# 5# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp) 6# 7release = '2008/03/08' 8 9require 'tk' 10begin 11 require 'tktextio' 12rescue LoadError 13 require File.join(File.dirname(File.expand_path(__FILE__)), 'tktextio.rb') 14end 15 16require 'irb' 17 18if TkCore::WITH_ENCODING 19else 20 # $KCODE setup 21 case Tk.encoding 22 when 'shiftjis', 'cp932' 23 $KCODE='SJIS' 24 when 'euc-jp' 25 $KCODE='EUC' 26 when 'utf-8', 'unicode' 27 $KCODE='UTF8' 28 else 29 # unknown 30 end 31end 32 33# console setup 34top = TkToplevel.new(:title=>'IRB console') 35top.protocol(:WM_DELETE_WINDOW){ Tk.exit } 36 37case (Tk.windowingsystem) 38when 'win32' 39 fnt = ['MS Gothic', '-12'] 40else 41 fnt = ['courier', '-12'] 42end 43 44console = TkTextIO.new(top, :mode=>:console, 45 :width=>80).pack(:side=>:left, 46 :expand=>true, :fill=>:both) 47console.yscrollbar(TkScrollbar.new(top, :width=>10).pack(:before=>console, 48 :side=>:right, 49 :expand=>false, 50 :fill=>:y)) 51 52# save original I/O 53out = $stdout 54err = $stderr 55 56irb_thread = nil 57ev_loop = Thread.new{ 58 begin 59 Tk.mainloop 60 ensure 61 $stdout = out 62 $stderr = err 63 irb_thread.kill if irb_thread 64 end 65} 66 67# window position control 68root = Tk.root 69 70r_x = root.winfo_rootx 71r_y = root.winfo_rooty 72r_w = root.winfo_width 73 74t_x = top.winfo_rootx 75t_y = top.winfo_rooty 76t_w = top.winfo_width 77 78delta = 10 79 80ratio = 0.8 81s_w = (ratio * root.winfo_screenwidth).to_i 82 83if r_x < t_x 84 r_x, t_x = t_x, r_x 85end 86if t_x + t_w + r_w + delta < s_w 87 r_x = t_x + t_w + delta 88elsif t_w + r_w + delta < s_w 89 r_x = s_w - r_w 90 t_x = r_x - t_w 91else 92 r_x = s_w - r_w 93 t_x = 0 94end 95 96root.geometry("+#{r_x}+#{r_y}") 97top.geometry("+#{t_x}+#{t_y}") 98 99root.raise 100console.focus 101 102# I/O setup 103$stdin = console 104$stdout = console 105$stderr = console 106 107# dummy for rubyw.exe on Windows 108def STDIN.tty? 109 true 110end 111 112# IRB setup 113IRB.init_config(nil) 114IRB.conf[:USE_READLINE] = false 115IRB.init_error 116irb = IRB::Irb.new 117IRB.conf[:MAIN_CONTEXT] = irb.context 118 119class IRB::StdioInputMethod 120 def gets 121 prompt = "\n" << @prompt 122 $stdin.instance_eval{ 123 flush 124 @prompt = prompt 125 _set_console_line 126 @prompt = nil 127 _see_pos 128 } 129 130 @line[@line_no += 1] = $stdin.gets 131 end 132end 133 134# IRB start 135$stdout.print("*** IRB console on Ruby/Tk (#{release}) ") 136irb_thread = Thread.new{ 137 catch(:IRB_EXIT){ 138 loop { 139 begin 140 irb.eval_input 141 rescue Exception 142 end 143 } 144 } 145} 146 147console.bind('Control-c'){ 148 console.insert('end', "^C\n") 149 irb_thread.raise RubyLex::TerminateLineInput 150} 151 152irb_thread.join 153 154# exit 155ev_loop.kill 156Tk.exit 157