123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844(*
* uTop.ml
* -------
* Copyright : (c) 2011, Jeremie Dimino <jeremie@dimino.org>
* Licence : BSD3
*
* This file is a part of utop.
*)[@@@warning"-27"]openLwt_reactopenLTerm_textopenLTerm_geomopenLTerm_stylelet(>>=)=Lwt.(>>=)moduleString_set=Set.Make(String)letversion="2.12.0"(* +-----------------------------------------------------------------+
| History |
+-----------------------------------------------------------------+ *)lethistory=LTerm_history.create[]lethistory_file_name =ref(Some(Filename.concatLTerm_resources.home".utop-history"))lethistory_file_max_size=refNonelethistory_file_max_entries =refNoneletstashable_session_history =UTop_history.create()(* +-----------------------------------------------------------------+
| Hooks |
+-----------------------------------------------------------------+ *)letnew_command_hooks=LTerm_dlist.create()letat_new_commandf=ignore(LTerm_dlist.add_lfnew_command_hooks)(* +-----------------------------------------------------------------+
| Config |
+-----------------------------------------------------------------+ *)typeui=UTop_private.ui=Console|Emacsletget_ui()=S.value UTop_private.uitypeprofile=Dark|Lightletprofile,set_profile =S.createDarkletset_profile p=set_profilepletsize=UTop_private.sizeletkey_sequence=UTop_private.key_sequenceletcount=UTop_private.countlettime=ref(Unix.time())let()=at_new_command (fun()->time:=Unix.time())letmake_variable?eqx=letsignal,set=S.create?eqxinletsetv=setvin(signal,(fun()->S.valuesignal),set)lethide_reserved,get_hide_reserved,set_hide_reserved=make_variabletrueletcreate_implicits,get_create_implicits,set_create_implicits=make_variablefalseletshow_box,get_show_box,set_show_box =make_variable trueletphrase_terminator,get_phrase_terminator,set_phrase_terminator =make_variable";;"letauto_run_lwt,get_auto_run_lwt,set_auto_run_lwt=make_variabletrueletauto_run_async,get_auto_run_async,set_auto_run_async=make_variabletruelettopfind_verbose,get_topfind_verbose,set_topfind_verbose=make_variablefalseletexternal_editor,get_external_editor,set_external_editor=make_variable(trySys.getenv"EDITOR"withNot_found ->"vi")(* Ugly hack until the action system of lambda-term is improved *)letend_and_accept_current_phrase:LTerm_read_line.action=Edit(Custom(fun()->assertfalse))letset_margin_functionf=UTop_private.set_margin_function f(* +-----------------------------------------------------------------+
| Keywords |
+-----------------------------------------------------------------+ *)letdefault_keywords=["and";"as";"assert";"begin";"class";"constraint";"do";"done";"downto";"else";"end";"exception";"external";"for";"fun";"function";"functor";"if";"in";"include";"inherit";"initializer";"lazy";"let";"match";"method";"module";"mutable";"new";"object";"of";"open";"private";"rec";"sig";"struct";"then";"to";"try";"type";"val";"virtual";"when";"while";"with";"try_lwt";"finally";"for_lwt";"lwt";]letkeywords=ref(String_set.of_listdefault_keywords)letadd_keywordkwd=keywords:=String_set.addkwd!keywords(* +-----------------------------------------------------------------+
| Span of Lines |
+-----------------------------------------------------------------+ *)typelines={start:int;stop:int;}(* +-----------------------------------------------------------------+
| Error reporting |
+-----------------------------------------------------------------+ *)letget_messagefuncx=letbuffer=Buffer.create1024inletpp=Format.formatter_of_bufferbufferinUTop_private.set_marginpp;funcppx;Format.pp_print_flushpp();Buffer.contentsbufferletget_ocaml_error_message exn=letbuffer=Buffer.create1024inletpp=Format.formatter_of_bufferbufferinUTop_private.set_marginpp;Errors.report_errorppexn;Format.pp_print_flush pp();letstr=Buffer.contentsbufferintryScanf.sscanfstr"Characters %d-%d:\n%[\000-\255]"(funstartstopmsg->((start,stop),msg,None))withScanf.Scan_failure(_)->tryScanf.sscanfstr"Line %d, characters %d-%d:\n%[\000-\255]"(funlinestartstopmsg->((start,stop),msg,Some{start=line;stop=line}))withScanf.Scan_failure(_)->tryScanf.sscanfstr"Lines %d-%d, characters %d-%d:\n%[\000-\255]"(funstart_linestop_linestartstopmsg->((start,stop),msg,Some{start=start_line;stop=stop_line}))withScanf.Scan_failure(_)->((0,0),str,None)letcollect_formattersbufppsf=(* First flush all formatters. *)List.iter(funpp->Format.pp_print_flushpp())pps;(* Saveall formatter functions. *)letsave=List.map(funpp->Format.pp_get_formatter_out_functionspp())ppsinletrestore()=List.iter2(funppout_functions ->Format.pp_print_flush pp();Format.pp_set_formatter_out_functions ppout_functions)ppssavein(* Outputfunctions. *)letout_functions=letppb=Format.formatter_of_bufferbufinFormat.pp_get_formatter_out_functionsppb()in(* Replace formatter functions. *)List.iter(funpp->UTop_private.set_marginpp;Format.pp_set_formatter_out_functionsppout_functions)pps;trylet x=f()inrestore();xwithexn->restore();raiseexnlet discard_formattersppsf=(* First flush all formatters. *)List.iter(funpp->Format.pp_print_flushpp())pps;(* Saveall formatter functions. *)letsave=List.map(funpp->Format.pp_get_formatter_out_functionspp())ppsinletrestore()=List.iter2(funppout_functions ->Format.pp_print_flush pp();Format.pp_set_formatter_out_functions ppout_functions)ppssavein(* Outputfunctions. *)letout_functions={Format.out_string =(fun___->());out_flush=ignore;out_newline=ignore;out_spaces=ignore;out_indent=ignore}in(* Replace formatter functions. *)List.iter(funpp->Format.pp_set_formatter_out_functionsppout_functions)pps;tryletx=f()inrestore();xwithexn->restore();raiseexn(* +-----------------------------------------------------------------+
| Parsing |
+-----------------------------------------------------------------+ *)typelocation=int*inttype'aresult=|Valueof'a|Erroroflocationlist*stringexception Need_moreletinput_name="//toplevel//"letlexbuf_of_stringeofstr=letpos=ref0inletlexbuf=Lexing.from_function(funbuflen->if!pos=String.lengthstrthenbegineof:=true;0endelsebeginletlen=minlen(String.lengthstr-!pos)inString.blitstr!posbuf0len;pos:=!pos +len;lenend)inLocation.initlexbufinput_name;lexbufletmklocloc=(loc.Location.loc_start.Lexing.pos_cnum,loc.Location.loc_end.Lexing.pos_cnum)letparse_defaultparsestreos_is_error=leteof=reffalseinletlexbuf=lexbuf_of_stringeofstrintry(* Try to parse the phrase. *)letphrase=parselexbufinValuephrasewith|_when!eof&¬eos_is_error->(* This is not an error, we just need more input. *)raiseNeed_more|End_of_file->(* If the string is empty, do not report an error. *)raiseNeed_more|Lexer.Error(error,loc)->(matchLocation.error_of_exn(Lexer.Error(error,loc))with|Some(`Okerror)->Error([mklocloc],get_messageLocation.print_reporterror)|_->raiseNeed_more)|Syntaxerr.Errorerror->beginmatcherrorwith|Syntaxerr.Unclosed(opening_loc,opening,closing_loc,closing)->Error([mklocopening_loc;mklocclosing_loc],Printf.sprintf"Syntax error: '%s' expected, the highlighted '%s' might be unmatched"closingopening)|Syntaxerr.Applicative_path loc->Error([mkloc loc],"Syntax error: applicative paths of the form F(X).t are not supported when the option -no-app-funct is set.")|Syntaxerr.Otherloc->Error([mkloc loc],"Syntax error")|Syntaxerr.Expecting(loc,nonterm)->Error([mklocloc],Printf.sprintf"Syntax error: %s expected."nonterm)|Syntaxerr.Variable_in_scope(loc,var)->Error([mkloc loc],Printf.sprintf"In this scoped type, variable '%s is reserved for the local type %s."varvar)|Syntaxerr.Not_expecting (loc,nonterm)->Error([mklocloc],Printf.sprintf"Syntax error: %s not expected"nonterm)|Syntaxerr.Ill_formed_ast(loc,s)->Error([mklocloc],Printf.sprintf"Error: broken invariant in parsetree: %s"s)|Syntaxerr.Invalid_package_type(loc,s)->Error([mklocloc],Printf.sprintf"Invalid package type: %s"s)#ifOCAML_VERSION>=(5,0,0)|Syntaxerr.Removed_string_setloc->Error([mklocloc],"Syntax error: strings are immutable, there is no assignment \
syntax for them.\n\
Hint: Mutable sequences of bytes are available in the Bytes module.\n\
Hint: Did you mean to use 'Bytes.set'?")#endifend|Syntaxerr.Escape_error|Parsing.Parse_error->Error([mkloc(Location.currlexbuf)],"Syntax error")|exn->Error([],"Unknown parsing error (please report it to the utop project): "^Printexc.to_stringexn)letparse_toplevel_phrase_default=parse_defaultParse.toplevel_phraseletparse_toplevel_phrase=refparse_toplevel_phrase_defaultletparse_use_file_default=parse_defaultParse.use_fileletparse_use_file =refparse_use_file_default(* +-----------------------------------------------------------------+
| Safety checking |
+-----------------------------------------------------------------+ *)letnull=Format.make_formatter(funstrofslen->())ignoreletreclast headtail =match tailwith|[]->head|head::tail->lastheadtailletwith_loclocstr={Location.txt=str;Location.loc=loc;}(* Check that the given phrase can be evaluated without typing/compile
errors. *)letcheck_phrasephrase=letopenParsetreeinmatchphrasewith|Ptop_dir_->None|Ptop_def[]->None|Ptop_def(item::items)->letloc={Location.loc_start=item.pstr_loc.Location.loc_start;Location.loc_end=(lastitemitems).pstr_loc.Location.loc_end;Location.loc_ghost=false;}in(* Backup. *)letsnap=Btype.snapshot()inletenv=!Toploop.toplevel_env in(* Construct "let _ () = let module _ = struct <items> end in ()" in order to test
the typing and compilation of [items] without evaluating them. *)letunit=with_locloc(Longident.Ldot(Lident"Unit","()"))inlettop_def=letopenAst_helperinwith_default_locloc(fun()->Str.eval(Exp.fun_NolabelNone(Pat.constructunitNone)(Exp.letmodule(with_loc loc#ifOCAML_VERSION >= (4,10,0)(Some"_")#else"_"#endif)(Mod.structure (item::items))(Exp.constructunitNone))))inletcheck_phrase =Ptop_def[top_def]intrylet_=discard_formatters[Format.err_formatter](fun()->Env.reset_cache_toplevel ();Toploop.execute_phrase falsenullcheck_phrase)in(* The phrase is safe. *)Toploop.toplevel_env := env;Btype.backtracksnap;Nonewithexn->(* The phrase contains errors. *)let loc,msg,line=get_ocaml_error_messageexninToploop.toplevel_env := env;Btype.backtracksnap;Some([loc],msg,[line])(* +-----------------------------------------------------------------+
| Prompt |
+-----------------------------------------------------------------+ *)letmake_prompt uiprofile countsizekey_sequence (recording,macro_count,macro_counter)=let tm=Unix.localtime !timeinletcolordarklight=matchprofilewith|Dark->dark|Light->lightinmatchuiwith|Emacs->[||]|Console->letbold=profile=Darkinlettxta=ifkey_sequence =[]theneval[B_boldbold;B_fg(colorlcyanblue);S"─( ";B_fg(colorlmagentamagenta);S(Printf.sprintf "%02d:%02d:%02d"tm.Unix.tm_hourtm.Unix.tm_mintm.Unix.tm_sec);E_fg;S" )─< ";B_fg(colorlyellowyellow);S(Printf.sprintf "command %d"count);E_fg;S" >─";]elseeval[B_boldbold;B_fg(colorlcyanblue);S"─( ";B_fg(colorlmagentamagenta);S(Printf.sprintf "%02d:%02d:%02d"tm.Unix.tm_hourtm.Unix.tm_mintm.Unix.tm_sec);E_fg;S" )─< ";B_fg(colorlyellowyellow);S(Printf.sprintf "command %d"count);E_fg;S" >─[ ";B_fg(colorlgreengreen);S(String.concat " "(List.mapLTerm_key.to_string_compact key_sequence));E_fg;S" ]─";]inlettxtb=ifrecording theneval[B_boldbold;B_fg(colorlcyanblue);S"{ ";B_fg(colorlwhiteblack);S(Printf.sprintf "counter: %d"macro_counter);E_fg;S" }─[ ";B_fg(colorlwhiteblack);S(Printf.sprintf "macro: %d"macro_count);E_fg;S" ]─";]elseeval[B_boldbold;B_fg(colorlcyanblue);S"{ ";B_fg(colorlwhiteblack);S(Printf.sprintf "counter: %d"macro_counter);E_fg;S" }─";]inletsecond_line =eval[S"\n";B_boldbold;B_fg(rgb0xe30xaa0x73);S"utop";B_fg(colorlgreengreen);S" # ";]inArray.append (ifArray.lengthtxta+Array.lengthtxtb>size.colsthenArray.sub(Array.appendtxtatxtb)0size.colselseArray.concat [txta;Array.make(size.cols-Array.lengthtxta-Array.lengthtxtb)(Zed_char.of_utf8 "\u{2500}",{nonewithforeground=Some(colorlcyanblue);bold=Somebold});txtb;])second_lineletdefault_prompt =S.l6make_promptUTop_private.uiprofilecountsizekey_sequence(S.l3(funxyz->(x,y,z))(Zed_macro.recording LTerm_read_line.macro)(Zed_macro.countLTerm_read_line.macro)(Zed_macro.counter LTerm_read_line.macro))letprompt =refdefault_promptletedit_mode=refLTerm_editor.Defaultletdefault_info ={Toploop.section="UTop";doc="";(* TODO: have some kind of documentation *)}let()=Toploop.add_directive "utop_prompt_simple"(Toploop.Directive_none(fun()->prompt:=S.map(Printf.ksprintf LTerm_text.of_utf8 "utop [%d]: ")count))default_info;Toploop.add_directive "utop_prompt_dummy"(Toploop.Directive_none(fun()->prompt:=S.const(LTerm_text.of_utf8"# ")))default_info;Toploop.add_directive "utop_prompt_fancy_light"(Toploop.Directive_none(fun()->set_profileLight;prompt:=default_prompt))default_info;Toploop.add_directive "utop_prompt_fancy_dark"(Toploop.Directive_none(fun()->set_profileDark;prompt:=default_prompt))default_info;Toploop.add_directive "edit_mode_default"(Toploop.Directive_none(fun()->edit_mode:=LTerm_editor.Default))default_info;Toploop.add_directive "edit_mode_vi"(Toploop.Directive_none(fun()->edit_mode:=LTerm_editor.Vi))default_info(* +-----------------------------------------------------------------+
| Help |
+-----------------------------------------------------------------+ *)moduleBindings=Zed_input.Make(LTerm_key)moduleKeys_map=Map.Make(structtypet=LTerm_key.tlistletcompare =compare end)letname_of_action action =ifaction ==end_and_accept_current_phrasethen"end-and-accept-current-phrase"elseLTerm_read_line.name_of_action actionletdoc_of_action action =ifaction ==end_and_accept_current_phrasethen"end the current phrase with the phrase terminator (;;) and evaluate it"elseLTerm_read_line.doc_of_action actionlet()=Toploop.add_directive "utop_help"(Toploop.Directive_none(fun()->print_endline "If you can't see the prompt properly try: #utop_prompt_simple
utop defines the following directives:
#help : list all directives
#utop_bindings : list all the current key bindings
#utop_macro : display the currently recorded macro
#utop_stash : store all the valid commands from your current session in a file
#utop_save : store the current session with a simple prompt in a file
#topfind_log : display messages recorded from findlib since the beginning of the session
#topfind_verbose : enable/disable topfind verbosity
For a complete description of utop, look at the utop(1) manual page."))default_info;Toploop.add_directive "utop_bindings"(Toploop.Directive_none(fun()->letmake_lineskeysactions acc=matchactionswith|[]->(String.concat " "(List.mapLTerm_key.to_string_compactkeys),"","does nothing"):: acc|action ::actions ->letrecloopactions acc=matchactionswith|[]->acc|action ::actions ->loopactions(("",name_of_actionaction,doc_of_actionaction):: acc)inloopactions((String.concat " "(List.mapLTerm_key.to_string_compactkeys),name_of_actionaction,doc_of_actionaction):: acc)inletbindings =Bindings.fold(funkeyactions map->Keys_map.add key(List.map(funaction ->(LTerm_read_line.Editaction))actions)map)!LTerm_edit.bindings Keys_map.emptyinletbindings =Bindings.foldKeys_map.add!LTerm_read_line.bindings bindings inlettable=List.rev(Keys_map.fold(funkeysaction acc->make_lineskeysaction acc)bindings [])inletsize_key,size_name,size_doc =List.fold_left(fun(size_key,size_name,size_doc)(key,name,doc)->(max(String.length key)size_key,max(String.lengthname)size_name,max(String.length doc)size_doc))(0,0,0)tableinlet buf=Buffer.create128inletformat_line(key,name,doc)=Buffer.clearbuf;Buffer.add_stringbuf key;whileBuffer.lengthbuf<size_keydoBuffer.add_char buf' 'done;Buffer.add_string buf" : ";Buffer.add_stringbufname;whileBuffer.lengthbuf<size_key+size_name+3doBuffer.add_char buf' 'done;Buffer.add_string buf" -> ";Buffer.add_stringbuf doc;Buffer.add_char buf'\n';output_string stdout (Buffer.contents buf)inList.iterformat_line table;flushstdout))default_info;Toploop.add_directive "utop_macro"(Toploop.Directive_none(fun()->letmacro=Zed_macro.contentsLTerm_read_line.macroinList.iter(funaction ->output_string stdout (name_of_actionaction);output_char stdout '\n')macro;flushstdout))default_infolet()=Toploop.add_directive "pwd"(Toploop.Directive_none(fun()->print_endline (Sys.getcwd ())))default_infoletmake_stash_directive entry_formatter fname=ifget_ui()=Emacsthenprint_endline "Stashing is currently not supported in Emacs"elseletentries =UTop_history.contents stashable_session_historyin(* remove the stash directive from its output *)letentries =matchentrieswith[]->[]|_::e->einletentries =List.reventries inPrintf.printf "Stashing %d entries in %s ... "(List.lengthentries)fname;trylet oc=open_out fnameintryList.iter(fune->letline=entry_formattereinoutput_string ocline;output_char oc'\n')entries;close_out oc;Printf.printf "Done.\n";withexn->close_out oc;raiseexnwithexn->Printf.printf "Error with file %s: %s\n"fname@@Printexc.to_stringexnlet()=let fn=make_stash_directivebeginfunction|UTop_history.Inputi->i|Outputout|Errorout|Bad_inputout|Warningsout->Printf.sprintf "(* %s *)"outendinToploop.add_directive "utop_stash"(Toploop.Directive_stringfn)default_infolet()=let fn=make_stash_directivebeginfunction|UTop_history.Inputi|Bad_inputi->Printf.sprintf "#%s"i|Outputout|Errorout|Warningsout->outendinToploop.add_directive "utop_save"(Toploop.Directive_stringfn)default_info(* +-----------------------------------------------------------------+
| Findlib stuff |
+-----------------------------------------------------------------+ *)letprint_error msg=Lazy.forceLTerm.stdout>>=funterm->LTerm.set_styleterm!UTop_private.error_style>>=fun()->Lwt_io.printmsg>>=fun()->LTerm.set_styletermLTerm_style.none>>=fun()->LTerm.flushtermlethandle_findlib_error =function|Failuremsg->Lwt_main.run(print_errormsg)|Fl_package_base.No_such_package(pkg,reason)->Lwt_main.run(print_error(Printf.sprintf"No such package: %s%s\n"pkg(ifreason <>""then"- "^reasonelse"")))|Fl_package_base.Package_looppkg->Lwt_main.run(print_error(Printf.sprintf"Package requires itself: %s\n"pkg))|exn->raiseexnlettopfind_log,set_topfind_log =S.create ~eq:(fun__->false)[]let()=letreal_log =!Topfind.loginTopfind.log :=fun str->set_topfind_log(str::S.valuetopfind_log);ifS.valuetopfind_verbosethenreal_log strlet()=Toploop.add_directive"topfind_log"(Toploop.Directive_none(fun()->List.iter(fun str->print_stringstr;print_char '\n')(S.valuetopfind_log);flushstdout))default_info;Toploop.add_directive"topfind_verbose"(Toploop.Directive_boolset_topfind_verbose)default_infoletsplit_words str=let len=String.lengthstrinletis_sep =function|' '|'\t'|'\r'|'\n'|','->true|_->falseinletrecskipacci=ifi=lenthenaccelseifis_sep str.[i]thenskipacc(i+1)elseextractacci(i+1)andextractaccij=ifj=lenthen(String.substri(j-i)):: accelseifis_sep str.[j]thenskip(String.substri(j-i):: acc)(j+1)elseextractacci(j+1)inList.rev(skip[]0)letrequire packages =tryleteff_packages =Findlib.package_deep_ancestors !Topfind.predicates packages inTopfind.loadeff_packageswithexn->handle_findlib_errorexnlet()=Toploop.add_directive"require"(Toploop.Directive_string(fun str->require(split_wordsstr)))default_info(* +-----------------------------------------------------------------+
| Backports |
+-----------------------------------------------------------------+ *)letuse_output command =let fn=Filename.temp_file "ocaml""_toploop.ml"inMisc.try_finally ~always:(fun()->trySys.remove fnwithSys_error_->())(fun()->matchPrintf.ksprintf Sys.command "%s > %s"command(Filename.quotefn)with|0->ignore (Toploop.use_file Format.std_formatter fn:bool)|n->Format.printf "Command exited with code %d.@."n)let()=letname="use_output"inifUTop_compat.toploop_get_directivename=NonethenToploop.add_directivename(Toploop.Directive_stringuse_output)default_info(* +-----------------------------------------------------------------+
| Initialization |
+-----------------------------------------------------------------+ *)let()=(* "utop" is an internal library so it is not passed as "-package"
to "ocamlfind ocamlmktop". *)Topfind.don't_load_deeply["utop"];Topfind.add_predicates ["byte";"toploop"];(* Add findlib path so Topfind is available and it won't be
initialized twice if the user does [#use "topfind"]. *)Topdirs.dir_directory(Findlib.package_directory"findlib");(* Make UTop accessible. *)Topdirs.dir_directory(Findlib.package_directory"utop")(* +-----------------------------------------------------------------+
| Compiler-libs re-exports |
+-----------------------------------------------------------------+ *)letget_load_path ()=Load_path.get_paths ()letset_load_path =UTop_compat.set_load_path(* +-----------------------------------------------------------------+
| Deprecated |
+-----------------------------------------------------------------+ *)letsmart_accept =reftrueletnew_prompt_hooks =LTerm_dlist.create ()letat_new_promptf=ignore (LTerm_dlist.add_lfnew_prompt_hooks)letprompt_continue =ref(S.const[||])letprompt_comment =ref(S.const[||])