def handle_stdin
@escapes ||= 0
@ebuff ||= ''
$stdin.read_nonblock(1024).each_char do |chr|
if @escapes == 0
if chr == "\e"
@escapes = 1
elsif chr == "\t"
cycle_controls
elsif chr == "\177"
route_key :backspace
else
route_key chr
end
elsif @escapes == 1 && chr == '['
@escapes = 2
elsif @escapes == 1 && chr == 'O'
@escapes = 5
elsif @escapes == 2
if chr == 'A'
route_key :up
elsif chr == 'B'
route_key :down
elsif chr == 'C'
route_key :right
elsif chr == 'D'
route_key :left
elsif chr == 'E'
route_key :center
elsif chr == 'Z'
cycle_controls_back
else
@ebuff = chr
@escapes = 3
end
@escapes = 0 if @escapes == 2
elsif @escapes == 3
if chr == '~' && @ebuff.to_i.to_s == @ebuff
route_key case @ebuff.to_i
when 2; :insert
when 3; :delete
when 5; :pageup
when 6; :pagedown
when 15; :f5
when 17; :f6
when 18; :f7
when 19; :f8
when 20; :f9
when 24; :f12
else; raise @ebuff.inspect
end
elsif @ebuff[0,1] == 'M' && @ebuff.size == 3
@ebuff += chr
info, x, y = @ebuff.unpack('xCCC').map{|i| i - 32}
modifiers = []
modifiers << :shift if info & 4 == 4
modifiers << :meta if info & 8 == 8
modifiers << :control if info & 16 == 16
pane = pane_at(x, y)
unless modal && modal != pane
pane.handle_click BUTTONS[info & 71], modifiers, x, y if pane
end
elsif @ebuff.size > 10
raise "long ebuff #{@ebuff.inspect} - #{chr.inspect}"
else
@ebuff += chr
@escapes = 4
end
@escapes = 0 if @escapes == 3
@escapes = 3 if @escapes == 4
@ebuff = '' if @escapes == 0
elsif @escapes == 5
if chr == 'H'
route_key :home
elsif chr == 'F'
route_key :end
elsif chr == 'Q'
route_key :f2
elsif chr == 'R'
route_key :f3
elsif chr == 'S'
route_key :f4
else
raise "escape 5 #{chr.inspect}"
end
@escapes = 0
else
@escapes = 0
end
end
@driver.flush
rescue Errno::EAGAIN
rescue EOFError
end