| 1 | [](http://melpa.org/#/reformatter) |
| 2 | [](http://stable.melpa.org/#/reformatter) |
| 3 | [](https://elpa.nongnu.org/nongnu/reformatter.html) |
| 4 | [](https://github.com/purcell/emacs-reformatter/actions/workflows/test.yml) |
| 5 | <a href="https://www.patreon.com/sanityinc"><img alt="Support me" src="https://img.shields.io/badge/Support%20Me-%F0%9F%92%97-ff69b4.svg"></a> |
| 6 | |
| 7 | # Define commands which run reformatters on the current Emacs buffer |
| 8 | |
| 9 | This library lets elisp authors easily define an idiomatic command to |
| 10 | reformat the current buffer using a command-line program, together |
| 11 | with an optional minor mode which can apply this command automatically |
| 12 | on save. |
| 13 | |
| 14 | By default, reformatter.el expects programs to read from stdin and |
| 15 | write to stdout, and you should prefer this mode of operation where |
| 16 | possible. If this isn't possible with your particular formatting |
| 17 | program, refer to the options for `reformatter-define`, and see the |
| 18 | examples in the package's tests. |
| 19 | |
| 20 | In its initial release it supports only reformatters which can read |
| 21 | from stdin and write to stdout, but a more versatile interface will |
| 22 | be provided as development continues. |
| 23 | |
| 24 | As an example, let's define a reformat command that applies the "dhall |
| 25 | format" command. We'll assume here that we've already defined a |
| 26 | variable `dhall-command` which holds the string name or path of the |
| 27 | dhall executable: |
| 28 | |
| 29 | ```el |
| 30 | (reformatter-define dhall-format |
| 31 | :program dhall-command |
| 32 | :args '("format") |
| 33 | :lighter " DF") |
| 34 | ``` |
| 35 | |
| 36 | The `reformatter-define` macro expands to code which generates |
| 37 | `dhall-format-buffer` and `dhall-format-region` interactive commands, |
| 38 | and a local minor mode called `dhall-format-on-save-mode`. The `:args` |
| 39 | and `:program` expressions will be evaluated at runtime, so they can |
| 40 | refer to variables that may (later) have a buffer-local value. A |
| 41 | custom variable will be generated for the mode lighter, with the |
| 42 | supplied value becoming the default. |
| 43 | |
| 44 | The generated minor mode allows idiomatic per-directory or per-file |
| 45 | customisation, via the "modes" support baked into Emacs' file-local |
| 46 | and directory-local variables mechanisms. For example, users of the |
| 47 | above example might add the following to a project-specific |
| 48 | `.dir-locals.el` file: |
| 49 | |
| 50 | ```el |
| 51 | ((dhall-mode |
| 52 | (mode . dhall-format-on-save))) |
| 53 | ``` |
| 54 | |
| 55 | See the documentation for `reformatter-define`, which provides a |
| 56 | number of options for customising the generated code. |
| 57 | |
| 58 | Library authors might like to provide autoloads for the generated |
| 59 | code, e.g.: |
| 60 | |
| 61 | ```el |
| 62 | ;;;###autoload (autoload 'dhall-format-buffer "current-file" nil t) |
| 63 | ;;;###autoload (autoload 'dhall-format-region "current-file" nil t) |
| 64 | ;;;###autoload (autoload 'dhall-format-on-save-mode "current-file" nil t) |
| 65 | ``` |
| 66 | |
| 67 | ## Examples of usage in the wild |
| 68 | |
| 69 | To find reverse dependencies, look for "Needed by" on the [MELPA page |
| 70 | for reformatter](https://melpa.org/#/reformatter). Here are some |
| 71 | specific examples: |
| 72 | |
| 73 | * [dhall-mode.el](https://github.com/psibi/dhall-mode/blob/master/dhall-mode.el) |
| 74 | * [elm-format.el](https://github.com/jcollard/elm-mode/blob/master/elm-format.el), in `elm-mode` |
| 75 | * [sqlformat.el](https://github.com/purcell/sqlformat/blob/master/sqlformat.el) |
| 76 | * [Here](https://github.com/purcell/emacs.d/blob/14f645a9bde04498ce2b60de268c2cbafa13604a/lisp/init-purescript.el#L18-L19) is the author defining a reformatter in his own configuration |
| 77 | |
| 78 | ## Rationale |
| 79 | |
| 80 | I contribute to a number of Emacs programming language modes and |
| 81 | tools, and increasingly use code reformatters in my daily work. It's |
| 82 | surprisingly difficult to write robust, correct code to apply these |
| 83 | reformatters, given that it must consider such issues as: |
| 84 | |
| 85 | * Missing programs |
| 86 | * Buffers not yet saved to a file |
| 87 | * Displaying error output |
| 88 | * Colorising ANSI escape sequences in any error output |
| 89 | * Handling file encodings correctly |
| 90 | |
| 91 | With this library, I hope to help the community standardise on best |
| 92 | practices, and make things easier for tool authors and end users |
| 93 | alike. |
| 94 | |
| 95 | ## FAQ |
| 96 | |
| 97 | ### How is this different from [format-all.el](https://github.com/lassik/emacs-format-all-the-code)? |
| 98 | |
| 99 | `format-all` is a very different approach: it aims to provide a single |
| 100 | minor mode which you then enable and configure to do the right thing |
| 101 | (including nothing) for all the languages you use. It even tries to |
| 102 | tell you how to install missing programs. It's an interesting project, |
| 103 | but IMO it's hard to design the configuration for such a grand unified |
| 104 | approach, and it can get complex. For example, you'd have to be able |
| 105 | to configure which of two possible reformatters you want to use for a |
| 106 | specific language, and to be able to do that on a per-project basis. |
| 107 | |
| 108 | In contrast reformatter produces small, self-contained and separate |
| 109 | formatters and minor modes which all work consistently and are |
| 110 | individually configured. It makes it possible to replace existing |
| 111 | formatter code, and it's also very convenient for users to define |
| 112 | their own ad-hoc reformatter wrappers |
| 113 | |
| 114 | ## Installation |
| 115 | |
| 116 | ### Manual |
| 117 | |
| 118 | Ensure `reformatter.el` is in a directory on your load-path, and add |
| 119 | the following to your `~/.emacs` or `~/.emacs.d/init.el`: |
| 120 | |
| 121 | ```elisp |
| 122 | (require 'reformatter) |
| 123 | ``` |
| 124 | |
| 125 | ### MELPA |
| 126 | |
| 127 | If you're an Emacs 24 user or you have a recent version of |
| 128 | `package.el` you can install `reformatter` from the |
| 129 | [MELPA](http://melpa.org) repository. The version of |
| 130 | `reformatter` there will always be up-to-date. |
| 131 | |
| 132 | ## About |
| 133 | |
| 134 | Author: Steve Purcell <steve at sanityinc dot com> |
| 135 | |
| 136 | Homepage: https://github.com/purcell/emacs-reformatter |
| 137 | |
| 138 | <hr> |
| 139 | |
| 140 | [💝 Support this project and my other Open Source work](https://www.patreon.com/sanityinc) |
| 141 | |
| 142 | [💼 LinkedIn profile](https://uk.linkedin.com/in/stevepurcell) |
| 143 | |
| 144 | [✍ sanityinc.com](https://www.sanityinc.com/) |
| 145 | |
| 146 | [🐦 @sanityinc](https://twitter.com/sanityinc) |