1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
require 'irb/ruby-lex'
require 'stringio'
class MimickIRB < RubyLex
attr_accessor :started
class Continue < StandardError; end
class Empty < StandardError; end
def initialize
super
set_input(StringIO.new)
end
def run(str)
obj = nil
@io << str
@io.rewind
unless l = lex
raise Empty if @line == ''
else
case l.strip
when "reset"
@line = ""
when "time"
@line = "puts %{You started \#{IRBalike.started.since} ago.}"
else
@line << l << "\n"
if @ltype or @continue or @indent > 0
raise Continue
end
end
end
unless @line.empty?
obj = eval @line, TOPLEVEL_BINDING, "(irb)", @line_no
end
@line_no += @line.scan(/\n/).length
@line = ''
@exp_line_no = @line_no
@indent = 0
@indent_stack = []
$stdout.rewind
output = $stdout.read
$stdout.truncate(0)
$stdout.rewind
[output, obj]
rescue Object => e
case e when Empty, Continue
else @line = ""
end
raise e
ensure
set_input(StringIO.new)
end
end
CURSOR = ">>"
IRBalike = MimickIRB.new
$stdout = StringIO.new
Shoes.app do
@str, @cmd = [CURSOR + " "], ""
stack :width => 1.0, :height => 1.0 do
background "#555"
stack :width => 1.0, :height => 50 do
para "Interactive Ruby ready.", :fill => white, :stroke => red
end
@scroll =
stack :width => 1.0, :height => -50, :scroll => true do
background "#555"
@console = para @str, :font => "Monospace 12px", :stroke => "#dfa"
@console.cursor = -1
end
end
keypress do |k|
case k
when "\n"
begin
out, obj = IRBalike.run(@cmd + ';')
@str += ["#@cmd\n",
span("#{out}=> #{obj.inspect}\n", :stroke => "#fda"),
"#{CURSOR} "]
@cmd = ""
rescue MimickIRB::Empty
rescue MimickIRB::Continue
@str += ["#@cmd\n.. "]
@cmd = ""
rescue Object => e
@str += ["#@cmd\n", span("#{e.class}: #{e.message}\n", :stroke => "#fcf"),
"#{CURSOR} "]
@cmd = ""
end
when String
@cmd += k
when :backspace
@cmd.slice!(-1)
when :tab
@cmd += " "
when :alt_q
quit
when :alt_c
self.clipboard = @cmd
when :alt_v
@cmd += self.clipboard
end
@console.replace *(@str + [@cmd])
@scroll.scroll_top = @scroll.scroll_max
end
end
|