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.
asciinema.org/app/models/terminal.rb

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