You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
1.3 KiB
Ruby
73 lines
1.3 KiB
Ruby
require 'open3'
|
|
|
|
class Terminal
|
|
|
|
SCRIPT_PATH = (Rails.root + "vt" + "main.js").to_s
|
|
|
|
def initialize(width, height)
|
|
@process = Process.new("node #{SCRIPT_PATH}")
|
|
send_cmd("new", { width: width, height: height })
|
|
end
|
|
|
|
def feed(data)
|
|
send_cmd("feed-str", { str: data })
|
|
end
|
|
|
|
def screen
|
|
send_cmd("dump-screen")
|
|
screen = read_result
|
|
lines = screen.fetch("lines")
|
|
cursor = screen.fetch("cursor")
|
|
|
|
{
|
|
snapshot: Snapshot.build(lines),
|
|
cursor: Cursor.new(cursor['x'], cursor['y'], cursor['visible'])
|
|
}
|
|
end
|
|
|
|
def release
|
|
process.stop
|
|
end
|
|
|
|
private
|
|
|
|
def send_cmd(cmd, data = {})
|
|
json = data.merge({ cmd: cmd }).to_json
|
|
process.write("#{json}\n")
|
|
end
|
|
|
|
def read_result()
|
|
Yajl::Parser.new.parse(process.read_line).fetch("result")
|
|
end
|
|
|
|
attr_reader :process
|
|
|
|
class Process
|
|
|
|
def initialize(command)
|
|
@stdin, @stdout, @thread = Open3.popen2(command)
|
|
end
|
|
|
|
def write(data)
|
|
check_thread!
|
|
@stdin.write(data)
|
|
end
|
|
|
|
def read_line
|
|
check_thread!
|
|
@stdout.readline.strip
|
|
end
|
|
|
|
def stop
|
|
@stdin.close
|
|
end
|
|
|
|
private
|
|
|
|
def check_thread!
|
|
raise "terminal died, exit code: #{@thread.value.exitstatus}, signaled?: #{@thread.value.signaled?}" unless @thread.alive?
|
|
end
|
|
end
|
|
|
|
end
|