Organisationsocaml-ppxocamlformat

ocamlformat

https://github.com/ocaml-ppx/ocamlformat
Branches (4)
fix-lexer-error-message
Print readable error messages in doc code blocks When parsing fails inside a `{@ocaml[...]}` block, the catch-all branch formatted the exception with `Exn.pp`, which for `Lexer.Error` produced the raw constructor pattern `Ocamlformat_parser_extended.Lexer.Error(_, _)`. `Lexer.Error` (and most other compiler-libs exceptions) register a printer via `Location.register_error_of_exn`, but that table is separate from the `Printexc` table `Exn.pp` consults, so the printer was never used. Route the catch-all through `Location.error_of_exn` instead: if a printer is registered, format its `main` message; otherwise fall back to `Exn.pp`. This handles `Lexer.Error` and any other registered exception (e.g. parser internals) without per-variant enumeration. The .err diff against the previous commit shows the before/after for the six variants the regression test exercises.
0b8ec2
metaocaml
Add MetaOCaml support Add a --metaocaml flag to enable MetaOCaml syntax (brackets .< >., escape .~, run .!) in the lexer and formatter. Lexer changes: - Split symbolchar into symbolcharnodot/symbolchar to avoid capturing MetaOCaml tokens as operator characters - Gate .~ (escape) and >. (bracket close) behind the metaocaml flag; .< (bracket open) is always lexed as METAOCAML_BRACKET_OPEN - Add symbolchars sub-lexer for consuming remaining operator chars after >. when metaocaml is disabled - Thread ~metaocaml through parse.ml to set lex_metaocaml ref Formatter changes: - Detect metaocaml.bracket and metaocaml.escape extension nodes (synthetic, with ghost loc) and render them with sugar syntax (.< expr >. and .~expr) instead of [%metaocaml.bracket ...] - Parenthesize .~ argument unless it is a simple identifier - Skip comment relocation for metaocaml extension nodes in Cmts Configuration: - Add metaocaml boolean to opr_opts (Conf_t), default false - Wire --metaocaml/--no-metaocaml flag through Conf and CLI - Thread ~metaocaml through Extended_ast, Std_ast, Parse_with_comments, Toplevel_lexer
d974c1
mll-support
FMT
c7659b
simplify-extended-std-ast
Misc: fmt
2edc18
Refs Branches (6)
Initial support for metaocaml
Add MetaOCaml support Add a --metaocaml flag to enable MetaOCaml syntax (brackets .< >., escape .~, run .!) in the lexer and formatter. Lexer changes: - Split symbolchar into symbolcharnodot/symbolchar to avoid capturing MetaOCaml tokens as operator characters - Gate .~ (escape) and >. (bracket close) behind the metaocaml flag; .< (bracket open) is always lexed as METAOCAML_BRACKET_OPEN - Add symbolchars sub-lexer for consuming remaining operator chars after >. when metaocaml is disabled - Thread ~metaocaml through parse.ml to set lex_metaocaml ref Formatter changes: - Detect metaocaml.bracket and metaocaml.escape extension nodes (synthetic, with ghost loc) and render them with sugar syntax (.< expr >. and .~expr) instead of [%metaocaml.bracket ...] - Parenthesize .~ argument unless it is a simple identifier - Skip comment relocation for metaocaml extension nodes in Cmts Configuration: - Add metaocaml boolean to opr_opts (Conf_t), default false - Wire --metaocaml/--no-metaocaml flag through Conf and CLI - Thread ~metaocaml through Extended_ast, Std_ast, Parse_with_comments, Toplevel_lexer
d974c1
#2630
Add neocaml-mode support to ocamlformat-before-save
Add changelog entry for neocaml-mode support
53e1c0
#2787
Simplify Extended_ast vs Std_ast
Misc: fmt
2edc18
#2791
Add ocamllex (.mll) file formatting support
FMT
c7659b
#2792
Print readable error messages in doc code blocks
Print readable error messages in doc code blocks When parsing fails inside a `{@ocaml[...]}` block, the catch-all branch formatted the exception with `Exn.pp`, which for `Lexer.Error` produced the raw constructor pattern `Ocamlformat_parser_extended.Lexer.Error(_, _)`. `Lexer.Error` (and most other compiler-libs exceptions) register a printer via `Location.register_error_of_exn`, but that table is separate from the `Printexc` table `Exn.pp` consults, so the printer was never used. Route the catch-all through `Location.error_of_exn` instead: if a printer is registered, format its `main` message; otherwise fall back to `Exn.pp`. This handles `Lexer.Error` and any other registered exception (e.g. parser internals) without per-variant enumeration. The .err diff against the previous commit shows the before/after for the six variants the regression test exercises.
0b8ec2
#2803
More `if-then-else=fit-or-vertical` fixes
Rework begin match/if branch layout (review follow-up) Reworks the previous fix (e3babbb1) per review. The earlier version special-cased `ctx0=ifthenelse` in `fmt_beginend` to handle a comment before a `begin match/if … end` branch body; it glued the body (`begin if a then b`) and reindented it when a comment was added. Why the comment case now goes through the plain begin/end path: `fmt_beginend` cannot see the comment — `branch_pro` consumes it in `Params` before the expression is formatted. `get_if_then_else`, however, runs before consumption, so the decision belongs there. A special `begin match/if … end` branch with a leading comment on its body no longer takes the `begin <kw>` shortcut arm; it falls through to the existing plain begin/end machinery (`has_cmts_before` predicate). That keeps `begin` on its own line with the body (comment included) one indent in, identically across all if-then-else modes, so adding a comment no longer reindents the body. Why expr_pro is dropped for special-bodied begin/end branches: the fit-or-vertical / vertical branch `expr_pro` is `break_unless_newline 1000`, which enqueues width 1000 even as a no-op at BOL and poisons the body's `match … with` / `if … then` header box, forcing it to split over several lines. Such a body already breaks after `begin`, so it provides its own break instead of the poisoning one. Simple-bodied `begin e end` keeps the regular branch break (no header to poison). K&R additionally dropped the extra body box that indented a comment-routed body by +2. Why a ctx0 box wrap remains in fmt_beginend: the no-comment shortcut path still needs `end` aligned with `begin`. In fit-or-vertical the branch box is `hovbox 0` while the branch break indents `begin` one level in, so the body and `end` are wrapped together. This is scoped to `ctx0=ifthenelse` because wrapping unconditionally reindents application arguments (`map x begin fun … end`, exp_grouping.ml); the scope is structural (alignment), not comment-handling logic. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
be77c0
#2810