Skip to content

jscheid/prettier.el

Repository files navigation

prettier.el

MELPA CI

The prettier Emacs package reformats your code by running Prettier with minimal overhead, by request or transparently on file save.

Overhead on top of Prettier registers in the range of single-digit milliseconds for reasonably sized files on a decent system.

Prettier is run in a long-running process so that Node startup overhead is only paid once, and so that V8 JIT compilation has a better opportunity to work its magic.

Additional features include first-class support for reformatting remote files via tramp-mode and integration with many major modes.

This is not the official Prettier integration for Emacs. The official package can be found at https://github.com/prettier/prettier-emacs.

Installation

Install from MELPA, for example with M-x package-install RET prettier RET.

A node executable needs to be on exec-path. It is recommended to provide a recent version of Node since older versions tend to be significantly slower. prettier also uses the Emacs nvm package so that if you have nvm, all you need to do is run nvm install node to ensure the latest version is available.

The Prettier package needs to be installed inside your npm package, or globally with either npm or yarn. Version 1.6 is the minimum requirement but it's recommended to use the latest version in order to get access to all parsers, features and bugfixes.

You can use M-x prettier-info to see which versions are being used for a given buffer and to aid with diagnosis when Node or Prettier can't be found.

The above instructions are for reformatting local files; see below for how to configure remote systems.

Troubleshooting

If you see the error Cannot find prettier anywhere even though Prettier is installed globally, you might be using node installed via snap on Ubuntu. When installed using this method, node is unable to find globally installed packages. This can be worked around by setting NODE_PATH explicitly, for example:

(setenv "NODE_PATH" "/usr/local/lib/node_modules")

Configuration

Use M-x global-prettier-mode to turn on the minor mode in all major modes supported by your version of Prettier and by any plugins installed (see prettier-enabled-parsers below.) When enabled, the minor mode will reformat on file save and also sync settings from Prettier to Emacs, such as indentation level.

To enable prettier-mode globally at startup:

(add-hook 'after-init-hook #'global-prettier-mode)

Enabling per-file / per-directory

emacs has a great feature called Per-Directory Local Variables, which can be utilised to automatically enable prettier-mode for specific files or directories. For example, if you put the following in a .dir-locals.el file at the top of a git repository:

((js-mode . ((eval . (prettier-mode t)))))

then it should automatically enable prettier-mode for any files using js-mode. (N.B. If the files are already open, you will have to close and re-open them to see this take effect.) You could also match by file path instead of by mode, as described in the above docs.

There is an alternative mechanism which can be handy if you want to avoid adding .dir-locals.el to a directory; add these to your emacs config:

(dir-locals-set-class-variables 'prettier-js
                                '((js-mode . ((eval . (prettier-mode t))))))
(dir-locals-set-directory-class "/path/to/my/pretty/project/" 'prettier-js)

Usage

When enabled as a minor mode with prettier-mode, your source code is formatted on save.

You can also M-x prettier-prettify to prettify the whole buffer at any time in any buffer (doing so doesn't require the minor mode to be enabled), and M-x prettier-prettify-region to prettify region (but note that region should align with a complete block of code).

If you give a prefix argument to either of these two commands you will be able to set/override the Prettier parser to use for formatting.

Changing Prettier Configuration

You should run M-x prettier-restart whenever any relevant configuration changes, such as when you install a new version of Node, Prettier, or any plugins; when you install or uninstall Prettier as a local npm package in a directory from which you already have files open in Emacs; or when you change Prettier settings that might affect any open files. Doing so will clear all caches and ensure that your changes are picked up.

On Remote Servers

When you edit files on a remote host, Prettier will be run remotely on that host. It follows that the remote host needs to have Node and Prettier installed as described above. nvm can't be used on remote hosts; you will have to ensure tramp-remote-path is set correctly.

Remote formatting might be improved in the future in the following ways:

  • Using remote Prettier only to determine options for the remote file, but using local Prettier to do the actual formatting. This would help with large source files and slow connections.

  • Obviating the need for remote Prettier by walking the remote filesystem and finding configuration files. This is unlikely to happen because it would mean having to keep this package's code in sync with Prettier configuration discovery logic.

Customization

M-x customize-group prettier

This is an overview of available options. The docstrings for the individual settings may contain additional information.

prettier-mode-sync-config-flag

Set this to nil if you don't want prettier-mode to change your buffer-local settings to match Prettier options.

prettier-editorconfig-flag

Set this to nil if you don't want Prettier to use .editorconfig files to load options.

prettier-enabled-parsers

Customize this to disable any parsers you don't want to use.

prettier-infer-parser-flag

Set this to nil if you don't want Prettier to fall back to inferring the parser to use based on the file name and contents.

prettier-prettify-on-save-flag

Set this to nil if you don't want Prettier to prettify (format) the buffer when saving. You can still format the buffer explicitly with prettier-prettify, which you might want to bind to a key.

prettier-inline-errors-flag

Set this to t if you want syntax errors to be shown inline instead of sending them to the default error buffer. This feature is experimental and won't yet work well when the error is outside the window.

prettier-pre-warm

Choose how to pre-warm Prettier caches.

Essentially this selects when you wait for Prettier startup overhead: with none, you tend to wait for it on first save. With full, you wait when prettier-mode is first activated.

some is a compromise, with it you wait some on first activation and some on first save.

prettier-mode-ignore-buffer-function

This function is called in every buffer that prettier-mode supports. If it returns non-nil, the buffer is ignored and prettier-mode won't be activated for it. The default is to ignore buffers for files nested beneath a node_modules directory. You can set this to nil and no buffers will be ignored.

prettier-mode-lighter

This Sexpr is evaluated as part of the modeline. The default value shows the string Prettier as well as the Prettier parser and Prettier version used for the buffer.

prettier-diff-timeout-seconds

Choose how long the diff operation is allowed to run, which matters for large files with many edits resulting from Prettier reformatting. The diff is required only for moving point to the correct new location (and adjust region, overlays etc.), so essentially this lets you decide how long you are willing to wait for this. A setting of 0 disables the timeout and lets the diff always run to completion. This used to be fixed at 1 second pre-1.4.0.

See [https://github.com/google/diff-match-patch/wiki/API#diff_maintext1-text2--diffs](diff-match-patch documentation).

prettier-diff-edit-cost

Determines how aggressively individual edits resulting from Prettier reformatting get coalesced into larger edits. The default setting should work reasonably well. This can be set to 0 to disabled grouping of edits altogether, which was the behaviour pre-1.4.0.

See [https://github.com/google/diff-match-patch/wiki/API#diff_cleanupefficiencydiffs--null](diff-match-patch documentation).

Differences from prettier-emacs

  • prettier-emacs launches Prettier in an external process, paying the Node startup overhead on each invocation unless mitigated by tools such as prettier_d. This package uses a long-running child process.

  • prettier-emacs lets Prettier guess the parser to use based on the filename. This package instead derives the parser from the major mode when possible and falls back to a guess based on the filename only when the major mode isn't supported.

  • prettier-emacs doesn't touch your buffer configuration, such as indentation offsets. prettier-mode, by default, tries to set the buffer configuration to match Prettier configuration as closely as possible.

  • This package keeps point at the same location relative to your code.

  • This package has first-class support for editing remote files via tramp-mode (with some room for improvement for large source files and slow connections), and for using a local Prettier installation (in your project's node_modules rather than installed globally.)

  • prettier-emacs allows overriding various Prettier options by setting prettier-js-args or prettier-js-width-mode. In contrast, this package believes that your Prettier configuration files should serve as the single source of truth.

Credits

This package is heavily inspired by the original package that integrated Prettier into Emacs, prettier-emacs.

Building from source

See HACKING.md for build instructions and RELEASING.md for information about the release process.

License

© Copyright 2018-present Julian Scheid

GNU Public License v3 or any later version (see COPYING)