123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314open!Core_kernelopen!ImportincludeCustomization_intfmoduleQ=structincludeQletalist="alist"|>Symbol.internandboolean="boolean"|>Symbol.internandcharacter="character"|>Symbol.internandchoice="choice"|>Symbol.internandcoding_system="coding-system"|>Symbol.internandcolor="color"|>Symbol.internandcons="cons"|>Symbol.internandconst="const"|>Symbol.internanddefcustom="defcustom"|>Symbol.internanddefgroup="defgroup"|>Symbol.internanddirectory="directory"|>Symbol.internandfile="file"|>Symbol.internandfloat="float"|>Symbol.internandfunction_="function"|>Symbol.internandgroup="group"|>Symbol.internandhook="hook"|>Symbol.internandinteger="integer"|>Symbol.internandplist="plist"|>Symbol.internandradio="radio"|>Symbol.internandrepeat="repeat"|>Symbol.internandset="set"|>Symbol.internandstring="string"|>Symbol.internandvariable="variable"|>Symbol.internendletcustomize_group=Funcall.("customize-group"<:Symbol.t@->returnnil)letcustomize_variable=Funcall.("customize-variable"<:Symbol.t@->returnnil)letqvalue=Value.list[Symbol.to_valueQ.quote;value]moduleGroup=structinclude(Symbol:sigtypet=Symbol.t[@@derivingsexp_of]includeValueable.Swithtypet:=tend)letall_defgroups=ref[]letdefgroupgroup_namehere~docstring~parents=letgroup_name=group_name|>Symbol.interninletform_of_parentparent=Form.[Q.K.group|>symbol;parent|>Symbol.to_value|>quote]inletdocstring=sprintf"%s\n\nDefined at %s"(docstring|>String.strip)(here|>Source_code_position.to_string)inForm.(Blocking.eval_i(list(List.concat[[Q.defgroup|>symbol;group_name|>symbol;nil;docstring|>string];List.concat_mapparents~f:form_of_parent])));all_defgroups:=group_name::!all_defgroups;group_name;;letof_string=Symbol.internletto_string=Symbol.nameletto_symbolt=tletemacs=of_string"emacs"letecaml=defgroup"ecaml"[%here]~docstring:{| Customization of Ecaml |}~parents:[emacs];;endmoduleType=structtypet=|Alistoft*t|Boolean|Character|Choiceoftlist|Coding_system|Color|Consoft*t|ConstofValue.t|Directory|Existing_file|Face|File|Float|Function|Groupoft|Hook|Integer|Listoftlist|Number|Optionofstring*t|Plist|Radiooftlist|Regexp|Repeatoft|Setoftlist|Sexp|String|Symbol|Tagged_stringofstring|Variable|Vectoroftlist[@@derivingsexp_of]lets=Symbol.to_valueletrecvsts=List.mapts~f:vandcompositests=Value.list(Symbol.to_values::vsts)andv=function|Alist(t1,t2)->Value.list[sQ.alist;sQ.K.key_type;vt1;sQ.K.value_type;vt2]|Boolean->sQ.boolean|Character->sQ.character|Choicets->compositeQ.choicets|Coding_system->sQ.coding_system|Color->sQ.color|Cons(t1,t2)->compositeQ.cons[t1;t2]|Constv->Value.list[sQ.const;v]|Directory->sQ.directory|Existing_file->Value.list[sQ.file;sQ.K.must_match;Value.t]|Face->sQ.face|File->sQ.file|Float->sQ.float|Function->sQ.function_|Groupt->compositeQ.group[t]|Hook->sQ.hook|Integer->sQ.integer|Listts->compositeQ.listts|Number->sQ.number|Option(none,t)->Value.list[sQ.choice;Value.list[sQ.const;sQ.K.tag;Value.of_utf8_bytesnone;sQ.nil];vt]|Plist->sQ.plist|Radiots->compositeQ.radiots|Regexp->sQ.regexp|Repeatt->compositeQ.repeat[t]|Setts->compositeQ.setts|Sexp->sQ.sexp|String->sQ.string|Symbol->sQ.symbol|Tagged_stringtag->Value.list[vString;sQ.K.tag;Value.of_utf8_bytestag]|Variable->sQ.variable|Vectorts->compositeQ.vectorts;;letto_value=vletenumallvalue_of_a=Choice(List.mapall~f:(funa->Const(value_of_aa)))endletall_defcustom_symbols=ref[]modulePrivate=structletall_defcustom_symbols()=!all_defcustom_symbols|>List.sort~compare:Symbol.compare_name;;letall_defgroups()=!Group.all_defgroups|>List.sort~compare:Symbol.compare_nameendtype'at='aVar.t[@@derivingsexp_of]letvart=tletsymbol=Var.symbolletvalue=Current_buffer0.value_exnletcustom_set_variables=Funcall.("custom-set-variables"<:value@->returnnil)letset_valueta=custom_set_variables(Value.list[Var.symbolt|>Symbol.to_value;a|>Value.Type.to_valuet.type_]);;letset_value_temporarilyta~f=letold=valuetinset_valueta;protect~f~finally:(fun()->set_valuetold);;letstandard_value=Var.default_value_exnletdefcustom?(show_form=false)symbolhere~docstring~group~type_~customization_type~standard_value?on_set()=letstandard_value=standard_value|>Value.Type.to_valuetype_in(tryletdocstring=concat[docstring|>String.strip;"\n\n";concat["Customization group: ";group|>Group.to_string;"\n"];concat["Standard value: ";standard_value|>Value.prin1_to_string;"\n"];concat["Customization type:";(letstring=customization_type|>Type.to_value|>Value.prin1_to_stringinifString.containsstring'\n'thenconcat["\n";string]elseconcat[" ";string])]]inall_defcustom_symbols:=symbol::!all_defcustom_symbols;Load_history.add_entryhere(Varsymbol);letform=List.concat[[Q.defcustom|>Symbol.to_value];[symbol|>Symbol.to_value];[standard_value|>q];[docstring|>Value.of_utf8_bytes];[Q.K.group|>Symbol.to_value;group|>Symbol.to_value|>q];[Q.K.type_|>Symbol.to_value;customization_type|>Type.to_value|>q];(matchon_setwith|None->[]|Someon_set->[Q.K.set|>Symbol.to_value;Function.to_value(Defun.lambda[%here](ReturnsValue.Type.unit)(letvar=Var.createsymboltype_inlet%map_open.Defun()=return()and_=required"symbol"Symbol.tanda=required"value"type_inon_seta;(* We set the Elisp variable after calling the user-supplied
[on_set] function, because we only want to do the set if that
succeeds. *)Var.set_default_valuevara))])]|>Value.list|>Form.of_value_exninifshow_formthenmessage_s[%sexp(form:Form.t)];ignore(Form.Blocking.evalform:Value.t)with|exn->raise_s[%message"[defcustom] failed"(exn:exn)(symbol:Symbol.t)(customization_type:Type.t)(group:Symbol.t)(standard_value:Value.t)(docstring:string)~_:(here:Source_code_position.t)]);Var.createsymboltype_;;letdefcustom_enum(typet)symbolhere(moduleT:Enum_argwithtypet=t)~docstring~group~standard_value?on_set()=lettype_=Value.Type.enum[%sexp(Symbol.namesymbol:string)](moduleT)(T.to_symbol>>Symbol.to_value)inletdocstring=concat~sep:"\n"((docstring|>String.strip)::""::List.mapT.all~f:(funt->letdocstring=matchT.docstringtwith|""->[]|docstring->[": ";docstring]inconcat(" - "::(t|>T.to_symbol|>Symbol.name)::docstring)))indefcustomsymbolhere~docstring~group~type_~customization_type:(Type.enumT.all(Value.Type.to_valuetype_))~standard_value?on_set();;