Some weeks ago I discovered a really nice package for emacs called reformatter.el. This package allows to define reformat functions in a easy way.

Most languages have a reformat tool. Elixir has mix format , Elm has elm format , python has black and so on. These formatters are convenient because they give uniformity to the code, but this is a topic for another post.

Having these formatters integrated within our favorite editor is great. These are enough(at least for me) reasons to use reformatter.el so let's get into the code:

reformatter.el has a simple macro that allows us to define a formatter with just a few lines.

For this example we'll create a formatter for haskell using hindent .

(reformatter-define haskell-format :program " hindent " )

We just need to define the command that will be used to format the code. In this case hindent . This will create some useful functions:

haskell-format

haskell-format-buffer

haskell-format-region

haskell-format-on-save-mode

These functions can be used with a key-binding:

( define-key haskell-mode-map (kbd " C-c C-f " ) 'haskell-format-buffer )

Also we can setup emacs to run the formatter when the file is saved, for example put this code in your .dir-locals.el and it will do the work.

(haskell-mode (mode . haskell-format-on-save))

The program used to format our code needs to be able to read from stdin and return the formatted code to stdout . In this case hindent does it by default.

In some cases the formatter doesn't do this by default. For those cases we can pass extra arguments to the command using :args key in the formatter macro. For example elixir format receive a file or a pattern by default but we can change that using mix format - , now it will read from stdin , so we need to pass these parameters to our formatter. The code should be:

(reformatter-define elixir-format :program " mix " :args ' ( " format " " - " ))

Now it will work properly.