lfe/fmt

Build StatusLFE VersionsErlang VersionsTags

A code formatter for LFE

LFE fmt project logo

About

lfmt is written in Erlang (like LFE itself) and is a general-purpose formatter for the wider BEAM community. While the first engine (fezzik) is intentionally single-language, single-purpose, the forthcoming pe and pc engines are built around user-supplied formatting-rules files. Given a rule set, lfmt is intended to format any text file according to those rules.

All engines are pure-Erlang with zero runtime dependencies.

Usage

The formatter reads source and pretty-prints it into a consistent, canonical layout — preserving comments and guaranteeing idempotence: formatting already-formatted code leaves it unchanged (format(format(X)) == format(X)).

lfmt has a multi-engine design: a single, stable API (lfmt:new/1) sits in front of pluggable formatting engines, so you can choose the algorithm that suits you. This release ships the fezzik engine; two further engines are planned:

EngineStatusNotes
fezzikavailabledirect, fast brute-force formatter
peplannedpretty-expressive (optimal-layout) engine
pcplannedpretty-canny engine

lfmt is an Erlang library add as a dependency (rebar3) in the usual manner:

{deps, [{lfmt, "~> 0.4"}]}.

lfmt provides the formatting capability of the LFE rebar3 plugin (rebar3_lfe) as of version 0.5.5 of that tool.

Formatting

The simplest form uses the default engine (fezzik); note that this is the only engine which is LFE-only (understandable, given it is a brute-force formatter, not a general-purpose one):

{ok, Formatted} = lfmt:format(Source).

To select an engine explicitly, build a reusable formatter with lfmt:new/1:

Fmtr = lfmt:new(#{engine => fezzik}),
{ok, Formatted} = lfmt:format(Fmtr, Source).

Source is LFE source as a binary or string, and the result is an iolist. Because formatted output can contain Unicode codepoints (> 127), convert it to a binary with unicode:characters_to_binary/1notiolist_to_binary/1:

{ok, IoData} = lfmt:format(<<"(defun id (x) x)">>),
Bin = unicode:characters_to_binary(IoData).

From LFE:

(case (lfmt:format source)
(`#(ok ,formatted) formatted)
(`#(error ,reason) (error reason)))

Selecting an engine that isn't available yet (e.g. pe/pc) is reported explicitly rather than silently ignored.

License

Apache-2.0. See LICENSE.