africwildman 发表于 2015-6-22 22:29:07

用gtk ruby写的简易irb

本帖最后由 africwildman 于 2015-6-24 00:27 编辑

就是调用eval执行表达式,参考了一下gnumeric里的py-console.c
代码:#!/usr/bin/env ruby
require 'gtk3'
require 'base64'
require 'stringio'
#base64格式的图标文件
ICON=<<ICON32_EOF
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
ICON32_EOF
#把图片文件转换成gtk的pixbuf格式
def base642pixbuf data
decode = Base64.decode64 data
loader = Gdk::PixbufLoader.new
loader.write decode
loader.close
return loader.pixbuf
end
#核心代码1 binding=Object.new.send :binding
#没有用irb,看了半天没看明白应该怎么调用,于是自己实现一个最简单的irb
binding=Object.new.send :binding
history,i=[],0
out=StringIO.new
out.sync=true
#把标准输出改到字符流,然后textview读取字符流内容
$stdout=out
Gtk.init
window=Gtk::Window.new
window.resize 400,300
window.title="简陋的gtk-irb"
window.icon=base642pixbuf ICON
window.signal_connect("destroy") do
Gtk.main_quit
end
box=Gtk::Box.new :vertical
window << box
textview=Gtk::TextView.new
textview.wrap_mode=:char
textview.editable=false
buffer=textview.buffer
box.add Gtk::ScrolledWindow.new.add(textview),expand:true,fill:true
hbox=Gtk::Box.new :horizontal
prompt=Gtk::Label.new "[#{history.count+1}] > "
entry=Gtk::Entry.new
entry.signal_connect("key-press-event") do |widget,event|
#具体键盘信号对应的名称需要在/usr/include/gtk-3.0/gdk/gdkkeysyms.h里面查
if event.keyval==Gdk::Keyval::KEY_Return or
    event.keyval==Gdk::Keyval::KEY_KP_Enter
    buffer.insert buffer.end_iter,"#{prompt.text}#{entry.text}\n"
    begin
#核心代码2 binding.eval(entry.text)
      buffer.insert buffer.end_iter,
      "=> #{binding.eval(entry.text).inspect}\n#{out.string}"
    rescue Exception
      buffer.insert buffer.end_iter,"#{$!.message}\n#{$!.backtrace.join("\n")}\n"
    rescue SystemExit
      buffer.insert buffer.end_iter,"#{$!.message}\n#{$!.backtrace.join("\n")}\n"
    end
    history.unshift entry.text
    entry.text,i,out.string="",0,""
    prompt.text="[#{history.count+1}] > "
#textview的末尾显示在屏幕上,代码参考的gnumeric的py-console.c
    textview.scroll_mark_onscreen(buffer.create_mark(
      "textend",buffer.end_iter,false))
elsif event.keyval==Gdk::Keyval::KEY_Up
    entry.text=history
    i+=1 if i.abs<(history.count-1)
    entry.position=entry.text.length
elsif event.keyval==Gdk::Keyval::KEY_Down
    if i>0
      i-=1
      entry.text=history
      entry.position=entry.text.length
    else
      entry.text=""
    end
end
end
hbox<< prompt
hbox.add entry,expand:true,fill:true
box<< hbox
entry.set_has_focus true
window.show_all
Gtk.main



页: [1]
查看完整版本: 用gtk ruby写的简易irb