Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file console.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245includeConsole_intf(** Color printing in terminals *)openCoreopenPolymoduleMake(Io:Io)=struct(* http://www.termsys.demon.co.uk/vtansi.htm *)moduleAnsi=structletkill_line()=Io.print_string"\027[2K"leterase_to_end_of_screen()=Io.print_string"\027[J"leterase_to_start_of_screen()=Io.print_string"\027[1J"leterase_all()=Io.print_string"\027[2J"letbell()=Io.print_string"\007"lethome_cursor()=Io.print_string"\027[0G"letcursor_up()=Io.print_string"\027[A"letcursor_down()=Io.print_string"\027[B"letcursor_backward()=Io.print_string"\027[D"letcursor_forward()=Io.print_string"\027[C"letsave_cursor()=Io.print_string"\027[s"letunsave_cursor()=Io.print_string"\027[u"moduleAll_attr=Ansi_kernel.With_all_attrsmoduleAttr=Ansi_kernel.Attrtypeattr=Attr.tletstring_with_attrstylestring=ifstyle=[]thenstringelseString.concat[All_attr.list_to_string(style:>All_attr.tlist);string;All_attr.list_to_string[`Reset]];;letoutput(style:attrlist)ocsstartlen=letopenIo.Let_syntaxinlet%bindcapable=Io.capable()inifcapable&&style<>[]then(Io.output_stringoc(All_attr.list_to_string(style:>All_attr.tlist));Io.outputoc~buf:s~pos:start~len;Io.output_stringoc(All_attr.list_to_string[`Reset]);Io.flushoc)elseIo.return(Io.outputoc~buf:s~pos:start~len);;letoutput_string(style:attrlist)ocs=letopenIo.Let_syntaxinlet%bindcapable=Io.capable()inifcapable&&style<>[]then(Io.output_stringoc(All_attr.list_to_string(style:>All_attr.tlist));Io.output_stringocs;Io.output_stringoc(All_attr.list_to_string[`Reset]);Io.flushoc)elseIo.return(Io.output_stringocs);;leteprintfstylefmt=Io.fprintf~attrs:(All_attr.list_to_string(style:>All_attr.tlist))Io.stderrfmt;;letprintfstylefmt=Io.fprintf~attrs:(All_attr.list_to_string(style:>All_attr.tlist))Io.stdoutfmt;;endletis_color_tty()=Io.capable()moduleColumnize(In:sigtypetvallength:t->intend):sigvaliter:middle:(sep:In.t->In.t->int->unitIo.t)->last:(In.t->int->unitIo.t)->sep:In.t->In.tlist->int->unitIo.tend=structletlinescolumnsa=((Array.lengtha-1)/columns)+1(** Size of an array printed out with this column configuration
(lines*chars per column)
*)letdimcolumnsa=letlines=linescolumnsainletrecloopcntcurrentacc=ifcnt=Array.lengthathenList.rev(current::acc)elseifcntmodlines=0thenloop(cnt+1)(In.lengtha.(cnt))(current::acc)elseloop(cnt+1)(max(In.lengtha.(cnt))current)accinlines,loop1(In.lengtha.(0))[];;letrecline_len~sep_lenacc=function|[]->acc|[v]->acc+v|h::t->line_len~sep_len(acc+sep_len+h)t;;letfind_dim~sep_lenamax_len=letreclooplinescolscnt=letnlines,ncols=dim(cnt+1)ainifnlines>lines||lines=1(* we are not gaining in vertical space anymore *)||line_len~sep_len0ncols>max_len(* we are overflowing *)thenArray.of_listcolselseloopnlinesncols(cnt+1)inletlines,cols=dim1ainlooplinescols1;;letcolumnizeacolumns=letlines=linescolumnsainletres=ref[]infori=lines-1downto0doletline_acc=ref[]inforj=columns-1downto0doletpos=i+(j*lines)inifpos<Array.lengthathenline_acc:=a.(pos)::!line_accdone;res:=!line_acc::!resdone;!res;;letrecfold_line~middle~lastsepaccpaddingline=letopenIo.Let_syntaxinmatchline,paddingwith|[v],len::_->last~accv(len-In.lengthv)|h::t,len::tlen->let%bind()=middle~acc~seph(len-In.lengthh)infold_line~middle~lastsepacctlent|_->assertfalse;;letfold~init~middle~last~seplmax_len=ifl=[]thenIo.returninitelse(leta=Array.of_listlinletcolumns=find_dima~sep_len:(In.lengthsep)max_leninletres=columnizea(Array.lengthcolumns)inIo.fold_leftres~f:(funaccline->fold_line~middle~lastsepacc(Array.to_listcolumns)line)~init);;letiter~middle~last=fold~init:()~last:(fun~acc:()->last)~middle:(fun~acc:()->middle);;endletwidth()=letopenIo.Let_syntaxinmatchLinux_ext.get_terminal_sizewith|Result.Error_->Io.return`Not_available|Result.Okget_size->if%mapIo.stdout_isatty()then`Cols(snd(get_size`Controlling))else`Not_a_tty;;letprint_listocl:unitIo.t=letopenIo.Let_syntaxinmatch%bind(width():>[`Colsofint|`Not_a_tty|`Not_available]Io.t)with|`Not_a_tty|`Not_available->List.iterl~f:(fun(s,_)->Io.print_string(s^"\n"));return()|`Colscols->letprint_styled(s,style)=Ansi.output_stringstyleocsinletsep=" ",[]inletlastv_=let%map()=print_styledvinIo.output_stringoc"\n"andmiddle~sepvpad_len=let%bind()=print_styledvinIo.output_stringoc(String.makepad_len' ');print_styledsepinletmoduleCol=Columnize(structtypet=string*Ansi.attrlistletlength(s,_)=String.lengthsend)inCol.iter~sep~last~middlelcols;;endincludeMake(structincludeMonad.Identtype'afmt=('a,Out_channel.t,unit)formattypeout_channel=Out_channel.tletoutput_string=Out_channel.output_stringletoutput=Out_channel.outputletstderr=Out_channel.stderrletstdout=Out_channel.stdoutletflush=Core.Out_channel.flushletprint_string=print_string(* if it's good enough for git then it's good enough for us... *)letcapable=lazy(Unix.isattyUnix.stdout&&matchSys.getenv"TERM"with|Some"dumb"|None->false|Some_->true);;letcapable()=Lazy.forcecapableletfprintf~attrschannelfmt=ifcapable()&¬(String.is_emptyattrs)thenPrintf.fprintfchannel("%s"^^fmt^^"\027[0m%!")attrselsePrintf.fprintfchannel(fmt^^"%!");;letfold_left=List.fold_leftletstdout_isatty()=Unix.isattyUnix.stdoutend)