Skip to content

Instantly share code, notes, and snippets.

@tompng
Created August 12, 2024 09:35
Show Gist options
  • Save tompng/478ccaad431d06b0adab4273a8e20a18 to your computer and use it in GitHub Desktop.
Save tompng/478ccaad431d06b0adab4273a8e20a18 to your computer and use it in GitHub Desktop.
require 'io/console'
require 'pty'
command = ARGV.join(' ')
if command.empty?
puts 'Error: Command not specified.'
puts "Usage: `ruby #{File.basename __FILE__} options -- command`"
exit
end
class SequenceReader
def initialize(input)
@input = input
@buf = nil
end
def read
loop do
c = @input.getc
return unless c
if @buf
@buf << c
if @buf.match?(/\A\e([^\[O]|\[[?;\d]*)[^?;\d]|O./)
buf = @buf
@buf = nil
return buf
end
elsif c == "\e"
@buf = c
else
return c
end
end
end
end
wait = 0
wait_write = ->(a = 1) { sleep a * 0.001 * 2**(wait - 1) if wait != 0 }
puts 'F1 : Rendering speed += 1'
puts 'F2 : Rendering speed -= 1'
PTY.spawn command do |pty_input, pty_output|
update_winsize = -> { pty_output.winsize = $stdin.winsize }
Signal.trap(:WINCH, &update_winsize)
update_winsize.call
Thread.new do
$stdin.raw do
stdin = SequenceReader.new($stdin)
loop do
data = stdin.read
case data
when nil
exit
when "\eOP" # F1
wait = [wait - 1, 0].max
when "\eOQ" # F2
wait = [wait + 1, 10].min
else
pty_output.write data
end
end
end
end
reader = SequenceReader.new pty_input
loop do
c = reader.read
exit unless c
case c
when "\e[?25l"
# ignore cursor hide
next
when /\A\e\[.+[JKLM]/
# use default color for clear line or screen
wait_write.call 10
when /\A\e\[.+[A-ISTZ]/, /\A\e[DEM]/, /[\x0A-\x0D]/
wait_write.call 10
end
wait_write.call
$stdout << c
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment