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
|
#!/usr/bin/env ruby
# lrep [-z] [-t SECS] [FILES...] - literate read-eval-print
# -*- ruby -*-
require 'pty'
require 'io/console'
# TODO keep each session keyed by ps1?
output = input = pid = nil
trap(:SIGCHLD) { input = output = nil }
def readp(output, ps)
return "[DEAD]" if output == nil
o = ps ? output.readpartial(1024) : ""
# p [:READ, o]
timeout = true
loop {
if o.split("\r\n").last =~ ps
timeout = false
break
end
if IO.select([output],[],[],0.04)
begin
x=output.readpartial(1024)
# p [:READ, x]
o << x
rescue Errno::EIO
# eof
break
end
else
break
end
}
o = "[TIMEOUT]\r\n" + o if timeout && ps
l = o.split("\r\n")
if ps && l[-1]
l[-1].gsub!(ps, "")
l.pop if l[-1].empty?
end
o = l.join("\n")
o
end
def ind(txt)
txt.split("\n").map { |l| "\t#{l}\n" }.join
end
ps = nil
while line = gets
if line =~ /^\t!(.*?)(?:!(.*?))?!(.*)/
puts line
begin
if $1.empty? && $2.empty?
output = input = pid = nil
print ind(`#{$3}`)
else
if $1.empty?
ps = nil
psl = /^\t.*#{Regexp.quote $2}(.*)/
else
ps = /.*?#{Regexp.union [$1,$2].compact}$/
psl = /^\t.*?#{Regexp.union [$1,$2].compact}(.*)/
end
output, input, pid = PTY.spawn $3
input.echo = false
print ind(readp(output, ps))
end
rescue
print ind("ERROR: #{$!.message}")
end
elsif line =~ psl
puts line
if input
# p [:WRITE, $1 + "\n"]
input.write $1 + "\n"
end
print ind(readp(output, ps))
elsif line =~ /^\t/
# old output, remove
else
puts line
end
end
|