123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184(**************************************************************************)(* *)(* OCamlFormat *)(* *)(* Copyright (c) Facebook, Inc. and its affiliates. *)(* *)(* This source code is licensed under the MIT license found in *)(* the LICENSE file in the root directory of this source tree. *)(* *)(**************************************************************************)(** Configuration options *)typefmt_opts={align_cases:bool;align_constructors_decl:bool;align_variants_decl:bool;assignment_operator:[`Begin_line|`End_line];break_before_in:[`Fit_or_vertical|`Auto];break_cases:[`Fit|`Nested|`Toplevel|`Fit_or_vertical|`All];break_collection_expressions:[`Wrap|`Fit_or_vertical];break_infix:[`Wrap|`Fit_or_vertical];break_infix_before_func:bool;break_fun_decl:[`Wrap|`Fit_or_vertical|`Smart];break_fun_sig:[`Wrap|`Fit_or_vertical|`Smart];break_separators:[`Before|`After];break_sequences:bool;break_string_literals:[`Auto|`Never];break_struct:bool;cases_exp_indent:int;cases_matching_exp_indent:[`Normal|`Compact];disambiguate_non_breaking_match:bool;doc_comments:[`Before|`Before_except_val|`After_when_possible];doc_comments_padding:int;doc_comments_tag_only:[`Fit|`Default];dock_collection_brackets:bool;exp_grouping:[`Parens|`Preserve];extension_indent:int;field_space:[`Tight|`Loose|`Tight_decl];function_indent:int;function_indent_nested:[`Always|`Auto|`Never];if_then_else:[`Compact|`Fit_or_vertical|`Keyword_first|`K_R];indent_after_in:int;indicate_multiline_delimiters:[`No|`Space|`Closing_on_separate_line];indicate_nested_or_patterns:[`Space|`Unsafe_no];infix_precedence:[`Indent|`Parens];leading_nested_match_parens:bool;let_and:[`Compact|`Sparse];let_binding_indent:int;let_binding_spacing:[`Compact|`Sparse|`Double_semicolon];let_module:[`Compact|`Sparse];line_endings:[`Lf|`Crlf];margin:int;match_indent:int;match_indent_nested:[`Always|`Auto|`Never];max_indent:intoption;module_item_spacing:[`Compact|`Preserve|`Sparse];nested_match:[`Wrap|`Align];ocp_indent_compat:bool;parens_ite:bool;parens_tuple:[`Always|`Multi_line_only];parens_tuple_patterns:[`Always|`Multi_line_only];parse_docstrings:bool;parse_toplevel_phrases:bool;sequence_blank_line:[`Compact|`Preserve_one];sequence_style:[`Before|`Separator|`Terminator];single_case:[`Compact|`Sparse];space_around_arrays:bool;space_around_lists:bool;space_around_records:bool;space_around_variants:bool;stritem_extension_indent:int;type_decl:[`Compact|`Sparse];type_decl_indent:int;wrap_comments:bool;wrap_fun_args:bool}typeopr_opts={comment_check:bool;debug:bool;disable:bool;margin_check:bool;max_iters:int;ocaml_version:Ocaml_version.t;quiet:bool}typet={fmt_opts:fmt_opts;opr_opts:opr_opts}letprofile_option_names=["p";"profile"]openCmdlinerletwarn_raw,collect_warnings=letdelay_warning=reffalseinletdelayed_warning_list=ref[]inletwarn_s=if!delay_warningthendelayed_warning_list:=s::!delayed_warning_listelseFormat.eprintf"%s%!"sinletcollect_warningsf=letold_flag,old_list=(!delay_warning,!delayed_warning_list)indelay_warning:=true;delayed_warning_list:=[];letres=f()inletcollected=List.rev!delayed_warning_listindelay_warning:=old_flag;delayed_warning_list:=old_list;(res,fun()->List.iter~f:warn_collected)in(warn_,collect_warnings)letwarn?filename?lnumfmt=Format.kasprintf(funs->letloc:string=match(filename,lnum)with|Somefile,Somelnum->Format.asprintf"File %a, line %d:@\n"Fpath.ppfilelnum|Somefile,None->Format.asprintf"File %a@\n"Fpath.ppfile|None,_->""inwarn_raw(Format.asprintf"%sWarning: %s@\n"locs))fmtmoduleC=Config_option.Make(structtypeconfig=tletprofile_option_names=profile_option_namesletwarn(config:config)fmt=Format.kasprintf(funs->ifnotconfig.opr_opts.quietthenwarn"%s"s)fmtend)letinfo=letdoc="A tool to format OCaml code."inletman=[`SCmdliner.Manpage.s_description;`P"$(tname) automatically formats OCaml code.";`S(C.section_nameC.Formatting`Valid);`P"Unless otherwise noted, any option \
$(b,--)$(i,option)$(b,=)$(i,VAL) detailed in this section can be \
set in many ways, its value is determined in the following order \
(of increasing priority): the default value is used if no other \
value is specified. The value of a boolean option $(b,--foo) or \
$(b,--no-foo) can be modified in an $(b,.ocamlformat) \
configuration file with '$(b,foo = ){$(b,true),$(b,false)}', it \
can be done for any other option with an '$(b,option = )$(i,VAL)' \
line (*), or using the OCAMLFORMAT environment variable: \
$(b,OCAMLFORMAT=)$(i,option)$(b,=)$(i,VAL)$(b,,)...$(b,,)$(i,option)$(b,=)$(i,VAL), \
or as an optional parameter on the command line, or with a global \
$(b,[@@@ocamlformat \")$(i,option)$(b,=)$(i,VAL)$(b,\"]) attribute \
in the processed file, or with an $(b,[@@ocamlformat \
\")$(i,option)$(b,=)$(i,VAL)$(b,\"]) attribute on expression in \
the processed file.";`P"(*) $(b,.ocamlformat) files in current and all ancestor \
directories for each input file are used, as well as the global \
$(b,ocamlformat) file defined in $(b,\\$XDG_CONFIG_HOME) or in \
$(b,\\$HOME/.config) if $(b,\\$XDG_CONFIG_HOME) is undefined. The \
global $(b,ocamlformat) file has the lowest priority, then the \
closer the directory is to the processed file, the higher the \
priority. The global $(b,ocamlformat) file is only used when the \
option $(b,enable-outside-detected-project) is set.";`P"If the $(b,disable) option is not set, an $(b,.ocamlformat-ignore) \
file specifies files that OCamlFormat should ignore. Each line in \
an $(b,.ocamlformat-ignore) file specifies a filename relative to \
the directory containing the $(b,.ocamlformat-ignore) file. \
Shell-style regular expressions are supported. Lines starting with \
$(b,#) are ignored and can be used as comments.";`P"If the $(b,disable) option is set, an $(b,.ocamlformat-enable) \
file specifies files that OCamlFormat should format even when the \
$(b,disable) option is set. Each line in an \
$(b,.ocamlformat-enable) file specifies a filename relative to the \
directory containing the $(b,.ocamlformat-enable) file. \
Shell-style regular expressions are supported. Lines starting with \
$(b,#) are ignored and can be used as comments.";`S(C.section_nameC.Operational`Valid);`P"Unless mentioned otherwise non-formatting options cannot be set in \
attributes or $(b,.ocamlformat) files."]inCmd.info"ocamlformat"~version:Version.current~doc~manletocaml_version_conv=letparsex=matchOcaml_version.of_stringxwith|Okx->`Okx|Error(`Msgx)->`Errorxin(parse,Ocaml_version.pp)letremoved_by_v1_0=Format.asprintf"It will be removed by version %a."Version.ppV1_0_0letdeprecated_orphan=C.deprecated~since:V0_20_0removed_by_v1_0(** Options affecting formatting *)moduleFormatting=structletkind=C.Formattingletupdate~fc={cwithfmt_opts=fc.fmt_opts}letalign_cases=letdoc="Align match/try cases vertically."inletnames=["align-cases"]inC.flag~default:false~names~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithalign_cases=x}))(funconf->conf.fmt_opts.align_cases)letalign_constructors_decl=letdoc="Align type declarations vertically."inletnames=["align-constructors-decl"]inC.flag~default:false~names~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithalign_constructors_decl=x}))(funconf->conf.fmt_opts.align_constructors_decl)letalign_variants_decl=letdoc="Align type variants declarations vertically."inletnames=["align-variants-decl"]inC.flag~default:false~names~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithalign_variants_decl=x}))(funconf->conf.fmt_opts.align_variants_decl)letassignment_operator=letdoc="Position of the assignment operator."inletnames=["assignment-operator"]inletall=[C.Value.make~name:"end-line"`End_line"$(b,end-line) positions assignment operators (`:=` and `<-`) at \
the end of the line and breaks after it if the whole assignment \
expression does not fit on a single line.";C.Value.make~name:"begin-line"`Begin_line"$(b,begin-line) positions assignment operators (`:=` and `<-`) \
at the beginning of the line and breaks before it if the whole \
assignment expression does not fit on a single line."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithassignment_operator=x}))(funconf->conf.fmt_opts.assignment_operator)letbreak_before_in=letdoc="Whether the line should break before the $(i,in) keyword of a \
$(i,let) binding."inletnames=["break-before-in"]inletall=[C.Value.make~name:"fit-or-vertical"`Fit_or_vertical"$(b,fit-or-vertical) will always break the line before the \
$(i,in) keyword if the whole $(i,let) binding does not fit on a \
single line.";C.Value.make~name:"auto"`Auto"$(b,auto) will only break the line if the $(i,in) keyword does \
not fit on the previous line."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithbreak_before_in=x}))(funconf->conf.fmt_opts.break_before_in)letbreak_cases=letdoc="Break pattern match cases."inletnames=["break-cases"]inletall=[C.Value.make~name:"fit"`Fit"Specifying $(b,fit) lets pattern matches break at the margin \
naturally.";C.Value.make~name:"nested"`Nested"$(b,nested) forces a break after nested or-patterns to highlight \
the case body. Note that with $(b,nested), the \
$(b,indicate-nested-or-patterns) option is not needed, and so \
ignored.";C.Value.make~name:"toplevel"`Toplevel~deprecated:deprecated_orphan"$(b,toplevel) forces top-level cases (i.e. not nested \
or-patterns) to break across lines, otherwise break naturally at \
the margin.";C.Value.make~name:"fit-or-vertical"`Fit_or_vertical"$(b,fit-or-vertical) tries to fit all or-patterns on the same \
line, otherwise breaks.";C.Value.make~name:"all"`All~deprecated:deprecated_orphan"$(b,all) forces all pattern matches to break across lines."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithbreak_cases=x}))(funconf->conf.fmt_opts.break_cases)letbreak_collection_expressions=letdoc="Break collection expressions (lists and arrays) elements by elements."inletnames=["break-collection-expressions"]inletall=[C.Value.make~name:"fit-or-vertical"`Fit_or_vertical"$(b,fit-or-vertical) vertically breaks expressions if they do \
not fit on a single line.";C.Value.make~name:"wrap"`Wrap"$(b,wrap) will group simple expressions and try to format them \
in a single line."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithbreak_collection_expressions=x}))(funconf->conf.fmt_opts.break_collection_expressions)letbreak_fun_decl=letdoc="Style for function declarations and types."inletnames=["break-fun-decl"]inletall=[C.Value.make~name:"wrap"`Wrap"$(b,wrap) breaks only if necessary.";C.Value.make~name:"fit-or-vertical"`Fit_or_vertical"$(b,fit-or-vertical) vertically breaks arguments if they do not \
fit on a single line.";C.Value.make~name:"smart"`Smart~deprecated:deprecated_orphan"$(b,smart) is like $(b,fit-or-vertical) but try to fit arguments \
on their line if they fit."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithbreak_fun_decl=x}))(funconf->conf.fmt_opts.break_fun_decl)letbreak_fun_sig=letdoc="Style for function signatures."inletnames=["break-fun-sig"]inletall=[C.Value.make~name:"wrap"`Wrap"$(b,wrap) breaks only if necessary.";C.Value.make~name:"fit-or-vertical"`Fit_or_vertical"$(b,fit-or-vertical) vertically breaks arguments if they do not \
fit on a single line.";C.Value.make~name:"smart"`Smart~deprecated:deprecated_orphan"$(b,smart) is like $(b,fit-or-vertical) but try to fit arguments \
on their line if they fit."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithbreak_fun_sig=x}))(funconf->conf.fmt_opts.break_fun_sig)letbreak_infix=letdoc="Break sequence of infix operators."inletnames=["break-infix"]inletall=[C.Value.make~name:"wrap"`Wrap"$(b,wrap) will group simple expressions and try to format them \
in a single line.";C.Value.make~name:"fit-or-vertical"`Fit_or_vertical"$(b,fit-or-vertical) vertically breaks expressions if they do \
not fit on a single line."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithbreak_infix=x}))(funconf->conf.fmt_opts.break_infix)letbreak_infix_before_func=letdoc="Break infix operators whose right arguments are anonymous functions \
specially: do not break after the operator so that the first line of \
the function appears docked at the end of line after the operator."inletnames=["break-infix-before-func"]inC.flag~default:false~names~doc~kind(funconfx->updateconf~f:(funf->{fwithbreak_infix_before_func=x}))(funconf->conf.fmt_opts.break_infix_before_func)letbreak_separators=letdoc="Break before or after separators such as `;` in list or record \
expressions."inletnames=["break-separators"]inletall=[C.Value.make~name:"after"`After"$(b,after) breaks the expressions after the separator.";C.Value.make~name:"before"`Before"$(b,before) breaks the expressions before the separator."]inC.choice~names~all~doc~kind~removed_values:[C.Value_removed.make~name:"after-and-docked"~since:V0_12_0~msg:"One can get a similar behaviour by setting \
`break-separators=after`, `space-around-lists=false`, and \
`dock-collection-brackets=false`."](funconfx->updateconf~f:(funf->{fwithbreak_separators=x}))(funconf->conf.fmt_opts.break_separators)letbreak_sequences=letdoc="Force sequence expressions to break irrespective of margin."inletnames=["break-sequences"]inC.flag~default:true~names~doc~kind(funconfx->updateconf~f:(funf->{fwithbreak_sequences=x}))(funconf->conf.fmt_opts.break_sequences)letbreak_string_literals=letdoc="Break string literals."inletnames=["break-string-literals"]inletall=[C.Value.make~name:"auto"`Auto"$(b,auto) mode breaks lines at newlines and wraps string \
literals at the margin.";C.Value.make~name:"never"`Never"$(b,never) mode formats string literals as they are parsed, in \
particular, with escape sequences expanded."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)~removed_values:(C.Value_removed.make_list~names:["newlines";"newlines-and-wrap";"wrap"]~since:V0_12_0~msg:"It has been replaced by the new default `auto` value, which \
breaks lines at newlines and wraps string literals at the \
margin.")(funconfx->updateconf~f:(funf->{fwithbreak_string_literals=x}))(funconf->conf.fmt_opts.break_string_literals)letbreak_struct=letdoc="Break struct-end module items."inletnames=["break-struct"]inletall=[C.Value.make~name:"force"`Force"$(b,force) will break struct-end phrases unconditionally.";C.Value.make~name:"natural"`Natural"$(b,natural) will break struct-end phrases naturally at the \
margin."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithbreak_struct=Poly.(x=`Force)}))(funconf->ifconf.fmt_opts.break_structthen`Forceelse`Natural)letcases_exp_indent=letdocv="COLS"inletdoc="Indentation of cases expressions ($(docv) columns). See also the \
$(b,cases-matching-exp-indent) and $(b,nested-match) options."inletnames=["cases-exp-indent"]inC.anyArg.int~names~default:4~doc~docv~kind~allow_inline:false(funconfx->updateconf~f:(funf->{fwithcases_exp_indent=x}))(funconf->conf.fmt_opts.cases_exp_indent)letcases_matching_exp_indent=letdoc="Indentation of cases right-hand sides which are `match` or `try` \
expressions."inletnames=["cases-matching-exp-indent"]inletall=[C.Value.make~name:"normal"`Normal"$(b,normal) indents as it would any other expression.";C.Value.make~name:"compact"`Compact"$(b,compact) forces an indentation of 2, unless \
$(b,nested-match) is set to $(b,align) and we're on the last \
case."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithcases_matching_exp_indent=x}))(funconf->conf.fmt_opts.cases_matching_exp_indent)letdisambiguate_non_breaking_match=letdoc="Add parentheses around matching constructs that fit on a single line."inC.flag~names:["disambiguate-non-breaking-match"]~default:false~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithdisambiguate_non_breaking_match=x}))(funconf->conf.fmt_opts.disambiguate_non_breaking_match)letdoc_comments=letdoc="Doc comments position."inletnames=["doc-comments"]inletall=[C.Value.make~name:"after-when-possible"`After_when_possible"$(b,after-when-possible) puts doc comments after the \
corresponding code. This option has no effect on variant \
declarations because that would change their meaning and on \
structures, signatures and objects for readability.";C.Value.make~name:"before-except-val"`Before_except_val"$(b,before-except-val) puts doc comments before the \
corresponding code, but puts doc comments of $(b,val) and \
$(b,external) declarations after the corresponding declarations.";C.Value.make~name:"before"`Before"$(b,before) puts comments before the corresponding code."]inC.choice~names~all~doc~kind~removed_values:[C.Value_removed.make~name:"after"~since:V0_14_2~msg:"This value has been renamed `after-when-possible` to take \
into account the technical limitations of ocamlformat, the \
behavior is unchanged."](funconfx->updateconf~f:(funf->{fwithdoc_comments=x}))(funconf->conf.fmt_opts.doc_comments)letdoc_comments_padding=letdocv="PADDING"inletdoc="Add $(docv) spaces before doc comments in type declarations."inletnames=["doc-comments-padding"]inC.anyArg.int~names~default:2~doc~docv~kind(funconfx->updateconf~f:(funf->{fwithdoc_comments_padding=x}))(funconf->conf.fmt_opts.doc_comments_padding)letdoc_comments_tag_only=letdoc="Position of doc comments with only tags."inletnames=["doc-comments-tag-only"]inletall=[C.Value.make~name:"default"`Default"$(b,default) means no special treatment.";C.Value.make~name:"fit"`Fit"$(b,fit) puts doc comments on the same line."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithdoc_comments_tag_only=x}))(funconf->conf.fmt_opts.doc_comments_tag_only)let((* doc_comments_val *))=letnames=["doc-comments-val"]inletmsg="If you are using `doc-comments-val=before` in combination with \
`doc-comments=before` then only `doc-comments=before` is now \
required to achive the same behavior. If you are using \
`doc-comments-val=before` in combination with `doc-comments=after` \
this behavior is not available anymore. If you are using \
`doc-comments-val=after` in combination with `doc-comments=before` \
please now use `doc-comments=before-except-val`. If you are using \
`doc-comments-val=after` in combination with `doc-comments=after` \
then only `doc-comments=after-when-possible` is now required to \
achieve the same behavior. If you are using `doc-comments-val=unset` \
the same behavior can now be achieved by setting `doc-comments` \
only."inC.removed_option~names~since:V0_16_0~msgletdock_collection_brackets=letdoc="Dock the brackets of lists, arrays and records, so that when the \
collection does not fit on a single line the brackets are opened on \
the preceding line and closed on the following line."inletnames=["dock-collection-brackets"]inC.flag~default:true~names~doc~kind(funconfx->updateconf~f:(funf->{fwithdock_collection_brackets=x}))(funconf->conf.fmt_opts.dock_collection_brackets)letconcrete_syntax_preserved_msg="Concrete syntax will now always be preserved."let((* escape_chars *))=letnames=["escape-chars"]inletmsg=concrete_syntax_preserved_msginC.removed_option~names~since:V0_16_0~msglet((* escape_strings *))=letnames=["escape-strings"]inletmsg=concrete_syntax_preserved_msginC.removed_option~names~since:V0_16_0~msgletexp_grouping=letdoc="Style of expression grouping."inletnames=["exp-grouping"]inletall=[C.Value.make~name:"parens"`Parens"$(b,parens) groups expressions using parentheses.";C.Value.make~name:"preserve"`Preserve"$(b,preserve) preserves the original grouping syntax \
(parentheses or $(i,begin)/$(i,end))."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithexp_grouping=x}))(funconf->conf.fmt_opts.exp_grouping)letextension_indent=letdocv="COLS"inletdoc="Indentation of items inside extension nodes ($(docv) columns)."inletnames=["extension-indent"]inC.anyArg.int~names~default:2~doc~docv~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithextension_indent=x}))(funconf->conf.fmt_opts.extension_indent)let((* extension_sugar *))=letnames=["extension-sugar"]inletmsg=concrete_syntax_preserved_msginC.removed_option~names~since:V0_17_0~msgletfield_space=letdoc="Whether or not to use a space between a field name and the rhs. This \
option affects records and objects."inletnames=["field-space"]inletall=[C.Value.make~name:"loose"`Loose"$(b,loose) does.";C.Value.make~name:"tight"`Tight"$(b,tight) does not use a space between a field name and the \
punctuation symbol (`:` or `=`).";C.Value.make~name:"tight-decl"`Tight_decl"$(b,tight-decl) is $(b,tight) for declarations and $(b,loose) \
for instantiations."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithfield_space=x}))(funconf->conf.fmt_opts.field_space)letfunction_indent=letdocv="COLS"inletdoc="Indentation of function cases ($(docv) columns)."inletnames=["function-indent"]inC.anyArg.int~names~default:2~doc~docv~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithfunction_indent=x}))(funconf->conf.fmt_opts.function_indent)letfunction_indent_nested=letdoc="Whether the $(b,function-indent) parameter should be applied even \
when in a sub-block."inletnames=["function-indent-nested"]inletall=[C.Value.make~name:"never"`Never"$(b,never) only applies $(b,function-indent) if the function \
block starts a line.";C.Value.make~name:"always"`Always"$(b,always) always apply $(b,function-indent).";C.Value.make~name:"auto"`Auto"$(b,auto) applies $(b,function-indent) when seen fit."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithfunction_indent_nested=x}))(funconf->conf.fmt_opts.function_indent_nested)letif_then_else=letdoc="If-then-else formatting."inletnames=["if-then-else"]inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) tries to format an if-then-else expression on a \
single line.";C.Value.make~name:"fit-or-vertical"`Fit_or_vertical~deprecated:deprecated_orphan"$(b,fit-or-vertical) vertically breaks branches if they do not \
fit on a single line.";C.Value.make~name:"keyword-first"`Keyword_first"$(b,keyword-first) formats if-then-else expressions such that \
the if-then-else keywords are the first on the line.";C.Value.make~name:"k-r"`K_R~deprecated:deprecated_orphan"$(b,k-r) formats if-then-else expressions with parentheses that \
match the K&R style."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithif_then_else=x}))(funconf->conf.fmt_opts.if_then_else)letindent_after_in=letdocv="COLS"inletdoc="Indentation ($(docv) columns) after `let ... in`, unless followed by \
another `let`."inletnames=["indent-after-in"]inC.anyArg.int~names~default:0~doc~docv~kind~allow_inline:false~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithindent_after_in=x}))(funconf->conf.fmt_opts.indent_after_in)letindicate_multiline_delimiters=letdoc="How to indicate that two matching delimiters live on different lines."inletnames=["indicate-multiline-delimiters"]inletall=[C.Value.make~name:"no"`No"$(b, no) doesn't do anything special to indicate the closing \
delimiter.";C.Value.make~name:"space"`Space"$(b,space) prints a space inside the delimiter to indicate the \
matching one is on a different line.";C.Value.make~name:"closing-on-separate-line"~deprecated:deprecated_orphan`Closing_on_separate_line"$(b, closing-on-separate-line) makes sure that the closing \
delimiter is on its own line."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithindicate_multiline_delimiters=x}))(funconf->conf.fmt_opts.indicate_multiline_delimiters)letindicate_nested_or_patterns=letdoc="Control whether or not to indicate nested or-pattern using \
indentation."inletnames=["indicate-nested-or-patterns"]inletall=[C.Value.make~name:"unsafe-no"`Unsafe_no"$(b,unsafe-no) does not indicate nested or-patterns. Warning: \
this can produce confusing code where a short body of a match \
case is visually hidden by surrounding long patterns, leading to \
misassociation between patterns and body expressions.";C.Value.make~name:"space"`Space"$(b,space) starts lines of nested or-patterns with \" |\" rather \
than \"| \"."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithindicate_nested_or_patterns=x}))(funconf->conf.fmt_opts.indicate_nested_or_patterns)letinfix_precedence=letdoc="Use indentation or also discretionary parentheses to explicitly \
disambiguate precedences of infix operators."inletnames=["infix-precedence"]inletall=[C.Value.make~name:"indent"`Indent"$(b,indent) uses indentation to explicitly disambiguate \
precedences of infix operators.";C.Value.make~name:"parens"`Parens"$(b,parens) uses parentheses to explicitly disambiguate \
precedences of infix operators."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithinfix_precedence=x}))(funconf->conf.fmt_opts.infix_precedence)letleading_nested_match_parens=letdoc="Nested match parens formatting."inletnames=["leading-nested-match-parens"]inC.flag~default:false~names~doc~kind~allow_inline:false(funconfx->updateconf~f:(funf->{fwithleading_nested_match_parens=x}))(funconf->conf.fmt_opts.leading_nested_match_parens)letlet_and=letdoc="Style of let_and."inletnames=["let-and"]inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) will try to format `let p = e and p = e` in a \
single line.";C.Value.make~name:"sparse"`Sparse"$(b,sparse) will always break between them."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithlet_and=x}))(funconf->conf.fmt_opts.let_and)letlet_binding_indent=letdocv="COLS"inletdoc="Indentation of let binding expressions ($(docv) columns) if they do \
not fit on a single line."inletnames=["let-binding-indent"]inC.anyArg.int~names~default:2~doc~docv~kind~allow_inline:false~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithlet_binding_indent=x}))(funconf->conf.fmt_opts.let_binding_indent)letlet_binding_spacing=letdoc="Spacing between let binding."inletnames=["let-binding-spacing"]inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) spacing separates adjacent let bindings in a module \
according to module-item-spacing.";C.Value.make~name:"sparse"`Sparse~deprecated:deprecated_orphan"$(b,sparse) places two open lines between a multi-line \
module-level let binding and the next.";C.Value.make~name:"double-semicolon"`Double_semicolon"$(b,double-semicolon) places double semicolons and an open line \
between a multi-line module-level let binding and the next."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithlet_binding_spacing=x}))(funconf->conf.fmt_opts.let_binding_spacing)letlet_module=letdoc="Module binding formatting."inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) does not break a line after the $(i,let module ... \
=) and before the $(i,in) if the module declaration does not fit \
on a single line.";C.Value.make~name:"sparse"`Sparse"$(b,sparse) breaks a line after $(i,let module ... =) and before \
the $(i,in) if the module declaration does not fit on a single \
line."]inC.choice~names:["let-module"]~all~doc~kind(funconfx->updateconf~f:(funf->{fwithlet_module=x}))(funconf->conf.fmt_opts.let_module)let((* let_open *))=letnames=["let-open"]inletmsg=concrete_syntax_preserved_msginC.removed_option~names~since:V0_17_0~msgletline_endings=letdoc="Line endings used."inletall=[C.Value.make~name:"lf"`Lf"$(b,lf) uses Unix line endings.";C.Value.make~name:"crlf"`Crlf"$(b,crlf) uses Windows line endings."]inC.choice~names:["line-endings"]~all~doc~allow_inline:false~kind(funconfx->updateconf~f:(funf->{fwithline_endings=x}))(funconf->conf.fmt_opts.line_endings)letmargin=letdocv="COLS"inletdoc="Format code to fit within $(docv) columns."inC.anyArg.int~names:["m";"margin"]~default:80~doc~docv~kind~allow_inline:false(funconfx->updateconf~f:(funf->{fwithmargin=x}))(funconf->conf.fmt_opts.margin)letmatch_indent=letdocv="COLS"inletdoc="Indentation of match/try cases ($(docv) columns)."inletnames=["match-indent"]inC.anyArg.int~names~default:0~doc~docv~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithmatch_indent=x}))(funconf->conf.fmt_opts.match_indent)letmatch_indent_nested=letdoc="Whether the $(b,match-indent) parameter should be applied even when \
in a sub-block."inletnames=["match-indent-nested"]inletall=[C.Value.make~name:"never"`Never"$(b,never) only applies $(b,match-indent) if the match block \
starts a line.";C.Value.make~name:"always"`Always"$(b,always) always apply $(b,match-indent).";C.Value.make~name:"auto"`Auto"$(b,auto) applies $(b,match-indent) when seen fit."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithmatch_indent_nested=x}))(funconf->conf.fmt_opts.match_indent_nested)letdefault_max_indent=(* Creating a fresh formatter in case the value of max-indent has been
changed for stdout. *)letfs=Format.formatter_of_buffer(Buffer.create0)inInt.to_string(Format.pp_get_max_indentfs())letmax_indent=letdocv="COLS"inletdoc="Maximum offset ($(docv) columns) added to a new line in addition to \
the offset of the previous line."inC.anyArg.(some~none:default_max_indentint)~names:["max-indent"]~doc~docv~kind~default:None~allow_inline:false(funconfx->updateconf~f:(funf->{fwithmax_indent=x}))(funconf->conf.fmt_opts.max_indent)letmodule_item_spacing=letdoc="Spacing between items of structures and signatures."inletnames=["module-item-spacing"]inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) will not leave open lines between one-liners of \
similar sorts.";C.Value.make~name:"sparse"`Sparse"$(b,sparse) will always break a line between two items.";C.Value.make~name:"preserve"`Preserve~deprecated:deprecated_orphan"$(b,preserve) will not leave open lines between one-liners of \
similar sorts unless there is an open line in the input."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithmodule_item_spacing=x}))(funconf->conf.fmt_opts.module_item_spacing)letnested_match=letdoc="Style of a pattern-matching nested in the last case of another \
pattern-matching."inletnames=["nested-match"]inletall=[C.Value.make~name:"wrap"`Wrap"$(b,wrap) wraps the nested pattern-matching with parentheses and \
adds indentation.";C.Value.make~name:"align"`Align"$(b,align) vertically aligns the nested pattern-matching under \
the encompassing pattern-matching."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithnested_match=x}))(funconf->conf.fmt_opts.nested_match)letocp_indent_compat=letdoc="Attempt to generate output which does not change (much) when \
post-processing with ocp-indent."inletnames=["ocp-indent-compat"]inC.flag~default:false~names~doc~kind(funconfx->updateconf~f:(funf->{fwithocp_indent_compat=x}))(funconf->conf.fmt_opts.ocp_indent_compat)letparens_ite=letdoc="Uses parentheses around if-then-else branches that spread across \
multiple lines."inletnames=["parens-ite"]inC.flag~default:false~names~doc~kind(funconfx->updateconf~f:(funf->{fwithparens_ite=x}))(funconf->conf.fmt_opts.parens_ite)letparens_tuple=letdoc="Parens tuple expressions."inletnames=["parens-tuple"]inletall=[C.Value.make~name:"always"`Always"$(b,always) always uses parentheses around tuples.";C.Value.make~name:"multi-line-only"`Multi_line_only"$(b,multi-line-only) mode will try to skip parens for \
single-line tuples."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithparens_tuple=x}))(funconf->conf.fmt_opts.parens_tuple)letparens_tuple_patterns=letdoc="Parens tuple patterns."inletnames=["parens-tuple-patterns"]inletall=[C.Value.make~name:"multi-line-only"`Multi_line_only"$(b,multi-line-only) mode will try to skip parens for \
single-line tuple patterns.";C.Value.make~name:"always"`Always"$(b,always) always uses parentheses around tuples patterns."]inC.choice~names~all~doc~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithparens_tuple_patterns=x}))(funconf->conf.fmt_opts.parens_tuple_patterns)letparse_docstrings=letdoc="Parse and format docstrings."inletnames=["parse-docstrings"]inC.flag~default:false~names~doc~kind(funconfx->updateconf~f:(funf->{fwithparse_docstrings=x}))(funconf->conf.fmt_opts.parse_docstrings)letparse_toplevel_phrases=letdoc="Parse and format toplevel phrases and their output."inletnames=["parse-toplevel-phrases"]inC.flag~default:false~names~doc~kind(funconfx->updateconf~f:(funf->{fwithparse_toplevel_phrases=x}))(funconf->conf.fmt_opts.parse_toplevel_phrases)letsequence_blank_line=letdoc="Blank line between expressions of a sequence."inletnames=["sequence-blank-line"]inletall=[C.Value.make~name:"preserve-one"`Preserve_one"$(b,preserve) will keep a blank line between two expressions of \
a sequence if the input contains at least one.";C.Value.make~name:"compact"`Compact"$(b,compact) will not keep any blank line between expressions of \
a sequence."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithsequence_blank_line=x}))(funconf->conf.fmt_opts.sequence_blank_line)letsequence_style=letdoc="Style of sequence."inletnames=["sequence-style"]inletall=[C.Value.make~name:"terminator"`Terminator"$(b,terminator) only puts spaces after semicolons.";C.Value.make~name:"separator"`Separator"$(b,separator) puts spaces before and after semicolons.";C.Value.make~name:"before"`Before~deprecated:deprecated_orphan"$(b,before) breaks the sequence before semicolons."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithsequence_style=x}))(funconf->conf.fmt_opts.sequence_style)letsingle_case=letdoc="Style of pattern matching expressions with only a single case."inletnames=["single-case"]inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) will try to format a single case on a single line.";C.Value.make~name:"sparse"`Sparse"$(b,sparse) will always break the line before a single case."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithsingle_case=x}))(funconf->conf.fmt_opts.single_case)letspace_around_arrays=letdoc="Add a space inside the delimiters of arrays."inletnames=["space-around-arrays"]inC.flag~default:true~names~doc~kind(funconfx->updateconf~f:(funf->{fwithspace_around_arrays=x}))(funconf->conf.fmt_opts.space_around_arrays)letspace_around_lists=letdoc="Add a space inside the delimiters of lists."inletnames=["space-around-lists"]inC.flag~default:true~names~doc~kind(funconfx->updateconf~f:(funf->{fwithspace_around_lists=x}))(funconf->conf.fmt_opts.space_around_lists)letspace_around_records=letdoc="Add a space inside the delimiters of records."inletnames=["space-around-records"]inC.flag~default:true~names~doc~kind(funconfx->updateconf~f:(funf->{fwithspace_around_records=x}))(funconf->conf.fmt_opts.space_around_records)letspace_around_variants=letdoc="Add a space inside the delimiters of variants."inletnames=["space-around-variants"]inC.flag~default:true~names~doc~kind(funconfx->updateconf~f:(funf->{fwithspace_around_variants=x}))(funconf->conf.fmt_opts.space_around_variants)letstritem_extension_indent=letdocv="COLS"inletdoc="Indentation of structure items inside extension nodes ($(docv) \
columns)."inletnames=["stritem-extension-indent"]inC.anyArg.int~names~default:0~doc~docv~kind~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithstritem_extension_indent=x}))(funconf->conf.fmt_opts.stritem_extension_indent)lettype_decl=letdoc="Style of type declaration."inletnames=["type-decl"]inletall=[C.Value.make~name:"compact"`Compact"$(b,compact) will try to format constructors and records \
definition in a single line.";C.Value.make~name:"sparse"`Sparse"$(b,sparse) will always break between constructors and record \
fields."]inC.choice~names~all~doc~kind(funconfx->updateconf~f:(funf->{fwithtype_decl=x}))(funconf->conf.fmt_opts.type_decl)lettype_decl_indent=letdocv="COLS"inletdoc="Indentation of type declarations ($(docv) columns) if they do not \
fit on a single line."inletnames=["type-decl-indent"]inC.anyArg.int~names~default:2~doc~docv~kind~allow_inline:false~status:(`Deprecateddeprecated_orphan)(funconfx->updateconf~f:(funf->{fwithtype_decl_indent=x}))(funconf->conf.fmt_opts.type_decl_indent)letwrap_comments=letdoc="Wrap comments and docstrings. Comments and docstrings are divided \
into paragraphs by open lines (two or more consecutive newlines), \
and each paragraph is wrapped at the margin. Multi-line comments \
with vertically-aligned asterisks on the left margin are not \
wrapped. Consecutive comments with both left and right margin \
aligned are not wrapped either."inC.flag~default:false~names:["wrap-comments"]~doc~kind(funconfx->updateconf~f:(funf->{fwithwrap_comments=x}))(funconf->conf.fmt_opts.wrap_comments)letwrap_fun_args=letdefault=trueinletdoc="Style for function call."inletnames=["wrap-fun-args"]inC.flag~default~names~doc~kind(funconfwrap_fun_args->updateconf~f:(funf->{fwithwrap_fun_args}))(funconf->conf.fmt_opts.wrap_fun_args)end(* Flags that can be modified in the config file that don't affect
formatting *)letkind=C.Operationalletdocs=C.section_namekind`ValidmoduleOperational=structletupdate~fc={cwithopr_opts=fc.opr_opts}letcomment_check=letdefault=trueinletdoc="Control whether to check comments and documentation comments. Unsafe \
to turn off. May be set in $(b,.ocamlformat)."inC.flag~default~names:["comment-check"]~doc~kind(funconfx->updateconf~f:(funf->{fwithcomment_check=x}))(funconf->conf.opr_opts.comment_check)letdebug=letdoc="Generate debugging output."inletdefault=falseinC.flag~default~names:["g";"debug"]~doc~kind(funconfx->updateconf~f:(funf->{fwithdebug=x}))(funconf->conf.opr_opts.debug)letdisable=letdoc="Disable ocamlformat. This is used in attributes to locally disable \
automatic code formatting. One can also use $(b,[@@@ocamlformat \
\"enable\"]) instead of $(b,[@@@ocamlformat \"disable=false\"])."inC.flag~names:["disable"]~default:false~doc~kind~allow_inline:true(funconfx->updateconf~f:(funf->{fwithdisable=x}))(funconf->conf.opr_opts.disable)letmargin_check=letdoc="Emit a warning if the formatted output exceeds the margin."inC.flag~default:false~names:["margin-check"]~doc~kind(funconfx->updateconf~f:(funf->{fwithmargin_check=x}))(funconf->conf.opr_opts.margin_check)letmax_iters=letdocv="N"inletdoc="Fail if output of formatting does not stabilize within $(docv) \
iterations. May be set in $(b,.ocamlformat)."inC.anyArg.int~names:["n";"max-iters"]~default:10~doc~docv~kind(funconfx->updateconf~f:(funf->{fwithmax_iters=x}))(funconf->conf.opr_opts.max_iters)letocaml_version=letdocv="V"inletdoc="Version of OCaml syntax of the output."inletdefault=Ocaml_version.sys_versioninletdefault_doc="the version of OCaml used to build OCamlFormat"inC.anyocaml_version_conv~names:["ocaml-version"]~default~default_doc~doc~docv~kind(funconfx->updateconf~f:(funf->{fwithocaml_version=x}))(funconf->conf.opr_opts.ocaml_version)letquiet=letdoc="Quiet. May be set in $(b,.ocamlformat)."inC.flag~default:false~names:["q";"quiet"]~doc~kind(funconfx->updateconf~f:(funf->{fwithquiet=x}))(funconf->conf.opr_opts.quiet)endletdisable_conf_attrs=letdoc="Disable configuration in attributes."inmk~default:falseArg.(value&flag&info["disable-conf-attrs"]~doc~docs)letdisable_conf_files=letdoc="Disable .ocamlformat configuration files."inmk~default:falseArg.(value&flag&info["disable-conf-files"]~doc~docs)letdisable_outside_detected_project=letdoc=Format.sprintf"$(b,Warning:) this option is $(b,deprecated) and will be removed by \
OCamlFormat v1.0."inletdefault=falseinletdeprecated=C.deprecated~since:V0_10_0removed_by_v1_0inletdocs=C.section_nameOperational(`Deprecateddeprecated)inmk~defaultArg.(value&flag&info["disable-outside-detected-project"]~doc~docs)letenable_outside_detected_project=letwitness=String.concat~sep:" or "(List.mapFile_system.project_root_witness~f:(funname->Format.sprintf"$(b,%s)"name))inletdoc=Format.sprintf"Read $(b,.ocamlformat) config files outside the current project. The \
project root of an input file is taken to be the nearest ancestor \
directory that contains a %s file. Formatting is enabled even if no \
$(b,.ocamlformat) configuration file is found."witnessinletdefault=falseinmk~defaultArg.(value&flag&info["enable-outside-detected-project"]~doc~docs)(* Other Flags *)letcheck=letdoc="Check whether the input files already are formatted. Mutually \
exclusive with --inplace and --output."inmk~default:falseArg.(value&flag&info["check"]~doc~docs)letconfig=letdoc="Aggregate options. Options are specified as a comma-separated list of \
pairs: \
$(i,option)$(b,=)$(i,VAL)$(b,,)...$(b,,)$(i,option)$(b,=)$(i,VAL)."inletenv=Cmd.Env.info"OCAMLFORMAT"inletdefault=[]inletassoc=Arg.(pair~sep:'='stringstring)inletlist_assoc=Arg.(list~sep:','assoc)inmk~defaultArg.(value&optlist_assocdefault&info["c";"config"]~doc~docs~env)letinplace=letdoc="Format in-place, overwriting input file(s)."inletdefault=falseinmk~defaultArg.(value&flag&info["i";"inplace"]~doc~docs)typefile=Stdin|Fileofstringletinputs=letdocv="SRC"inletfile_or_dash=letparse,print=Arg.non_dir_fileinletprintfmt=function|Stdin->printfmt"<standard input>"|Filex->printfmtxinletparse=function|"-"->`OkStdin|s->(matchparseswith`Okx->`Ok(Filex)|`Errorx->`Errorx)in(parse,print)inletdoc="Input files. At least one is required, and exactly one without \
$(b,--inplace). If $(b,-) is passed, will read from stdin."inletdefault=[]inmk~defaultArg.(value&pos_allfile_or_dashdefault&info[]~doc~docv~docs)letkind:Syntax.toptionref=letdoc="Parse input as an implementation."inletimpl=(SomeSyntax.Use_file,Arg.info["impl"]~doc~docs)inletdoc="Parse input as an interface."inletintf=(SomeSyntax.Signature,Arg.info["intf"]~doc~docs)inletdoc="Deprecated. Same as $(b,impl)."inletuse_file=(SomeSyntax.Use_file,Arg.info["use-file"]~doc~docs)inletdoc="Parse input as toplevel phrases with their output."inletrepl_file=(SomeSyntax.Repl_file,Arg.info["repl-file"]~doc~docs)inletdefault=Noneinmk~defaultArg.(value&vflagdefault[impl;intf;use_file;repl_file])letname=letdocv="NAME"inletdoc="Name of input file for use in error reporting and starting point when \
searching for '.ocamlformat' files. Defaults to the input file name. \
Some options can be specified in configuration files named \
'.ocamlformat' in the same or a parent directory of $(docv), see \
documentation of other options for details."inletdefault=Noneinmk~defaultArg.(value&opt(somestring)default&info["name"]~doc~docs~docv)letnumeric=letdoc="Instead of re-formatting the file, output one integer per line \
corresponding to the indentation value, printing as many values as \
lines in the range between lines X and Y (included)."inletdefault=Noneinletdocv="X-Y"inmk~defaultArg.(value&opt(some(pair~sep:'-'intint))default&info["numeric"]~doc~docs~docv)letocp_indent_options=letunsupportedocp_indent=(ocp_indent,([],""))inletaliasocp_indentocamlformat=(ocp_indent,([ocamlformat],Printf.sprintf"$(b,%s) is an alias for $(b,%s)."ocp_indentocamlformat))inletmulti_aliasocp_indentl_ocamlformat=(ocp_indent,(l_ocamlformat,Format.asprintf"$(b,%s) sets %a."ocp_indent(Format.pp_print_list~pp_sep:(funfs()->Format.fprintffs" and ")(funfsx->Format.fprintffs"$(b,%s)"x))l_ocamlformat))in[alias"base""let-binding-indent";alias"type""type-decl-indent";alias"in""indent-after-in";multi_alias"with"["function-indent";"match-indent"];alias"match_clause""cases-exp-indent";alias"ppx_stritem_ext""stritem-extension-indent";alias"max_indent""max-indent";multi_alias"strict_with"["function-indent-nested";"match-indent-nested"];unsupported"strict_else";unsupported"strict_comments";unsupported"align_ops";unsupported"align_params"]letocp_indent_config=letdoc=letopenFormatinletsupported=letonly_doc(_,(_,doc))=Option.some_if(not(String.is_emptydoc))docinletl=List.filter_mapocp_indent_options~f:only_docinifList.is_emptylthen""elseasprintf" %a"(pp_print_list~pp_sep:(funfs()->fprintffs"@ ")(funfss->fprintffs"%s"s))linasprintf"Read .ocp-indent configuration files.%s"supportedinletdefault=falseinmk~defaultArg.(value&flag&info["ocp-indent-config"]~doc~docs)letoutput=letdocv="DST"inletdoc="Output file. Mutually exclusive with --inplace. Write to stdout if \
omitted."inletdefault=Noneinmk~defaultArg.(value&opt(somestring)default&info["o";"output"]~doc~docs~docv)letprint_config=letdoc="Print the configuration determined by the environment variable, the \
configuration files, preset profiles and command line. Attributes are \
not considered. If many input files are specified, only print the \
configuration for the first file. If no input file is specified, print \
the configuration for the root directory if specified, or for the \
current working directory otherwise."inletdefault=falseinmk~defaultArg.(value&flag&info["print-config"]~doc~docs)letroot=letdocv="DIR"inletdoc="Root of the project. If specified, only take into account .ocamlformat \
configuration files inside $(docv) and its subdirectories."inletdefault=Noneinmk~defaultArg.(value&opt(somedir)default&info["root"]~doc~docs~docv)letno_version_check=letdoc="Do not check that the version matches the one specified in \
.ocamlformat."inletdefault=falseinmk~defaultArg.(value&flag&info["no-version-check"]~doc~docs)letignore_invalid_options=letdoc="Ignore invalid options (e.g. in .ocamlformat)."inletdefault=falseinmk~defaultArg.(value&flag&info["ignore-invalid-option"]~doc~docs)letocamlformat_profile={align_cases=false;align_constructors_decl=false;align_variants_decl=false;assignment_operator=`End_line;break_before_in=`Fit_or_vertical;break_cases=`Nested;break_collection_expressions=`Fit_or_vertical;break_infix=`Wrap;break_infix_before_func=true;break_fun_decl=`Wrap;break_fun_sig=`Wrap;break_separators=`Before;break_sequences=false;break_string_literals=`Auto;break_struct=true;cases_exp_indent=4;cases_matching_exp_indent=`Compact;disambiguate_non_breaking_match=false;doc_comments=`Before_except_val;doc_comments_padding=2;doc_comments_tag_only=`Default;dock_collection_brackets=false;exp_grouping=`Parens;extension_indent=2;field_space=`Tight;function_indent=2;function_indent_nested=`Never;if_then_else=`Compact;indent_after_in=0;indicate_multiline_delimiters=`Space;indicate_nested_or_patterns=`Space;infix_precedence=`Indent;leading_nested_match_parens=false;let_and=`Compact;let_binding_indent=2;let_binding_spacing=`Compact;let_module=`Compact;line_endings=`Lf;margin=80;match_indent=0;match_indent_nested=`Never;max_indent=None;module_item_spacing=`Sparse;nested_match=`Wrap;ocp_indent_compat=false;parens_ite=false;parens_tuple=`Always;parens_tuple_patterns=`Multi_line_only;parse_docstrings=false;parse_toplevel_phrases=false;sequence_blank_line=`Compact;sequence_style=`Separator;single_case=`Compact;space_around_arrays=false;space_around_lists=false;space_around_records=false;space_around_variants=false;stritem_extension_indent=0;type_decl=`Compact;type_decl_indent=2;wrap_comments=false;wrap_fun_args=true}letconventional_profile={align_cases=C.defaultFormatting.align_cases;align_constructors_decl=C.defaultFormatting.align_constructors_decl;align_variants_decl=C.defaultFormatting.align_variants_decl;assignment_operator=C.defaultFormatting.assignment_operator;break_before_in=C.defaultFormatting.break_before_in;break_cases=C.defaultFormatting.break_cases;break_collection_expressions=C.defaultFormatting.break_collection_expressions;break_infix=C.defaultFormatting.break_infix;break_infix_before_func=C.defaultFormatting.break_infix_before_func;break_fun_decl=C.defaultFormatting.break_fun_decl;break_fun_sig=C.defaultFormatting.break_fun_sig;break_separators=C.defaultFormatting.break_separators;break_sequences=C.defaultFormatting.break_sequences;break_string_literals=C.defaultFormatting.break_string_literals;break_struct=Poly.(C.defaultFormatting.break_struct=`Force);cases_exp_indent=C.defaultFormatting.cases_exp_indent;cases_matching_exp_indent=C.defaultFormatting.cases_matching_exp_indent;disambiguate_non_breaking_match=C.defaultFormatting.disambiguate_non_breaking_match;doc_comments=C.defaultFormatting.doc_comments;doc_comments_padding=C.defaultFormatting.doc_comments_padding;doc_comments_tag_only=C.defaultFormatting.doc_comments_tag_only;dock_collection_brackets=C.defaultFormatting.dock_collection_brackets;exp_grouping=C.defaultFormatting.exp_grouping;extension_indent=C.defaultFormatting.extension_indent;field_space=C.defaultFormatting.field_space;function_indent=C.defaultFormatting.function_indent;function_indent_nested=C.defaultFormatting.function_indent_nested;if_then_else=C.defaultFormatting.if_then_else;indent_after_in=C.defaultFormatting.indent_after_in;indicate_multiline_delimiters=C.defaultFormatting.indicate_multiline_delimiters;indicate_nested_or_patterns=C.defaultFormatting.indicate_nested_or_patterns;infix_precedence=C.defaultFormatting.infix_precedence;leading_nested_match_parens=C.defaultFormatting.leading_nested_match_parens;let_and=C.defaultFormatting.let_and;let_binding_indent=C.defaultFormatting.let_binding_indent;let_binding_spacing=C.defaultFormatting.let_binding_spacing;let_module=C.defaultFormatting.let_module;line_endings=C.defaultFormatting.line_endings;margin=C.defaultFormatting.margin;match_indent=C.defaultFormatting.match_indent;match_indent_nested=C.defaultFormatting.match_indent_nested;max_indent=C.defaultFormatting.max_indent;module_item_spacing=C.defaultFormatting.module_item_spacing;nested_match=C.defaultFormatting.nested_match;ocp_indent_compat=C.defaultFormatting.ocp_indent_compat;parens_ite=C.defaultFormatting.parens_ite;parens_tuple=C.defaultFormatting.parens_tuple;parens_tuple_patterns=C.defaultFormatting.parens_tuple_patterns;parse_docstrings=C.defaultFormatting.parse_docstrings;parse_toplevel_phrases=C.defaultFormatting.parse_toplevel_phrases;sequence_blank_line=C.defaultFormatting.sequence_blank_line;sequence_style=C.defaultFormatting.sequence_style;single_case=C.defaultFormatting.single_case;space_around_arrays=C.defaultFormatting.space_around_arrays;space_around_lists=C.defaultFormatting.space_around_lists;space_around_records=C.defaultFormatting.space_around_records;space_around_variants=C.defaultFormatting.space_around_variants;stritem_extension_indent=C.defaultFormatting.stritem_extension_indent;type_decl=C.defaultFormatting.type_decl;type_decl_indent=C.defaultFormatting.type_decl_indent;wrap_comments=C.defaultFormatting.wrap_comments;wrap_fun_args=C.defaultFormatting.wrap_fun_args}letdefault_profile=conventional_profileletcompact_profile={ocamlformat_profilewithbreak_before_in=`Auto;break_cases=`Fit;break_collection_expressions=`Wrap;break_infix=`Wrap;break_fun_decl=`Wrap;break_fun_sig=`Wrap;break_sequences=false;break_struct=false;doc_comments_tag_only=`Fit;exp_grouping=`Parens;field_space=`Tight;if_then_else=`Compact;indicate_nested_or_patterns=`Space;leading_nested_match_parens=false;let_and=`Compact;let_binding_spacing=`Compact;let_module=`Compact;module_item_spacing=`Compact;single_case=`Compact;space_around_arrays=false;space_around_lists=false;space_around_records=false;space_around_variants=false;type_decl=`Compact;wrap_fun_args=true}letsparse_profile={ocamlformat_profilewithbreak_before_in=`Fit_or_vertical;break_cases=`Nested;break_collection_expressions=`Fit_or_vertical;break_infix=`Fit_or_vertical;break_fun_decl=`Smart;break_fun_sig=`Smart;break_sequences=true;break_struct=true;field_space=`Loose;if_then_else=`Keyword_first;indicate_nested_or_patterns=`Space;leading_nested_match_parens=true;let_and=`Sparse;let_binding_spacing=`Sparse;let_module=`Sparse;module_item_spacing=`Sparse;single_case=`Sparse;sequence_blank_line=`Preserve_one;space_around_arrays=true;space_around_lists=true;space_around_records=true;space_around_variants=true;type_decl=`Sparse;wrap_fun_args=false}letjanestreet_profile={align_constructors_decl=false;align_cases=false;align_variants_decl=false;assignment_operator=`Begin_line;break_before_in=`Fit_or_vertical;break_cases=`Fit_or_vertical;break_collection_expressions=ocamlformat_profile.break_collection_expressions;break_infix=`Fit_or_vertical;break_infix_before_func=true;break_fun_decl=`Fit_or_vertical;break_fun_sig=`Fit_or_vertical;break_separators=`Before;break_sequences=true;break_string_literals=`Auto;break_struct=ocamlformat_profile.break_struct;cases_exp_indent=2;cases_matching_exp_indent=`Normal;disambiguate_non_breaking_match=false;doc_comments=`Before;doc_comments_padding=1;doc_comments_tag_only=`Fit;dock_collection_brackets=false;exp_grouping=`Parens;extension_indent=2;field_space=`Loose;function_indent=2;function_indent_nested=`Never;if_then_else=`Keyword_first;indent_after_in=0;indicate_multiline_delimiters=`No;indicate_nested_or_patterns=`Unsafe_no;infix_precedence=`Parens;leading_nested_match_parens=true;let_and=`Sparse;let_binding_indent=2;let_binding_spacing=`Double_semicolon;let_module=`Sparse;line_endings=`Lf;margin=90;match_indent=0;match_indent_nested=`Never;max_indent=None;module_item_spacing=`Compact;nested_match=`Wrap;ocp_indent_compat=true;parens_ite=true;parens_tuple=`Multi_line_only;parens_tuple_patterns=`Multi_line_only;parse_docstrings=false;parse_toplevel_phrases=false;sequence_blank_line=`Compact;sequence_style=`Terminator;single_case=`Sparse;space_around_arrays=true;space_around_lists=true;space_around_records=true;space_around_variants=true;stritem_extension_indent=0;type_decl=`Sparse;type_decl_indent=2;wrap_comments=false;wrap_fun_args=false}letselected_profile_ref=ref(Somedefault_profile)let(_profile:fmt_optsoptionC.t)=letdoc="Select a preset profile which sets $(i,all) options, overriding lower \
priority configuration."inletnames=profile_option_namesinletall=[C.Value.make~name:"conventional"(Someconventional_profile)"The $(b,conventional) profile aims to be as familiar and \
\"conventional\" appearing as the available options allow.";C.Value.make~name:"default"(Somedefault_profile)"$(b,default) is an alias for the $(b,conventional) profile.";C.Value.make~name:"compact"(Somecompact_profile)~deprecated:deprecated_orphan"The $(b,compact) profile is similar to $(b,ocamlformat) but opts \
for a generally more compact code style.";C.Value.make~name:"sparse"(Somesparse_profile)~deprecated:deprecated_orphan"The $(b,sparse) profile is similar to $(b,ocamlformat) but opts \
for a generally more sparse code style.";C.Value.make~name:"ocamlformat"(Someocamlformat_profile)"The $(b,ocamlformat) profile aims to take advantage of the \
strengths of a parsetree-based auto-formatter, and to limit the \
consequences of the weaknesses imposed by the current \
implementation. This is a style which optimizes for what the \
formatter can do best, rather than to match the style of any \
existing code. General guidelines that have directed the design \
include: Legibility, in the sense of making it as hard as possible \
for quick visual parsing to give the wrong interpretation, is of \
highest priority; Whenever possible the high-level structure of \
the code should be obvious by looking only at the left margin, in \
particular, it should not be necessary to visually jump from left \
to right hunting for critical keywords, tokens, etc; All else \
equal compact code is preferred as reading without scrolling is \
easier, so indentation or white space is avoided unless it helps \
legibility; Attention has been given to making some syntactic \
gotchas visually obvious.";C.Value.make~name:"janestreet"(Somejanestreet_profile)"The $(b,janestreet) profile is used at Jane Street."]inC.choice~names~all~doc~kind:C.Formatting(funconfp->selected_profile_ref:=p;letnew_fmt_opts=Option.valuep~default:conf.fmt_optsin{confwithfmt_opts=new_fmt_opts})(fun_->!selected_profile_ref)letocp_indent_normal_profile=[("base","2");("type","2");("in","0");("with","0");("match_clause","2");("ppx_stritem_ext","2");("max_indent","4");("strict_with","never");("strict_else","always");("strict_comments","false");("align_ops","true");("align_params","auto")]letocp_indent_apprentice_profile=[("base","2");("type","4");("in","2");("with","2");("match_clause","4");("ppx_stritem_ext","2");("strict_with","never");("strict_else","always");("strict_comments","false");("align_ops","true");("align_params","always")]letocp_indent_janestreet_profile=[("base","2");("type","2");("in","0");("with","0");("match_clause","2");("ppx_stritem_ext","2");("max_indent","2");("strict_with","auto");("strict_else","always");("strict_comments","true");("align_ops","true");("align_params","always")]letparse_lineconfig~froms=letupdate~config~from~name~value=letname=String.stripnameinletvalue=String.stripvalueinmatch(name,from)with|"version",`File_->ifString.equalVersion.currentvalue||!no_version_checkthenOkconfigelseError(Config_option.Error.Bad_value(name,Format.sprintf"expecting %S but got %S"Version.currentvalue))|name,`Filex->C.update~config~from:(`Parsed(`Filex))~name~value~inline:false|name,`Attribute->if!disable_conf_attrsthen(warn"Configuration in attribute %S ignored."s;Okconfig)elseC.update~config~from:(`Parsed`Attribute)~name~value~inline:trueinletupdate_ocp_indent_option~config~from~name~value=letequal=String.equalinmatchList.Assoc.findocp_indent_options~equalnamewith|None->Okconfig|Some(l,_doc)->letupdate_oneconfigname=update~config~from~name~valueinList.fold_resultl~init:config~f:update_oneinletrecupdate_many~config~from=function|[]->Okconfig|(name,value)::t->(matchupdate_ocp_indent_option~config~from~name~valuewith|Okc->update_many~config:c~fromt|Errore->Errore)inlets=matchString.indexs'#'with|Somei->String.subs~pos:0~len:i|None->sinlets=String.stripsinmatchString.split~on:'='swith|[]|[""]->Okconfig|[name;value]->letname=String.stripnameinletvalue=String.stripvalueinifList.Assoc.memocp_indent_options~equal:String.equalnamethenupdate_ocp_indent_option~config~from~name~valueelseupdate~config~from~name~value|[s]->(matchString.stripswith|""->impossible"previous match"(* special case for disable/enable *)|"enable"->update~config~from~name:"disable"~value:"false"|"normal"->update_many~config~fromocp_indent_normal_profile|"apprentice"->update_many~config~fromocp_indent_apprentice_profile|"JaneStreet"->Result.(>>=)(update~config~from~name:"profile"~value:"janestreet")(funconfig->update_many~config~fromocp_indent_janestreet_profile)|name->update~config~from~name~value:"true")|_->Error(Config_option.Error.Malformeds)(** Do not escape from [build_config] *)exceptionConf_errorofstringletfailwith_user_errors~fromerrors=letopenFormatinletpp_errorppe=pp_print_stringpp(Config_option.Error.to_stringe)inletpp_errors=pp_print_list~pp_sep:pp_print_newlinepp_errorinletmsg=asprintf"Error while parsing %s:@ %a"frompp_errorserrorsinraise(Conf_errormsg)letread_config_fileconf=function|File_system.Ocp_indent_whennot!ocp_indent_config->conf|File_system.Ocp_indentfile|File_system.Ocamlformatfile->(letfilename=Fpath.to_stringfileintryIn_channel.with_filefilename~f:(funic->letc,errors,_=In_channel.fold_linesic~init:(conf,[],1)~f:(fun(conf,errors,num)line->letfrom=`File(file,num)inmatchparse_lineconf~fromlinewith|Okconf->(conf,errors,Int.succnum)|Error_when!ignore_invalid_options->warn~filename:file~lnum:num"ignoring invalid options %S"line;(conf,errors,Int.succnum)|Errore->(conf,e::errors,Int.succnum))inmatchList.reverrorswith|[]->c|l->failwith_user_errors~from:filenamel)withSys_error_->conf)letupdate_using_envconf=letf(config,errors)(name,value)=matchC.update~config~from:`Env~name~value~inline:falsewith|Okc->(c,errors)|Errore->(config,e::errors)inletconf,errors=List.fold_left!config~init:(conf,[])~finmatchList.reverrorswith|[]->conf|l->failwith_user_errors~from:"OCAMLFORMAT environment variable"lletis_in_listing_file~listings~filename=letdrop_linel=String.is_emptyl||String.is_prefixl~prefix:"#"in(* process deeper files first *)letlistings=List.revlistingsinList.find_maplistings~f:(funlisting_file->letdir,_=Fpath.split_baselisting_fileintryIn_channel.with_file(Fpath.to_stringlisting_file)~f:(funch->letlines=In_channel.input_linesch|>List.mapi~f:(funis->(i+1,String.strips))|>List.filter~f:(fun(_,l)->not(drop_linel))inList.find_maplines~f:(fun(lno,line)->matchFpath.of_stringlinewith|Okfile_on_current_line->(letf=Fpath.(dir//file_on_current_line)inifFpath.equalfilenamefthenSome(listing_file,lno)elsetryletfilename=Fpath.to_stringfilenameinletre=letpathname=trueandanchored=trueinletf=Fpath.to_stringfinRe.(Glob.glob~pathname~anchoredf|>compile)inOption.some_if(Re.execprefilename)(listing_file,lno)withRe.Glob.Parse_error->warn~filename:listing_file~lnum:lno"pattern %s cannot be parsed"line;None)|Error(`Msgmsg)->warn~filename:listing_file~lnum:lno"%s"msg;None))withSys_errorerr->warn"ignoring %a, %s"Fpath.pplisting_fileerr;None)letdefault={fmt_opts=default_profile;opr_opts={comment_check=C.defaultOperational.comment_check;debug=C.defaultOperational.debug;disable=C.defaultOperational.disable;margin_check=C.defaultOperational.margin_check;max_iters=C.defaultOperational.max_iters;ocaml_version=C.defaultOperational.ocaml_version;quiet=C.defaultOperational.quiet}}letbuild_config~enable_outside_detected_project~root~file~is_stdin=letvfile=Fpath.vfileinletfile_abs=Fpath.(vfile|>to_absolute|>normalize)inletfs=File_system.make~enable_outside_detected_project~disable_conf_files:!disable_conf_files~root~file:file_absinletconf=List.foldfs.configuration_files~init:default~f:read_config_file|>update_using_env|>C.update_using_cmdlineinletno_ocamlformat_files=List.for_allfs.configuration_files~f:File_system.is_ocp_indent_fileinif(notis_stdin)&&no_ocamlformat_files&¬enable_outside_detected_projectthen((letwhy=matchfs.project_rootwith|Someroot->Format.sprintf"no [.ocamlformat] was found within the project (root: %s)"(Fpath.to_string~relativize:trueroot)|None->"no project root was found"inwarn~filename:vfile"Ocamlformat disabled because [--enable-outside-detected-project] is \
not set and %s"why);Operational.updateconf~f:(funf->{fwithdisable=true}))elseletlistings=ifconf.opr_opts.disablethenfs.enable_fileselsefs.ignore_filesinmatchis_in_listing_file~listings~filename:file_abswith|Some(file,lno)->letstatus=ifconf.opr_opts.disablethen"enabled"else"ignored"inifconf.opr_opts.debugthenFormat.eprintf"File %a: %s in %a:%d@\n"Fpath.ppfile_absstatusFpath.ppfilelno;Operational.updateconf~f:(funf->{fwithdisable=notf.disable})|None->confletbuild_config~enable_outside_detected_project~root~file~is_stdin=tryletconf,warn_now=collect_warnings(fun()->build_config~enable_outside_detected_project~root~file~is_stdin)inifnotconf.opr_opts.quietthenwarn_now();OkconfwithConf_errormsg->Errormsgletkind_of_extfname=matchFilename.extensionfnamewith|".ml"|".mlt"|".eliom"->SomeSyntax.Use_file|".mli"|".eliomi"->SomeSyntax.Signature|_->Noneletvalidate_inputs()=match(!inputs,!kind,!name)with|[],_,_->Ok`No_input|[Stdin],None,None->Error"Must specify at least one of --name, --impl or --intf when reading \
from stdin"|[Stdin],Somekind,name->Ok(`Stdin(name,kind))|[Stdin],None,Somename->(matchkind_of_extnamewith|Somekind->Ok(`Stdin(Somename,kind))|None->Error"Cannot deduce file kind from passed --name. Please specify \
--impl or --intf")|[Filef],Somekind,name->Ok(`Single_file(kind,name,f))|[Filef],None,name->letkind=Option.value~default:fname|>kind_of_ext|>Option.value~default:Syntax.Use_fileinOk(`Single_file(kind,name,f))|_::_::_,Some_,_->Error"Cannot specify --impl or --intf with multiple inputs"|_::_::_,_,Some_->Error"Cannot specify --name with multiple inputs"|(_::_::_asinputs),None,None->List.mapinputs~f:(function|Stdin->Error"Cannot specify stdin together with other inputs"|Filef->letkind=Option.value~default:Use_file(kind_of_extf)inOk(kind,f))|>Result.all|>Result.map~f:(funfiles->`Several_filesfiles)letvalidate_action()=matchList.filter_map~f:(funs->s)[Option.map~f:(funo->(`Outputo,"--output"))!output;Option.some_if!inplace(`Inplace,"--inplace");Option.some_if!check(`Check,"--check");Option.some_if!print_config(`Print_config,"--print-config");Option.map~f:(funr->(`Numericr,"--numeric"))!numeric]with|[]->Ok`No_action|[(action,_)]->Okaction|(_,a1)::(_,a2)::_->Error(Printf.sprintf"Cannot specify %s with %s"a1a2)typeinput={kind:Syntax.t;name:string;file:file;conf:t}typeaction=|In_outofinput*stringoption|Inplaceofinputlist|Checkofinputlist|Print_configoft|Numericofinput*(int*int)letmake_action~enable_outside_detected_project~rootactioninputs=letopenResultinletmake_file?(with_conf=func->c)?namekindfile=letname=Option.value~default:filenameinbuild_config~enable_outside_detected_project~root~file:name~is_stdin:false>>=funconf->Ok{kind;name;file=Filefile;conf=with_confconf}inletmake_stdin?(name="<standard input>")kind=build_config~enable_outside_detected_project~root~file:name~is_stdin:false>>=funconf->Ok{kind;name;file=Stdin;conf}inletmake_input=function|`Single_file(kind,name,f)->make_file?namekindf|`Stdin(name,kind)->make_stdin?namekindinletmake_inputs=function|(`Single_file_|`Stdin_)asinp->make_inputinp>>=funinp->Ok[inp]|`Several_filesfiles->(letf(kind,f)=make_filekindfinmatchList.mapfiles~f|>List.partition_resultwith|_,e::_->Errore|inputs,[]->Okinputs)inmatch(action,inputs)with|`Print_config,inputs->letfile,is_stdin=matchinputswith|`Stdin_->("-",true)|`Single_file(_,_,f)->(f,false)|`Several_files((_,f)::_)->(f,false)|`Several_files[]|`No_input->(File_system.root_ocamlformat_file~root|>Fpath.to_string,true)inbuild_config~enable_outside_detected_project~root~file~is_stdin>>=funconf->Ok(Print_configconf)|(`No_action|`Output_|`Inplace|`Check|`Numeric_),`No_input->Error"Must specify at least one input file, or `-` for stdin"|(`No_action|`Output_|`Numeric_),`Several_files_->Error"Must specify exactly one input file without --inplace or --check"|`Inplace,`Stdin_->Error"Cannot specify stdin together with --inplace"|`No_action,((`Single_file_|`Stdin_)asinp)->make_inputinp>>=funinp->Ok(In_out(inp,None))|`Outputoutput,((`Single_file_|`Stdin_)asinp)->make_inputinp>>=funinp->Ok(In_out(inp,Someoutput))|`Inplace,((`Single_file_|`Several_files_)asinputs)->make_inputsinputs>>=funinputs->Ok(Inplaceinputs)|`Check,((`Single_file_|`Several_files_|`Stdin_)asinputs)->make_inputsinputs>>=funinputs->Ok(Checkinputs)|`Numericrange,((`Stdin_|`Single_file_)asinp)->make_inputinp>>=funinp->Ok(Numeric(inp,range))letvalidate()=letroot=Option.map!root~f:Fpath.(funx->vx|>to_absolute|>normalize)inletenable_outside_detected_project=!enable_outside_detected_project&&Option.is_nonerootinif!disable_outside_detected_projectthenwarn"option `--disable-outside-detected-project` is deprecated and will \
be removed in OCamlFormat v1.0.";matchletopenResultinvalidate_action()>>=funaction->validate_inputs()>>=funinputs->make_action~enable_outside_detected_project~rootactioninputswith|Errore->`Error(false,e)|Okaction->`Okactionletaction()=parseinfovalidateopenExtended_astletupdate?(quiet=false)c{attr_name={txt;loc};attr_payload;_}=letresult=matchtxtwith|"ocamlformat"->(matchattr_payloadwith|PStr[{pstr_desc=Pstr_eval({pexp_desc=Pexp_constant{pconst_desc=Pconst_string(str,_,None);_};pexp_attributes=[];_},[]);_}]->parse_line~from:`Attributecstr|>Result.map_error~f:Config_option.Error.to_string|_->Error"Invalid format: String expected")|_whenString.is_prefix~prefix:"ocamlformat."txt->Error(Format.sprintf"Invalid format: Unknown suffix %S"(String.chop_prefix_exn~prefix:"ocamlformat."txt))|_->Okcinmatchresultwith|Okconf->conf|Errorerror->letw=Warnings.Attribute_payload(txt,error)inif(notc.opr_opts.quiet)&¬quietthenWarning.print_warninglocw;cletupdate_valueconfig~name~value=C.update~config~from:`Commandline~name~value~inline:falseletprint_config=C.print_config