123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611open!Coreopen!Import0moduleFrame=Frame0moduleQ=structincludeQletbold="bold"|>Symbol.internletcondensed="condensed"|>Symbol.internletexpanded="expanded"|>Symbol.internletextra_bold="extra-bold"|>Symbol.internletextra_condensed="extra-condensed"|>Symbol.internletextra_expanded="extra-expanded"|>Symbol.internletextra_light="extra-light"|>Symbol.internletitalic="italic"|>Symbol.internletlight="light"|>Symbol.internletnormal="normal"|>Symbol.internletoblique="oblique"|>Symbol.internletreverse_italic="reverse-italic"|>Symbol.internletreverse_oblique="reverse-oblique"|>Symbol.internletsemi_bold="semi-bold"|>Symbol.internletsemi_condensed="semi-condensed"|>Symbol.internletsemi_expanded="semi-expanded"|>Symbol.internletsemi_light="semi-light"|>Symbol.internletultra_bold="ultra-bold"|>Symbol.internletultra_condensed="ultra-condensed"|>Symbol.internletultra_expanded="ultra-expanded"|>Symbol.internletultra_light="ultra-light"|>Symbol.internletunspecified="unspecified"|>Symbol.internendmoduleValue=structincludeValueletunspecified=Q.unspecified|>Symbol.to_valueendincludeValue.Make_subtype(structletname="face"lethere=[%here]letis_in_subtype=Value.is_symbolend)letlist_type=Value.Type.listtletof_names=s|>Value.intern|>of_value_exnletdefault="default"|>of_nameletto_namet=letv=t|>to_valueinmatchSymbol.of_value_exnvwith|s->s|>Symbol.name|exception_->raise_s[%message"[Face.to_name] got unexpected value"~_:(v:Value.t)];;letcomparet1t2=String.compare(t1|>to_name)(t2|>to_name)letequal=eqmoduletypeAttribute_value=sigtypet[@@derivingsexp_of]valsymbol:Symbol.tvalof_value_exn:Value.t->tvalto_value:t->Value.tvalunspecified:tendmoduleUnimplemented=structtypet=Value.t[@@derivingsexp_of]letof_value_exn=Fn.idletto_value=Fn.idletunspecified=Value.unspecifiedendmoduleColor_or_unspecified=structtypet=|ColorofColor.t|Unspecified[@@derivingsexp_of]letunspecified=Unspecifiedletto_value=function|Colorc->c|>Color.to_value|Unspecified->Value.unspecified;;letof_value_exnvalue=ifValue.eqvalueValue.unspecified(* Sometimes Emacs returns an unspecified color as the string "unspecified-fg" or
"unspecified-bg" rather than the symbol [unspecified]. *)||(Value.is_stringvalue&&String.is_prefix~prefix:"unspecified"(Value.to_utf8_bytes_exnvalue))thenUnspecifiedelseColor(value|>Color.of_value_exn);;endmoduleString_name=structtypet=|Nameofstring|Unspecified[@@derivingsexp_of]letunspecified=Unspecifiedletof_value_exnvalue=ifValue.eqvalueValue.unspecifiedthenUnspecifiedelseName(value|>Value.to_utf8_bytes_exn);;letto_value=function|Names->s|>Value.of_utf8_bytes|Unspecified->Value.unspecified;;endmoduleBackground=structincludeColor_or_unspecifiedletsymbol=Q.K.backgroundendmoduleBox=structletsymbol=Q.K.boxincludeUnimplementedendmoduleFont=structletsymbol=Q.K.fontincludeUnimplementedendmoduleFont_family=structletsymbol=Q.K.familyincludeString_nameendmoduleFont_foundry=structletsymbol=Q.K.foundryincludeString_nameendmoduleForeground=structincludeColor_or_unspecifiedletsymbol=Q.K.foregroundendmoduleHeight=structtypet=|Scale_underlying_faceoffloat|Tenths_of_pointofint|Unspecified[@@derivingsexp_of]letunspecified=Unspecifiedletsymbol=Q.K.heightletof_value_exnvalue=ifValue.eqvalueValue.unspecifiedthenUnspecifiedelse(matchValue.to_int_exnvaluewith|i->Tenths_of_pointi|exception_->(matchValue.to_float_exnvaluewith|f->Scale_underlying_facef|exception_->raise_s[%message"[Face.Height.of_value_exn] got unexpected value"(value:Value.t)]));;letto_value=function|Scale_underlying_facef->f|>Value.of_float|Tenths_of_pointi->i|>Value.of_int_exn|Unspecified->Value.unspecified;;endmoduleInherit=structletsymbol=Q.K.inherit_typenonrect=|Faceoftlist|Unspecified[@@derivingsexp_of]letunspecified=Unspecifiedletto_value=function|Face[]|Unspecified->Value.unspecified|Face[face]->to_valueface|Facefaces->Value.Type.to_valuelist_typefaces;;letof_value_exnvalue=(* It's possible to (defface nil) and then even to (describe-face nil), but applying
the nil face and inheriting from the nil face have no effect. *)ifValue.eqvalueValue.unspecified||Value.eqvalueValue.nilthenUnspecifiedelseifValue.is_consvaluethenFace(Value.Type.of_value_exnlist_typevalue)elseFace[of_value_exnvalue];;endmoduleInverse_video=structletsymbol=Q.K.inverse_videotypet=|No|Yes|Unspecified[@@derivingsexp_of]letunspecified=Unspecifiedletto_value=function|No->Value.nil|Yes->Value.t|Unspecified->Value.unspecified;;letof_value_exnvalue=ifValue.is_nilvaluethenNoelseifValue.eqvalueValue.tthenYeselseifValue.eqvalueValue.unspecifiedthenUnspecifiedelseraise_s[%message"[Face.Inverse_video.of_value_exn] got unexpected value"(value:Value.t)];;endmoduleLine=structtypet=|Absent|ColorofColor.t|Foreground|Unspecified[@@derivingsexp_of]letunspecified=Unspecifiedletof_value_exnvalue=ifValue.eqvalueValue.unspecifiedthenUnspecifiedelseifValue.is_nilvaluethenAbsentelseifValue.eqvalueValue.tthenForegroundelse(matchColor.of_value_exnvaluewith|c->Colorc|exception_->raise_s[%message"[Face.Line.of_value_exn] got unexpected value"(value:Value.t)]);;letto_value=function|Absent->Value.nil|Colorc->c|>Color.to_value|Foreground->Value.t|Unspecified->Value.unspecified;;endmoduleOverline=structincludeLineletsymbol=Q.K.overlineendmoduleSlant=structmoduleT=structletmodule_name="Face.Slant"letsymbol=Q.K.slanttypet=|Italic|Oblique|Normal|Reverse_italic|Reverse_oblique|Unspecified[@@derivingenumerate,sexp_of]letunspecified=Unspecifiedletto_symbol=function|Italic->Q.italic|Oblique->Q.oblique|Normal->Q.normal|Reverse_italic->Q.reverse_italic|Reverse_oblique->Q.reverse_oblique|Unspecified->Q.unspecified;;endincludeTincludeSymbol.Make_subtype(T)endmoduleStipple=structletsymbol=Q.K.stippleincludeUnimplementedendmoduleStrike_through=structletsymbol=Q.K.strike_throughincludeLineendmoduleUnderline=structletsymbol=Q.K.underlineincludeLineendmoduleWeight=structmoduleT=structletmodule_name="Face.Weight"letsymbol=Q.K.weighttypet=|Ultra_bold|Extra_bold|Bold|Semi_bold|Normal|Semi_light|Light|Extra_light|Ultra_light|Unspecified[@@derivingenumerate,sexp_of]letunspecified=Unspecifiedletto_symbol=function|Ultra_bold->Q.ultra_bold|Extra_bold->Q.extra_bold|Bold->Q.bold|Semi_bold->Q.semi_bold|Normal->Q.normal|Semi_light->Q.semi_light|Light->Q.light|Extra_light->Q.extra_light|Ultra_light->Q.ultra_light|Unspecified->Q.unspecified;;endincludeTincludeSymbol.Make_subtype(T)endmoduleWidth=structmoduleT=structletmodule_name="Face.Width"letsymbol=Q.K.widthtypet=|Ultra_condensed|Extra_condensed|Condensed|Semi_condensed|Normal|Semi_expanded|Expanded|Extra_expanded|Ultra_expanded|Unspecified[@@derivingenumerate,sexp_of]letunspecified=Unspecifiedletto_symbol=function|Ultra_condensed->Q.ultra_condensed|Extra_condensed->Q.extra_condensed|Condensed->Q.condensed|Semi_condensed->Q.semi_condensed|Normal->Q.normal|Semi_expanded->Q.semi_expanded|Expanded->Q.expanded|Extra_expanded->Q.extra_expanded|Ultra_expanded->Q.ultra_expanded|Unspecified->Q.unspecified;;endincludeTincludeSymbol.Make_subtype(T)endmoduleAttribute=structtype_t=|Background:Background.tt|Box:Box.tt|Font:Font.tt|Font_family:Font_family.tt|Font_foundry:Font_foundry.tt|Foreground:Foreground.tt|Height:Height.tt|Inherit:Inherit.tt|Inverse_video:Inverse_video.tt|Overline:Overline.tt|Slant:Slant.tt|Stipple:Stipple.tt|Strike_through:Strike_through.tt|Underline:Underline.tt|Weight:Weight.tt|Width:Width.tt[@@derivingsexp_of]type'aattribute='atletvalue_module:typea.at->(moduleAttribute_valuewithtypet=a)=function|Background->(moduleBackground)|Box->(moduleBox)|Font->(moduleFont)|Font_family->(moduleFont_family)|Font_foundry->(moduleFont_foundry)|Foreground->(moduleForeground)|Height->(moduleHeight)|Inherit->(moduleInherit)|Inverse_video->(moduleInverse_video)|Overline->(moduleOverline)|Slant->(moduleSlant)|Stipple->(moduleStipple)|Strike_through->(moduleStrike_through)|Underline->(moduleUnderline)|Weight->(moduleWeight)|Width->(moduleWidth);;letunspecified_value(typea)(t:at):a=letmoduleValue=(valvalue_modulet)inValue.unspecified;;letto_symbol(typea)(t:at)=letmoduleValue=(valvalue_modulet)inValue.symbol;;letcompare_namet1t2=String.compare(t1|>to_symbol|>Symbol.name)(t2|>to_symbol|>Symbol.name);;modulePacked=structmoduleT=structletmodule_name="Face.Attribute.Packed"typet=T:_attribute->tletsexp_of_t(Ta)=[%sexp(a:_t)](* The type system doesn't guarantee that [all] is exhaustive. But the tests of
[Face.attributes] in [test_face.ml] do ensure this, because they convert
attributes as symbols to [Face.Attribute.Packed.t] using [Packed.of_symbol_exn],
which looks up attributes based on [all]. *)letall=[TBackground;TBox;TFont;TFont_family;TFont_foundry;TForeground;THeight;TInherit;TInverse_video;TOverline;TSlant;TStipple;TStrike_through;TUnderline;TWeight;TWidth];;letto_symbol(Ta)=to_symbolaendincludeTincludeSymbol.Make_subtype(T)endletof_value_exn(typea)(t:at):Value.t->a=letmoduleValue=(valvalue_modulet)inValue.of_value_exn;;letto_value(typea)(t:at):a->Value.t=letmoduleValue=(valvalue_modulet)inValue.to_value;;letface_attribute_relative_p=Funcall.Wrap.("face-attribute-relative-p"<:Symbol.t@->value@->returnbool);;letis_relativeta=face_attribute_relative_p(t|>to_symbol)(a|>to_valuet)letmerge_face_attribute=Funcall.Wrap.("merge-face-attribute"<:Symbol.t@->value@->value@->returnvalue);;letmergeta1a2=merge_face_attribute(t|>to_symbol)(a1|>to_valuet)(a2|>to_valuet)|>of_value_exnt;;endmoduleAttribute_and_value=structtypet=T:'aAttribute.t*'a->tletsexp_of_t(T(attribute,value))=letmoduleValue=(valAttribute.value_moduleattribute)in[%message""~_:(attribute:_Attribute.t)~_:(value:Value.t)];;letcompare_attribute_name(T(a1,_))(T(a2,_))=Attribute.compare_namea1a2letof_value_exnvalue=matchValue.car_exnvaluewith|attribute->let(Attribute.Packed.Tattribute)=attribute|>Attribute.Packed.of_value_exninT(attribute,Attribute.of_value_exnattribute(Value.cdr_exnvalue))|exception_->raise_s[%message"[Face.Attribute_and_value.of_value_exn] got unexpected value"(value:Value.t)];;letsort_by_attribute_namets=List.sortts~compare:(fun(T(a1,_))(T(a2,_))->Attribute.compare_namea1a2);;letto_value_list(T(attribute,value))=[Attribute.to_symbolattribute|>Symbol.to_value;Attribute.to_valueattributevalue];;endletframeoption=matchoptionwith|Somex->x|None->Frame.selected();;letface_list=Funcall.Wrap.("face-list"<:nullary@->return(listt))letall_defined()=face_list()|>List.sort~compareletfont_family_list=Funcall.Wrap.("font-family-list"<:Frame.t@->return(liststring));;letfont_family_list?on()=font_family_list(frameon)letface_attribute=Funcall.Wrap.("face-attribute"<:t@->Symbol.t@->Frame.t@->returnvalue);;letattribute_value?ontattribute=face_attributet(attribute|>Attribute.to_symbol)(frameon)|>Attribute.of_value_exnattribute;;letset_face_attribute=Funcall.Wrap.("set-face-attribute"<:t@->Frame.t@->Symbol.t@->value@->returnnil);;letset_attribute?ontattributevalue=set_face_attributet(frameon)(attribute|>Attribute.to_symbol)(Attribute.to_valueattributevalue);;letface_all_attributes=Funcall.Wrap.("face-all-attributes"<:t@->Frame.t@->return(listvalue));;letattributes?ont=face_all_attributest(frameon)|>List.map~f:Attribute_and_value.of_value_exn;;letspecs_to_valuespecs=Value.(list[const(list(List.concat_mapspecs~f:Attribute_and_value.to_value_list))]);;letface_spec_set=Funcall.Wrap.("face-spec-set"<:t@->value@->returnnil)letspec_setfacespecs=face_spec_setface(specs_to_valuespecs)