1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Tty_unix.mli *)letwrite(s:string):unit=letrecgoi=ifi<String.lengthsthengo(i+Unix.write_substringUnix.stdoutsi(String.lengths-i))ingo0(* the bytes waiting on stdin, none if none *)letavailable():string=letbuf=Bytes.create256inmatchUnix.readUnix.stdinbuf0256withn->Bytes.sub_stringbuf0n|exceptionUnix.Unix_error(Unix.EAGAIN,_,_)->""letrun(_caps:<Cap.stdin;Cap.stdout;..>)(p:'modelTui.program):unit=letsaved=Unix.tcgetattrUnix.stdinin(* raw: keys at once, unechoed, Control-C a key; a read returning
what is there, maybe nothing *)Unix.tcsetattrUnix.stdinUnix.TCSANOW{savedwithc_icanon=false;c_echo=false;c_isig=false;c_ixon=false;c_icrnl=false;c_vmin=0;c_vtime=0};write"\x1b[?1049h";Fun.protect~finally:(fun()->write"\x1b[0m\x1b[?25h\x1b[?1049l";Unix.tcsetattrUnix.stdinUnix.TCSANOWsaved)(fun()->letscreen=p.viewp.initinwrite(Curses.redrawscreen);letrecloop(model:'model)(shown:Curses.t)(last:float)=ifnot(p.overmodel)thenbegin(matchUnix.select[Unix.stdin][][]0.05with_->()|exceptionUnix.Unix_error(Unix.EINTR,_,_)->());letkeys=Line_discipline.split_keys(available())in(* Control-C: the program's end, in raw mode as without *)ifList.mem"\x03"keysthen()elsebeginletmodel=List.fold_left(funmk->p.update(Keyk)m)modelkeysinletnow=Unix.gettimeofday()in(* a pause (the process stopped, Control-Z) isn't time played *)letmodel=p.update(Tick(Float.min0.25(now-.last)))modelinletnext=p.viewmodelinwrite(Curses.refresh~before:shownnext);loopmodelnextnowendendinloopp.initscreen(Unix.gettimeofday()))