123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971(*
* lTerm_unix.ml
* -------------
* Copyright : (c) 2011, Jeremie Dimino <jeremie@dimino.org>
* Licence : BSD3
*
* This file is a part of Lambda-Term.
*)openCamomileLibraryDefault.CamomileopenLTerm_keyletreturn,(>>=),(>|=)=Lwt.return,Lwt.(>>=),Lwt.(>|=)externalget_sigwinch:unit->intoption="lt_unix_get_sigwinch"externalget_system_encoding:unit->string="lt_unix_get_system_encoding"letsigwinch=get_sigwinch()(* Obtained by running the folliwing makefile in the "localedata"
directory of the glibc:
{[
include SUPPORTED
all:
@echo $(SUPPORTED-LOCALES) | sed 's/ /\n/g' | awk -F/ '$$1 ~ /[.]/ { next; }; { print " | \""$$1"\" -> \""$$2"\"" }'
]}
*)letencoding_of_lang=function|"aa_DJ"->"ISO-8859-1"|"aa_ER"->"UTF-8"|"aa_ER@saaho"->"UTF-8"|"aa_ET"->"UTF-8"|"af_ZA"->"ISO-8859-1"|"am_ET"->"UTF-8"|"an_ES"->"ISO-8859-15"|"ar_AE"->"ISO-8859-6"|"ar_BH"->"ISO-8859-6"|"ar_DZ"->"ISO-8859-6"|"ar_EG"->"ISO-8859-6"|"ar_IN"->"UTF-8"|"ar_IQ"->"ISO-8859-6"|"ar_JO"->"ISO-8859-6"|"ar_KW"->"ISO-8859-6"|"ar_LB"->"ISO-8859-6"|"ar_LY"->"ISO-8859-6"|"ar_MA"->"ISO-8859-6"|"ar_OM"->"ISO-8859-6"|"ar_QA"->"ISO-8859-6"|"ar_SA"->"ISO-8859-6"|"ar_SD"->"ISO-8859-6"|"ar_SY"->"ISO-8859-6"|"ar_TN"->"ISO-8859-6"|"ar_YE"->"ISO-8859-6"|"az_AZ"->"UTF-8"|"as_IN"->"UTF-8"|"ast_ES"->"ISO-8859-15"|"be_BY"->"CP1251"|"be_BY@latin"->"UTF-8"|"bem_ZM"->"UTF-8"|"ber_DZ"->"UTF-8"|"ber_MA"->"UTF-8"|"bg_BG"->"CP1251"|"bn_BD"->"UTF-8"|"bn_IN"->"UTF-8"|"bo_CN"->"UTF-8"|"bo_IN"->"UTF-8"|"br_FR"->"ISO-8859-1"|"br_FR@euro"->"ISO-8859-15"|"bs_BA"->"ISO-8859-2"|"byn_ER"->"UTF-8"|"ca_AD"->"ISO-8859-15"|"ca_ES"->"ISO-8859-1"|"ca_ES@euro"->"ISO-8859-15"|"ca_FR"->"ISO-8859-15"|"ca_IT"->"ISO-8859-15"|"crh_UA"->"UTF-8"|"cs_CZ"->"ISO-8859-2"|"csb_PL"->"UTF-8"|"cv_RU"->"UTF-8"|"cy_GB"->"ISO-8859-14"|"da_DK"->"ISO-8859-1"|"de_AT"->"ISO-8859-1"|"de_AT@euro"->"ISO-8859-15"|"de_BE"->"ISO-8859-1"|"de_BE@euro"->"ISO-8859-15"|"de_CH"->"ISO-8859-1"|"de_DE"->"ISO-8859-1"|"de_DE@euro"->"ISO-8859-15"|"de_LU"->"ISO-8859-1"|"de_LU@euro"->"ISO-8859-15"|"dv_MV"->"UTF-8"|"dz_BT"->"UTF-8"|"el_GR"->"ISO-8859-7"|"el_CY"->"ISO-8859-7"|"en_AG"->"UTF-8"|"en_AU"->"ISO-8859-1"|"en_BW"->"ISO-8859-1"|"en_CA"->"ISO-8859-1"|"en_DK"->"ISO-8859-1"|"en_GB"->"ISO-8859-1"|"en_HK"->"ISO-8859-1"|"en_IE"->"ISO-8859-1"|"en_IE@euro"->"ISO-8859-15"|"en_IN"->"UTF-8"|"en_NG"->"UTF-8"|"en_NZ"->"ISO-8859-1"|"en_PH"->"ISO-8859-1"|"en_SG"->"ISO-8859-1"|"en_US"->"ISO-8859-1"|"en_ZA"->"ISO-8859-1"|"en_ZM"->"UTF-8"|"en_ZW"->"ISO-8859-1"|"es_AR"->"ISO-8859-1"|"es_BO"->"ISO-8859-1"|"es_CL"->"ISO-8859-1"|"es_CO"->"ISO-8859-1"|"es_CR"->"ISO-8859-1"|"es_DO"->"ISO-8859-1"|"es_EC"->"ISO-8859-1"|"es_ES"->"ISO-8859-1"|"es_ES@euro"->"ISO-8859-15"|"es_GT"->"ISO-8859-1"|"es_HN"->"ISO-8859-1"|"es_MX"->"ISO-8859-1"|"es_NI"->"ISO-8859-1"|"es_PA"->"ISO-8859-1"|"es_PE"->"ISO-8859-1"|"es_PR"->"ISO-8859-1"|"es_PY"->"ISO-8859-1"|"es_SV"->"ISO-8859-1"|"es_US"->"ISO-8859-1"|"es_UY"->"ISO-8859-1"|"es_VE"->"ISO-8859-1"|"et_EE"->"ISO-8859-1"|"eu_ES"->"ISO-8859-1"|"eu_ES@euro"->"ISO-8859-15"|"fa_IR"->"UTF-8"|"ff_SN"->"UTF-8"|"fi_FI"->"ISO-8859-1"|"fi_FI@euro"->"ISO-8859-15"|"fil_PH"->"UTF-8"|"fo_FO"->"ISO-8859-1"|"fr_BE"->"ISO-8859-1"|"fr_BE@euro"->"ISO-8859-15"|"fr_CA"->"ISO-8859-1"|"fr_CH"->"ISO-8859-1"|"fr_FR"->"ISO-8859-1"|"fr_FR@euro"->"ISO-8859-15"|"fr_LU"->"ISO-8859-1"|"fr_LU@euro"->"ISO-8859-15"|"fur_IT"->"UTF-8"|"fy_NL"->"UTF-8"|"fy_DE"->"UTF-8"|"ga_IE"->"ISO-8859-1"|"ga_IE@euro"->"ISO-8859-15"|"gd_GB"->"ISO-8859-15"|"gez_ER"->"UTF-8"|"gez_ER@abegede"->"UTF-8"|"gez_ET"->"UTF-8"|"gez_ET@abegede"->"UTF-8"|"gl_ES"->"ISO-8859-1"|"gl_ES@euro"->"ISO-8859-15"|"gu_IN"->"UTF-8"|"gv_GB"->"ISO-8859-1"|"ha_NG"->"UTF-8"|"he_IL"->"ISO-8859-8"|"hi_IN"->"UTF-8"|"hne_IN"->"UTF-8"|"hr_HR"->"ISO-8859-2"|"hsb_DE"->"ISO-8859-2"|"ht_HT"->"UTF-8"|"hu_HU"->"ISO-8859-2"|"hy_AM"->"UTF-8"|"id_ID"->"ISO-8859-1"|"ig_NG"->"UTF-8"|"ik_CA"->"UTF-8"|"is_IS"->"ISO-8859-1"|"it_CH"->"ISO-8859-1"|"it_IT"->"ISO-8859-1"|"it_IT@euro"->"ISO-8859-15"|"iu_CA"->"UTF-8"|"iw_IL"->"ISO-8859-8"|"ka_GE"->"GEORGIAN-PS"|"kk_KZ"->"PT154"|"kl_GL"->"ISO-8859-1"|"km_KH"->"UTF-8"|"kn_IN"->"UTF-8"|"kok_IN"->"UTF-8"|"ks_IN"->"UTF-8"|"ks_IN@devanagari"->"UTF-8"|"ku_TR"->"ISO-8859-9"|"kw_GB"->"ISO-8859-1"|"ky_KG"->"UTF-8"|"lb_LU"->"UTF-8"|"lg_UG"->"ISO-8859-10"|"li_BE"->"UTF-8"|"li_NL"->"UTF-8"|"lij_IT"->"UTF-8"|"lo_LA"->"UTF-8"|"lt_LT"->"ISO-8859-13"|"lv_LV"->"ISO-8859-13"|"mai_IN"->"UTF-8"|"mg_MG"->"ISO-8859-15"|"mhr_RU"->"UTF-8"|"mi_NZ"->"ISO-8859-13"|"mk_MK"->"ISO-8859-5"|"ml_IN"->"UTF-8"|"mn_MN"->"UTF-8"|"mr_IN"->"UTF-8"|"ms_MY"->"ISO-8859-1"|"mt_MT"->"ISO-8859-3"|"my_MM"->"UTF-8"|"nan_TW@latin"->"UTF-8"|"nb_NO"->"ISO-8859-1"|"nds_DE"->"UTF-8"|"nds_NL"->"UTF-8"|"ne_NP"->"UTF-8"|"nl_AW"->"UTF-8"|"nl_BE"->"ISO-8859-1"|"nl_BE@euro"->"ISO-8859-15"|"nl_NL"->"ISO-8859-1"|"nl_NL@euro"->"ISO-8859-15"|"nn_NO"->"ISO-8859-1"|"nr_ZA"->"UTF-8"|"nso_ZA"->"UTF-8"|"oc_FR"->"ISO-8859-1"|"om_ET"->"UTF-8"|"om_KE"->"ISO-8859-1"|"or_IN"->"UTF-8"|"os_RU"->"UTF-8"|"pa_IN"->"UTF-8"|"pa_PK"->"UTF-8"|"pap_AN"->"UTF-8"|"pl_PL"->"ISO-8859-2"|"ps_AF"->"UTF-8"|"pt_BR"->"ISO-8859-1"|"pt_PT"->"ISO-8859-1"|"pt_PT@euro"->"ISO-8859-15"|"ro_RO"->"ISO-8859-2"|"ru_RU"->"ISO-8859-5"|"ru_UA"->"KOI8-U"|"rw_RW"->"UTF-8"|"sa_IN"->"UTF-8"|"sc_IT"->"UTF-8"|"sd_IN"->"UTF-8"|"sd_IN@devanagari"->"UTF-8"|"se_NO"->"UTF-8"|"shs_CA"->"UTF-8"|"si_LK"->"UTF-8"|"sid_ET"->"UTF-8"|"sk_SK"->"ISO-8859-2"|"sl_SI"->"ISO-8859-2"|"so_DJ"->"ISO-8859-1"|"so_ET"->"UTF-8"|"so_KE"->"ISO-8859-1"|"so_SO"->"ISO-8859-1"|"sq_AL"->"ISO-8859-1"|"sq_MK"->"UTF-8"|"sr_ME"->"UTF-8"|"sr_RS"->"UTF-8"|"sr_RS@latin"->"UTF-8"|"ss_ZA"->"UTF-8"|"st_ZA"->"ISO-8859-1"|"sv_FI"->"ISO-8859-1"|"sv_FI@euro"->"ISO-8859-15"|"sv_SE"->"ISO-8859-1"|"sw_KE"->"UTF-8"|"sw_TZ"->"UTF-8"|"ta_IN"->"UTF-8"|"te_IN"->"UTF-8"|"tg_TJ"->"KOI8-T"|"th_TH"->"TIS-620"|"ti_ER"->"UTF-8"|"ti_ET"->"UTF-8"|"tig_ER"->"UTF-8"|"tk_TM"->"UTF-8"|"tl_PH"->"ISO-8859-1"|"tn_ZA"->"UTF-8"|"tr_CY"->"ISO-8859-9"|"tr_TR"->"ISO-8859-9"|"ts_ZA"->"UTF-8"|"tt_RU"->"UTF-8"|"tt_RU@iqtelif"->"UTF-8"|"ug_CN"->"UTF-8"|"uk_UA"->"KOI8-U"|"ur_PK"->"UTF-8"|"uz_UZ"->"ISO-8859-1"|"uz_UZ@cyrillic"->"UTF-8"|"ve_ZA"->"UTF-8"|"vi_VN"->"UTF-8"|"wa_BE"->"ISO-8859-1"|"wa_BE@euro"->"ISO-8859-15"|"wae_CH"->"UTF-8"|"wo_SN"->"UTF-8"|"xh_ZA"->"ISO-8859-1"|"yi_US"->"CP1255"|"yo_NG"->"UTF-8"|"yue_HK"->"UTF-8"|"zh_CN"->"GB2312"|"zh_HK"->"BIG5-HKSCS"|"zh_SG"->"GB2312"|"zh_TW"->"BIG5"|"zu_ZA"->"ISO-8859-1"|_->"ASCII"letsystem_encoding=matchget_system_encoding()with|""->beginmatchtrySome(Sys.getenv"LANG")withNot_found->Nonewith|None->"ASCII"|Somelang->matchtrySome(String.indexlang'.')withNot_found->Nonewith|None->encoding_of_langlang|Someidx->String.sublang(idx+1)(String.lengthlang-idx-1)end|enc->enc(* +-----------------------------------------------------------------+
| Parsing of encoded characters |
+-----------------------------------------------------------------+ *)classoutput_single(cell:UChar.toptionref)=objectmethodputchar=cell:=Somecharmethodflush()=()methodclose_out()=()endletparse_charencodingstfirst_byte=letcell=refNoneinletoutput=newCharEncoding.convert_uchar_outputencoding(newoutput_singlecell)inletrecloopst=match!cellwith|Somechar->returnchar|None->Lwt_stream.nextst>>=funbyte->assert(output#output(Bytes.make1byte)01=1);output#flush();loopstinLwt.catch(fun()->assert(output#output(Bytes.make1first_byte)01=1);Lwt_stream.parsestloop)(function|CharEncoding.Malformed_code|Lwt_stream.Empty->return(UChar.of_charfirst_byte)|exn->Lwt.failexn)(* +-----------------------------------------------------------------+
| Input of escape sequence |
+-----------------------------------------------------------------+ *)exceptionNot_a_sequenceletparse_escapeescape_timest=letbuf=Buffer.create32in(* Read one character and add it to [buf]: *)letget()=Lwt.pick[Lwt_stream.getst;Lwt_unix.sleepescape_time>>=fun()->returnNone]>>=funch->matchchwith|None->(* If the rest is not immediatly available, conclude that
this is not an escape sequence but just the escape
key: *)Lwt.failNot_a_sequence|Some('\x00'..'\x1f'|'\x80'..'\xff')->(* Control characters and non-ascii characters are not part
of escape sequences. *)Lwt.failNot_a_sequence|Somech->Buffer.add_charbufch;returnchinletrecloop()=get()>>=function|'0'..'9'|';'|'['->loop()|_->return(Buffer.contentsbuf)inget()>>=function|'['|'O'->loop()|_->Lwt.failNot_a_sequence(* +-----------------------------------------------------------------+
| Escape sequences mapping |
+-----------------------------------------------------------------+ *)letcontrols=[|Char(UChar.of_char' ');Char(UChar.of_char'a');Char(UChar.of_char'b');Char(UChar.of_char'c');Char(UChar.of_char'd');Char(UChar.of_char'e');Char(UChar.of_char'f');Char(UChar.of_char'g');Char(UChar.of_char'h');Tab;Enter;Char(UChar.of_char'k');Char(UChar.of_char'l');Char(UChar.of_char'm');Char(UChar.of_char'n');Char(UChar.of_char'o');Char(UChar.of_char'p');Char(UChar.of_char'q');Char(UChar.of_char'r');Char(UChar.of_char's');Char(UChar.of_char't');Char(UChar.of_char'u');Char(UChar.of_char'v');Char(UChar.of_char'w');Char(UChar.of_char'x');Char(UChar.of_char'y');Char(UChar.of_char'z');Escape;Char(UChar.of_char'\\');Char(UChar.of_char']');Char(UChar.of_char'^');Char(UChar.of_char'_');|]letsequences=[|"[1~",{control=false;meta=false;shift=false;code=Home};"[2~",{control=false;meta=false;shift=false;code=Insert};"[3~",{control=false;meta=false;shift=false;code=Delete};"[4~",{control=false;meta=false;shift=false;code=End};"[5~",{control=false;meta=false;shift=false;code=Prev_page};"[6~",{control=false;meta=false;shift=false;code=Next_page};"[7~",{control=false;meta=false;shift=false;code=Home};"[8~",{control=false;meta=false;shift=false;code=End};"[11~",{control=false;meta=false;shift=false;code=F1};"[12~",{control=false;meta=false;shift=false;code=F2};"[13~",{control=false;meta=false;shift=false;code=F3};"[14~",{control=false;meta=false;shift=false;code=F4};"[15~",{control=false;meta=false;shift=false;code=F5};"[17~",{control=false;meta=false;shift=false;code=F6};"[18~",{control=false;meta=false;shift=false;code=F7};"[19~",{control=false;meta=false;shift=false;code=F8};"[20~",{control=false;meta=false;shift=false;code=F9};"[21~",{control=false;meta=false;shift=false;code=F10};"[23~",{control=false;meta=false;shift=false;code=F11};"[24~",{control=false;meta=false;shift=false;code=F12};"[1^",{control=true;meta=false;shift=false;code=Home};"[2^",{control=true;meta=false;shift=false;code=Insert};"[3^",{control=true;meta=false;shift=false;code=Delete};"[4^",{control=true;meta=false;shift=false;code=End};"[5^",{control=true;meta=false;shift=false;code=Prev_page};"[6^",{control=true;meta=false;shift=false;code=Next_page};"[7^",{control=true;meta=false;shift=false;code=Home};"[8^",{control=true;meta=false;shift=false;code=End};"[11^",{control=true;meta=false;shift=false;code=F1};"[12^",{control=true;meta=false;shift=false;code=F2};"[13^",{control=true;meta=false;shift=false;code=F3};"[14^",{control=true;meta=false;shift=false;code=F4};"[15^",{control=true;meta=false;shift=false;code=F5};"[17^",{control=true;meta=false;shift=false;code=F6};"[18^",{control=true;meta=false;shift=false;code=F7};"[19^",{control=true;meta=false;shift=false;code=F8};"[20^",{control=true;meta=false;shift=false;code=F9};"[21^",{control=true;meta=false;shift=false;code=F10};"[23^",{control=true;meta=false;shift=false;code=F11};"[24^",{control=true;meta=false;shift=false;code=F12};"[1$",{control=false;meta=false;shift=true;code=Home};"[2$",{control=false;meta=false;shift=true;code=Insert};"[3$",{control=false;meta=false;shift=true;code=Delete};"[4$",{control=false;meta=false;shift=true;code=End};"[5$",{control=false;meta=false;shift=true;code=Prev_page};"[6$",{control=false;meta=false;shift=true;code=Next_page};"[7$",{control=false;meta=false;shift=true;code=Home};"[8$",{control=false;meta=false;shift=true;code=End};"[1@",{control=true;meta=false;shift=true;code=Home};"[2@",{control=true;meta=false;shift=true;code=Insert};"[3@",{control=true;meta=false;shift=true;code=Delete};"[4@",{control=true;meta=false;shift=true;code=End};"[5@",{control=true;meta=false;shift=true;code=Prev_page};"[6@",{control=true;meta=false;shift=true;code=Next_page};"[7@",{control=true;meta=false;shift=true;code=Home};"[8@",{control=true;meta=false;shift=true;code=End};"[25~",{control=false;meta=false;shift=true;code=F3};"[26~",{control=false;meta=false;shift=true;code=F4};"[28~",{control=false;meta=false;shift=true;code=F5};"[29~",{control=false;meta=false;shift=true;code=F6};"[31~",{control=false;meta=false;shift=true;code=F7};"[32~",{control=false;meta=false;shift=true;code=F8};"[33~",{control=false;meta=false;shift=true;code=F9};"[34~",{control=false;meta=false;shift=true;code=F10};"[23$",{control=false;meta=false;shift=true;code=F11};"[24$",{control=false;meta=false;shift=true;code=F12};"[25^",{control=true;meta=false;shift=true;code=F3};"[26^",{control=true;meta=false;shift=true;code=F4};"[28^",{control=true;meta=false;shift=true;code=F5};"[29^",{control=true;meta=false;shift=true;code=F6};"[31^",{control=true;meta=false;shift=true;code=F7};"[32^",{control=true;meta=false;shift=true;code=F8};"[33^",{control=true;meta=false;shift=true;code=F9};"[34^",{control=true;meta=false;shift=true;code=F10};"[23@",{control=true;meta=false;shift=true;code=F11};"[24@",{control=true;meta=false;shift=true;code=F12};"[Z",{control=false;meta=false;shift=true;code=Tab};"[A",{control=false;meta=false;shift=false;code=Up};"[B",{control=false;meta=false;shift=false;code=Down};"[C",{control=false;meta=false;shift=false;code=Right};"[D",{control=false;meta=false;shift=false;code=Left};"[a",{control=false;meta=false;shift=true;code=Up};"[b",{control=false;meta=false;shift=true;code=Down};"[c",{control=false;meta=false;shift=true;code=Right};"[d",{control=false;meta=false;shift=true;code=Left};"A",{control=false;meta=false;shift=false;code=Up};"B",{control=false;meta=false;shift=false;code=Down};"C",{control=false;meta=false;shift=false;code=Right};"D",{control=false;meta=false;shift=false;code=Left};"OA",{control=false;meta=false;shift=false;code=Up};"OB",{control=false;meta=false;shift=false;code=Down};"OC",{control=false;meta=false;shift=false;code=Right};"OD",{control=false;meta=false;shift=false;code=Left};"Oa",{control=true;meta=false;shift=false;code=Up};"Ob",{control=true;meta=false;shift=false;code=Down};"Oc",{control=true;meta=false;shift=false;code=Right};"Od",{control=true;meta=false;shift=false;code=Left};"OP",{control=false;meta=false;shift=false;code=F1};"OQ",{control=false;meta=false;shift=false;code=F2};"OR",{control=false;meta=false;shift=false;code=F3};"OS",{control=false;meta=false;shift=false;code=F4};"O2P",{control=false;meta=false;shift=true;code=F1};"O2Q",{control=false;meta=false;shift=true;code=F2};"O2R",{control=false;meta=false;shift=true;code=F3};"O2S",{control=false;meta=false;shift=true;code=F4};"O3P",{control=false;meta=true;shift=false;code=F1};"O3Q",{control=false;meta=true;shift=false;code=F2};"O3R",{control=false;meta=true;shift=false;code=F3};"O3S",{control=false;meta=true;shift=false;code=F4};"O4P",{control=false;meta=true;shift=true;code=F1};"O4Q",{control=false;meta=true;shift=true;code=F2};"O4R",{control=false;meta=true;shift=true;code=F3};"O4S",{control=false;meta=true;shift=true;code=F4};"O5P",{control=true;meta=false;shift=false;code=F1};"O5Q",{control=true;meta=false;shift=false;code=F2};"O5R",{control=true;meta=false;shift=false;code=F3};"O5S",{control=true;meta=false;shift=false;code=F4};"O6P",{control=true;meta=false;shift=true;code=F1};"O6Q",{control=true;meta=false;shift=true;code=F2};"O6R",{control=true;meta=false;shift=true;code=F3};"O6S",{control=true;meta=false;shift=true;code=F4};"O7P",{control=true;meta=true;shift=false;code=F1};"O7Q",{control=true;meta=true;shift=false;code=F2};"O7R",{control=true;meta=true;shift=false;code=F3};"O7S",{control=true;meta=true;shift=false;code=F4};"O8P",{control=true;meta=true;shift=true;code=F1};"O8Q",{control=true;meta=true;shift=true;code=F2};"O8R",{control=true;meta=true;shift=true;code=F3};"O8S",{control=true;meta=true;shift=true;code=F4};"[[A",{control=false;meta=false;shift=false;code=F1};"[[B",{control=false;meta=false;shift=false;code=F2};"[[C",{control=false;meta=false;shift=false;code=F3};"[[D",{control=false;meta=false;shift=false;code=F4};"[[E",{control=false;meta=false;shift=false;code=F5};"[H",{control=false;meta=false;shift=false;code=Home};"[F",{control=false;meta=false;shift=false;code=End};"OH",{control=false;meta=false;shift=false;code=Home};"OF",{control=false;meta=false;shift=false;code=End};"H",{control=false;meta=false;shift=false;code=Home};"F",{control=false;meta=false;shift=false;code=End};"[1;2A",{control=false;meta=false;shift=true;code=Up};"[1;2B",{control=false;meta=false;shift=true;code=Down};"[1;2C",{control=false;meta=false;shift=true;code=Right};"[1;2D",{control=false;meta=false;shift=true;code=Left};"[1;3A",{control=false;meta=true;shift=false;code=Up};"[1;3B",{control=false;meta=true;shift=false;code=Down};"[1;3C",{control=false;meta=true;shift=false;code=Right};"[1;3D",{control=false;meta=true;shift=false;code=Left};"[1;4A",{control=false;meta=true;shift=true;code=Up};"[1;4B",{control=false;meta=true;shift=true;code=Down};"[1;4C",{control=false;meta=true;shift=true;code=Right};"[1;4D",{control=false;meta=true;shift=true;code=Left};"[1;5A",{control=true;meta=false;shift=false;code=Up};"[1;5B",{control=true;meta=false;shift=false;code=Down};"[1;5C",{control=true;meta=false;shift=false;code=Right};"[1;5D",{control=true;meta=false;shift=false;code=Left};"[1;6A",{control=true;meta=false;shift=true;code=Up};"[1;6B",{control=true;meta=false;shift=true;code=Down};"[1;6C",{control=true;meta=false;shift=true;code=Right};"[1;6D",{control=true;meta=false;shift=true;code=Left};"[1;7A",{control=true;meta=true;shift=false;code=Up};"[1;7B",{control=true;meta=true;shift=false;code=Down};"[1;7C",{control=true;meta=true;shift=false;code=Right};"[1;7D",{control=true;meta=true;shift=false;code=Left};"[1;8A",{control=true;meta=true;shift=true;code=Up};"[1;8B",{control=true;meta=true;shift=true;code=Down};"[1;8C",{control=true;meta=true;shift=true;code=Right};"[1;8D",{control=true;meta=true;shift=true;code=Left};"[1;2P",{control=false;meta=false;shift=true;code=F1};"[1;2Q",{control=false;meta=false;shift=true;code=F2};"[1;2R",{control=false;meta=false;shift=true;code=F3};"[1;2S",{control=false;meta=false;shift=true;code=F4};"[1;3P",{control=false;meta=true;shift=false;code=F1};"[1;3Q",{control=false;meta=true;shift=false;code=F2};"[1;3R",{control=false;meta=true;shift=false;code=F3};"[1;3S",{control=false;meta=true;shift=false;code=F4};"[1;4P",{control=false;meta=true;shift=true;code=F1};"[1;4Q",{control=false;meta=true;shift=true;code=F2};"[1;4R",{control=false;meta=true;shift=true;code=F3};"[1;4S",{control=false;meta=true;shift=true;code=F4};"[1;5P",{control=true;meta=false;shift=false;code=F1};"[1;5Q",{control=true;meta=false;shift=false;code=F2};"[1;5R",{control=true;meta=false;shift=false;code=F3};"[1;5S",{control=true;meta=false;shift=false;code=F4};"[1;6P",{control=true;meta=false;shift=true;code=F1};"[1;6Q",{control=true;meta=false;shift=true;code=F2};"[1;6R",{control=true;meta=false;shift=true;code=F3};"[1;6S",{control=true;meta=false;shift=true;code=F4};"[1;7P",{control=true;meta=true;shift=false;code=F1};"[1;7Q",{control=true;meta=true;shift=false;code=F2};"[1;7R",{control=true;meta=true;shift=false;code=F3};"[1;7S",{control=true;meta=true;shift=false;code=F4};"[1;8P",{control=true;meta=true;shift=true;code=F1};"[1;8Q",{control=true;meta=true;shift=true;code=F2};"[1;8R",{control=true;meta=true;shift=true;code=F3};"[1;8S",{control=true;meta=true;shift=true;code=F4};"O1;2P",{control=false;meta=false;shift=true;code=F1};"O1;2Q",{control=false;meta=false;shift=true;code=F2};"O1;2R",{control=false;meta=false;shift=true;code=F3};"O1;2S",{control=false;meta=false;shift=true;code=F4};"O1;3P",{control=false;meta=true;shift=false;code=F1};"O1;3Q",{control=false;meta=true;shift=false;code=F2};"O1;3R",{control=false;meta=true;shift=false;code=F3};"O1;3S",{control=false;meta=true;shift=false;code=F4};"O1;4P",{control=false;meta=true;shift=true;code=F1};"O1;4Q",{control=false;meta=true;shift=true;code=F2};"O1;4R",{control=false;meta=true;shift=true;code=F3};"O1;4S",{control=false;meta=true;shift=true;code=F4};"O1;5P",{control=true;meta=false;shift=false;code=F1};"O1;5Q",{control=true;meta=false;shift=false;code=F2};"O1;5R",{control=true;meta=false;shift=false;code=F3};"O1;5S",{control=true;meta=false;shift=false;code=F4};"O1;6P",{control=true;meta=false;shift=true;code=F1};"O1;6Q",{control=true;meta=false;shift=true;code=F2};"O1;6R",{control=true;meta=false;shift=true;code=F3};"O1;6S",{control=true;meta=false;shift=true;code=F4};"O1;7P",{control=true;meta=true;shift=false;code=F1};"O1;7Q",{control=true;meta=true;shift=false;code=F2};"O1;7R",{control=true;meta=true;shift=false;code=F3};"O1;7S",{control=true;meta=true;shift=false;code=F4};"O1;8P",{control=true;meta=true;shift=true;code=F1};"O1;8Q",{control=true;meta=true;shift=true;code=F2};"O1;8R",{control=true;meta=true;shift=true;code=F3};"O1;8S",{control=true;meta=true;shift=true;code=F4};"[15;2~",{control=false;meta=false;shift=true;code=F5};"[17;2~",{control=false;meta=false;shift=true;code=F6};"[18;2~",{control=false;meta=false;shift=true;code=F7};"[19;2~",{control=false;meta=false;shift=true;code=F8};"[20;2~",{control=false;meta=false;shift=true;code=F9};"[21;2~",{control=false;meta=false;shift=true;code=F10};"[23;2~",{control=false;meta=false;shift=true;code=F11};"[24;2~",{control=false;meta=false;shift=true;code=F12};"[15;3~",{control=false;meta=true;shift=false;code=F5};"[17;3~",{control=false;meta=true;shift=false;code=F6};"[18;3~",{control=false;meta=true;shift=false;code=F7};"[19;3~",{control=false;meta=true;shift=false;code=F8};"[20;3~",{control=false;meta=true;shift=false;code=F9};"[21;3~",{control=false;meta=true;shift=false;code=F10};"[23;3~",{control=false;meta=true;shift=false;code=F11};"[24;3~",{control=false;meta=true;shift=false;code=F12};"[15;4~",{control=false;meta=true;shift=true;code=F5};"[17;4~",{control=false;meta=true;shift=true;code=F6};"[18;4~",{control=false;meta=true;shift=true;code=F7};"[19;4~",{control=false;meta=true;shift=true;code=F8};"[20;4~",{control=false;meta=true;shift=true;code=F9};"[21;4~",{control=false;meta=true;shift=true;code=F10};"[23;4~",{control=false;meta=true;shift=true;code=F11};"[24;4~",{control=false;meta=true;shift=true;code=F12};"[15;5~",{control=true;meta=false;shift=false;code=F5};"[17;5~",{control=true;meta=false;shift=false;code=F6};"[18;5~",{control=true;meta=false;shift=false;code=F7};"[19;5~",{control=true;meta=false;shift=false;code=F8};"[20;5~",{control=true;meta=false;shift=false;code=F9};"[21;5~",{control=true;meta=false;shift=false;code=F10};"[23;5~",{control=true;meta=false;shift=false;code=F11};"[24;5~",{control=true;meta=false;shift=false;code=F12};"[15;6~",{control=true;meta=false;shift=true;code=F5};"[17;6~",{control=true;meta=false;shift=true;code=F6};"[18;6~",{control=true;meta=false;shift=true;code=F7};"[19;6~",{control=true;meta=false;shift=true;code=F8};"[20;6~",{control=true;meta=false;shift=true;code=F9};"[21;6~",{control=true;meta=false;shift=true;code=F10};"[23;6~",{control=true;meta=false;shift=true;code=F11};"[24;6~",{control=true;meta=false;shift=true;code=F12};"[15;7~",{control=true;meta=true;shift=false;code=F5};"[17;7~",{control=true;meta=true;shift=false;code=F6};"[18;7~",{control=true;meta=true;shift=false;code=F7};"[19;7~",{control=true;meta=true;shift=false;code=F8};"[20;7~",{control=true;meta=true;shift=false;code=F9};"[21;7~",{control=true;meta=true;shift=false;code=F10};"[23;7~",{control=true;meta=true;shift=false;code=F11};"[24;7~",{control=true;meta=true;shift=false;code=F12};"[15;8~",{control=true;meta=true;shift=true;code=F5};"[17;8~",{control=true;meta=true;shift=true;code=F6};"[18;8~",{control=true;meta=true;shift=true;code=F7};"[19;8~",{control=true;meta=true;shift=true;code=F8};"[20;8~",{control=true;meta=true;shift=true;code=F9};"[21;8~",{control=true;meta=true;shift=true;code=F10};"[23;8~",{control=true;meta=true;shift=true;code=F11};"[24;8~",{control=true;meta=true;shift=true;code=F12};"[1;2H",{control=false;meta=false;shift=true;code=Home};"[1;2F",{control=false;meta=false;shift=true;code=End};"[1;3H",{control=false;meta=true;shift=false;code=Home};"[1;3F",{control=false;meta=true;shift=false;code=End};"[1;4H",{control=false;meta=true;shift=true;code=Home};"[1;4F",{control=false;meta=true;shift=true;code=End};"[1;5H",{control=true;meta=false;shift=false;code=Home};"[1;5F",{control=true;meta=false;shift=false;code=End};"[1;6H",{control=true;meta=false;shift=true;code=Home};"[1;6F",{control=true;meta=false;shift=true;code=End};"[1;7H",{control=true;meta=true;shift=false;code=Home};"[1;7F",{control=true;meta=true;shift=false;code=End};"[1;8H",{control=true;meta=true;shift=true;code=Home};"[1;8F",{control=true;meta=true;shift=true;code=End};"[2;2~",{control=false;meta=false;shift=true;code=Insert};"[3;2~",{control=false;meta=false;shift=true;code=Delete};"[5;2~",{control=false;meta=false;shift=true;code=Prev_page};"[6;2~",{control=false;meta=false;shift=true;code=Next_page};"[2;3~",{control=false;meta=true;shift=false;code=Insert};"[3;3~",{control=false;meta=true;shift=false;code=Delete};"[5;3~",{control=false;meta=true;shift=false;code=Prev_page};"[6;3~",{control=false;meta=true;shift=false;code=Next_page};"[2;4~",{control=false;meta=true;shift=true;code=Insert};"[3;4~",{control=false;meta=true;shift=true;code=Delete};"[5;4~",{control=false;meta=true;shift=true;code=Prev_page};"[6;4~",{control=false;meta=true;shift=true;code=Next_page};"[2;5~",{control=true;meta=false;shift=false;code=Insert};"[3;5~",{control=true;meta=false;shift=false;code=Delete};"[5;5~",{control=true;meta=false;shift=false;code=Prev_page};"[6;5~",{control=true;meta=false;shift=false;code=Next_page};"[2;6~",{control=true;meta=false;shift=true;code=Insert};"[3;6~",{control=true;meta=false;shift=true;code=Delete};"[5;6~",{control=true;meta=false;shift=true;code=Prev_page};"[6;6~",{control=true;meta=false;shift=true;code=Next_page};"[2;7~",{control=true;meta=true;shift=false;code=Insert};"[3;7~",{control=true;meta=true;shift=false;code=Delete};"[5;7~",{control=true;meta=true;shift=false;code=Prev_page};"[6;7~",{control=true;meta=true;shift=false;code=Next_page};"[2;8~",{control=true;meta=true;shift=true;code=Insert};"[3;8~",{control=true;meta=true;shift=true;code=Delete};"[5;8~",{control=true;meta=true;shift=true;code=Prev_page};"[6;8~",{control=true;meta=true;shift=true;code=Next_page};(* iTerm2 *)"[1;9A",{control=false;meta=true;shift=false;code=Up};"[1;9B",{control=false;meta=true;shift=false;code=Down};"[1;9C",{control=false;meta=true;shift=false;code=Right};"[1;9D",{control=false;meta=true;shift=false;code=Left};|]let()=Array.sort(fun(seq1,_)(seq2,_)->String.compareseq1seq2)sequencesletfind_sequenceseq=letrecloopab=ifa=bthenNoneelseletc=(a+b)/2inletk,v=Array.unsafe_getsequencescinmatchString.compareseqkwith|dwhend<0->loopac|dwhend>0->loop(c+1)b|_->Somevinloop0(Array.lengthsequences)letrecparse_event?(escape_time=0.1)encodingstream=Lwt_stream.nextstream>>=funbyte->matchbytewith|'\x1b'->begin(* Escape sequences *)Lwt.catch(fun()->(* Try to parse an escape seqsuence *)Lwt_stream.parsestream(parse_escapeescape_time)>>=function|"[M"->begin(* Mouse report *)letopenLTerm_mouseinLwt_stream.nextstream>|=Char.code>>=funmask->Lwt_stream.nextstream>|=Char.code>>=funx->Lwt_stream.nextstream>|=Char.code>>=funy->tryifmask=0b00100011thenraiseExit;return(LTerm_event.Mouse{control=maskland0b00010000<>0;meta=maskland0b00001000<>0;shift=false;row=y-33;col=x-33;button=(matchmaskland0b11000111with|0b00000000->Button1|0b00000001->Button2|0b00000010->Button3|0b01000000->Button4|0b01000001->Button5|0b01000010->Button6|0b01000011->Button7|0b01000100->Button8|0b01000101->Button9|_->raiseExit);})withExit->parse_eventencodingstreamend|seq->matchfind_sequenceseqwith|Somekey->return(LTerm_event.Keykey)|None->return(LTerm_event.Sequence("\x1b"^seq)))(function|Not_a_sequence->begin(* If it is not, test if it is META+key. *)Lwt.pick[Lwt_stream.peekstream;Lwt_unix.sleepescape_time>>=fun()->returnNone]>>=funch->matchchwith|None->return(LTerm_event.Key{control=false;meta=false;shift=false;code=Escape})|Somebyte->beginmatchbytewith|'\x1b'->begin(* Escape sequences *)Lwt.catch(fun()->beginLwt_stream.parsestream(funstream->Lwt_stream.junkstream>>=fun()->Lwt.pick[Lwt_stream.peekstream;Lwt_unix.sleepescape_time>>=fun()->returnNone]>>=funch->matchchwith|None->Lwt.failNot_a_sequence|Some_->parse_escapeescape_timestream)end>>=funseq->matchfind_sequenceseqwith|Somekey->return(LTerm_event.Key{keywithmeta=true})|None->return(LTerm_event.Sequence("\x1b\x1b"^seq)))(function|Not_a_sequence->return(LTerm_event.Key{control=false;meta=false;shift=false;code=Escape})|exn->Lwt.failexn)end|'\x00'..'\x1b'->(* Control characters *)Lwt_stream.junkstream>>=fun()->letcode=controls.(Char.codebyte)inreturn(LTerm_event.Key{control=(matchcodewithChar_->true|_->false);meta=true;shift=false;code})|'\x7f'->(* Backspace *)Lwt_stream.junkstream>>=fun()->return(LTerm_event.Key{control=false;meta=true;shift=false;code=Backspace})|'\x00'..'\x7f'->(* Other ascii characters *)Lwt_stream.junkstream>>=fun()->return(LTerm_event.Key{control=false;meta=true;shift=false;code=Char(UChar.of_charbyte)})|byte'->Lwt_stream.junkstream>>=fun()->parse_charencodingstreambyte'>>=funcode->return(LTerm_event.Key{control=false;meta=true;shift=false;code=Charcode})endend|exn->Lwt.failexn)end|'\x00'..'\x1f'->(* Control characters *)letcode=controls.(Char.codebyte)inreturn(LTerm_event.Key{control=(matchcodewithChar_->true|_->false);meta=false;shift=false;code})|'\x7f'->(* Backspace *)return(LTerm_event.Key{control=false;meta=false;shift=false;code=Backspace})|'\x00'..'\x7f'->(* Other ascii characters *)return(LTerm_event.Key{control=false;meta=false;shift=false;code=Char(UChar.of_charbyte)})|_->(* Encoded characters *)parse_charencodingstreambyte>>=funcode->return(LTerm_event.Key{control=false;meta=false;shift=false;code=Charcode})