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
1.
(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.
This package is very useful if you don't want to install a external package just for formatting. I replaced hindent-mode
(haskell formatter) and a custom elixir formatter with this package. Also this package is used in elm-mode
package.