about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-07-03 19:05:47 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2016-07-03 19:05:47 +0200
commitc7009c75fbc2efc1d71cd2d9709cdedd11fe0330 (patch)
tree93746762e0cb5414c9fef92f8a620461d4bd1fd6
downloadlrep-c7009c75fbc2efc1d71cd2d9709cdedd11fe0330.tar.gz
lrep-c7009c75fbc2efc1d71cd2d9709cdedd11fe0330.tar.xz
lrep-c7009c75fbc2efc1d71cd2d9709cdedd11fe0330.zip
initial import of lrep
-rwxr-xr-xlrep93
1 files changed, 93 insertions, 0 deletions
diff --git a/lrep b/lrep
new file mode 100755
index 0000000..4a98148
--- /dev/null
+++ b/lrep
@@ -0,0 +1,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