Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/samples/expert-irb.rb
blob: 8960ef79f9ee47ea701eb6f9601a0f53e7ba6298 (plain)
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