mix format plugin that
canonicalises ICU MessageFormat 2 (MF2) messages.
The plugin handles two input shapes:
~Msigils in Elixir source. Content between~M"...",~M"""...""",~M(...), etc. is parsed as MF2 and rewritten to its canonical form (same form the~Msigil produces at compile time viaLocalize.Message.canonical_message!/2). This keeps the source text identical to what the compiler records and makes translator keys stable regardless of developer whitespace preferences.Standalone
.mf2files. Files listed under the formatter's:inputsand matching*.mf2are rewritten in place. Useful when messages live in their own files rather than embedded in Elixir.
The lowercase ~m sigil is not supported by this plugin. ~m
permits #{interpolation}, which cannot be round-tripped through
the MF2 parser without losing structure. Use ~M for anything you
want mix format to touch.
Installation
Add to the project's .formatter.exs:
[
plugins: [Localize.Message.Formatter.Plugin],
inputs: [
"{mix,.formatter}.exs",
"{config,lib,test}/**/*.{ex,exs}",
"priv/messages/**/*.mf2"
]
]Running mix format will then canonicalise every ~M sigil body in
the Elixir files and every .mf2 file under priv/messages/.
Options
Plugin options live under the :mf2 key in .formatter.exs:
[
plugins: [Localize.Message.Formatter.Plugin],
mf2: [pretty: true]
]:pretty—true | false | :auto(default:auto). When:auto, single-line input is kept compact and multi-line input is pretty-printed.true/falseforce one or the other regardless of the input shape.
Error handling
If an MF2 message fails to parse, the plugin returns the input
unchanged and emits a Mix.shell().error/1 warning naming the file
(or sigil location, when available) and the line / column reported by
the parser. mix format continues formatting the rest of the file.
mix format --check-formatted then surfaces the warning without
blocking the run on other files.
Idempotency
Canonical MF2 is a fixed point of canonical_message/2, and a
property test in the Localize test-suite locks this in. Running
mix format twice produces identical output on the second run.