Skip to content

Instantly share code, notes, and snippets.

@tompng
Created April 28, 2023 13:26
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 tompng/2ab7f6a7c5fd5d7846fcece86b30a156 to your computer and use it in GitHub Desktop.
Save tompng/2ab7f6a7c5fd5d7846fcece86b30a156 to your computer and use it in GitHub Desktop.
require 'io/console'
require 'pty'
STDIN.raw!
$> << "\e[H\e[2J\e[2;1H"
row, col = 1, 1
width = 100
height = 40
$write_sleep = 0
$show_sleep = 0
$darkness = false
Thread.new{
sleep 20;
$write_sleep = 0.0025
$show_sleep = 0.04
$darkness = true
}
def color(num)
num = 38 if num == 39
darkness = $darkness ? 10 : 0
r, g, b = [
[0,0,0],
[255,0,0],
[0,255,0],
[255,255,0],
[0,0,255],
[255,0,255],
[0,255,255],
[128,128,128],
[255,255,255],
[32,34,37],
][num % 10].map {[_1 - darkness%20, 0].max}
"\e[#{num / 10}8;2;#{r};#{g};#{b}m"
end
#command = 'ruby -I~/Documents/github/ruby/irb/lib -I~/Documents/github/ruby/reline/lib -I~/Desktop/katakata_irb/lib ~/Documents/github/ruby/irb/exe/irb -f'
command = 'irb'# if ARGV.join.include? 'old'
PTY.spawn command do |pty_input, pty_output|
pty_output.winsize = [height, width]
Thread.new do
loop do
data = STDIN.readpartial 1024
exit if data.nil? || data =~ /Q/
break if data.nil? || data.empty?
pty_output.write data
end
exit
rescue => e
puts e
exit
end
fg = 39
bg = 49
show = ->(msg){
sleep 5 * $show_sleep if $show_sleep > 0
# return if $show_sleep == 0
# puts "\e[1;1H#{msg}\e[#{row};#{col}H"
# sleep $show_sleep
# puts "\e[1;1H\e[K\e[#{row};#{col}H"
# sleep $show_sleep
}
styles = []
seq = ''
color_seq = ''
loop do
c = pty_input.getc
exit if c.nil?
if seq || c == "\e"
seq = '' unless seq
seq << c
if /\e\[(?<question>\?)?(?<params>[\d;]*)(?<cmd>[a-zA-Z])/ =~ seq
params = params.split(';').map(&:to_i)
case cmd
when 'l', 'h'
raise unless question
when 'n', 'J'
$> << seq
when 'K'
show.call "CLEAR LINE"
$> << "\e[m" + seq + color_seq
when 'H'
show.call "MOVE_CURSOR"
row, col = [*params, 1, 1]
when 'm'
params << 0 if params.empty?
params.each {
case _1
when 0
styles = []
fg = 39
bg = 49
when 30..39
fg = _1
when 40..49
bg = _1
else
styles << _1
end
}
seq1 = color(fg)
seq2 = color(bg)
color_seq = "\e[#{[0, *styles].join(';')}m" + seq1 + seq2
$> << color_seq
when 'A'
show.call "MOVE_CURSOR_UP"
row -= params[0] || 1
$> << seq
when 'B', 'S'
show.call "MOVE_CURSOR_DOWN"
row += params[0] || 1
$> << seq
when 'G'
show.call "MOVE_CURSOR_COLUMN"
col = params[0] || 1
$> << seq
else
puts "UNKNOWN #{cmd}"
exit
end
seq = nil
elsif seq =~ /\e[^\[]/
$> << seq
seq = nil
end
else
if c == "\n"
row += 1
elsif c == "\r"
col = 0
end
$> << c
sleep $write_sleep if $write_sleep > 0
col += 1
end
end
end
__END__
srand 3; $skip = true; Thread.new{sleep 5; $skip = false};
[[47,30],[42,30],[43,30],[44,37],[45,37]].each_with_index do |(bg,fg),index|
pointClass = Data.define :x, :y
Reline.add_dialog_proc :"dialog#{index}", ->{
return if $skip
contents = 6.times.map do
'-' * _1 + 'abcdef' + '-' * (5 - _1)
end
Reline::DialogRenderInfo.new(
pos: pointClass.new(x: rand(40), y: rand(20)),
contents: contents,
height: 10,
bg_color: bg,
fg_color: fg,
)
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment