Skip to content

Instantly share code, notes, and snippets.

@beccasaurus
Last active July 10, 2019 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beccasaurus/992de401eae28119a3b094889046319a to your computer and use it in GitHub Desktop.
Save beccasaurus/992de401eae28119a3b094889046319a to your computer and use it in GitHub Desktop.
Playing with syswrite
require "drb/drb"
DRb.start_service
@screen = DRbObject.new_with_uri "druby://localhost:6789"
def write content
@screen.write content
end
require "irb"
puts "Connected to screen"
puts "use write() method"
puts
puts "e.g. write \"Hello, world!\""
binding.irb

Playing with syswrite

Run screen.rb

Run client.rb

Try it out

write "Hello"
write "\e[1G" # go to start of line
write "\e[0K" # clear line
write "\e[1A" # go up one
require "drb/drb"
class Screen
def initialize output
@output = output
end
def write content
@output.syswrite content
end
end
screen = Screen.new STDOUT
DRb.start_service "druby://localhost:6789", screen
puts "screen available @ druby://localhost:6789"
DRb.thread.join
require "drb/drb"
DRb.start_service
@screen = DRbObject.new_with_uri "druby://localhost:6789"
def write *contents
contents.each { |content| @screen.write content }
end
def clear_screen
@screen.clear
end
# 0 Header (real-time updates) (poll on every keystroke)
# 1
# 2 > prompt
# 3
# 4 $ last run comment
# 5 output here
# 6
# 7 $ the command before that
# 8 output here
clear_screen
write "[This is the header]\n"
write "\n"
write "> this is where I'm typing my command..."
# later, print older ones below.
# right now, only show last command results.
# [{ command: "str", output: "str" }, {}]
# command_results = []
def run command_string
# re-write the `>` with the command, as if we typed it
write_line "> #{command_string}"
if @last_output_lines
# if the output of a previous command is present, delete it
go_down 2
write_line "$ "
@last_output_lines.times { go_down; clear_line }
@last_output_lines.times { go_up }
go_up 2
else
# else, this is the first `run` - let's add the $ line below for output
go_down 2
write "$ \n"
write "\n"
go_up 4
end
# copy command from > to $
go_down 2
write_line "$ #{command_string}"
# clear the prompt (after drawing the command down below)
go_up 2
write_line "> "
# get the output (stdout only), hoping it doesn't blow up
output = `#{command_string} 2>&1`
# print the output on the line below $ command
go_down 3
write output
# now the cursor is output lines length further down
# put the cursor back on the prompt line
go_up output.lines.length + 3
@last_output_lines = output.lines.length
end
def go_down lines = 1
write "\e[#{lines}E"
end
def go_up lines = 1
write "\e[#{lines}A"
end
def clear_line
write "\e[1G\e[0K"
end
def write_line line
clear_line
write line
end
require "irb"
puts "Connected to screen"
puts "use write() method"
puts
puts "e.g. write \"Hello, world!\""
binding.irb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment