# `Localize.Message.Formatter.Plugin`
[🔗](https://github.com/elixir-localize/localize/blob/v0.39.0/lib/localize/message/formatter/plugin.ex#L1)

[`mix format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) plugin that
canonicalises ICU MessageFormat 2 (MF2) messages.

The plugin handles two input shapes:

* **`~M` sigils in Elixir source.** Content between `~M"..."`,
  `~M"""..."""`, `~M(...)`, etc. is parsed as MF2 and rewritten to
  its canonical form (same form the `~M` sigil produces at compile
  time via `Localize.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 `.mf2` files.** Files listed under the formatter's
  `:inputs` and matching `*.mf2` are 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`/`false` force 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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
