Files
test-repo/docs/plugins.md
T

225 lines
6.7 KiB
Markdown
Raw Normal View History

2017-12-26 12:23:50 +11:00
---
id: plugins
2018-01-10 07:03:39 -05:00
title: Plugins (Beta)
2017-12-26 12:23:50 +11:00
---
2018-01-10 07:03:39 -05:00
## IN BETA
2017-12-26 12:23:50 +11:00
2018-01-10 07:03:39 -05:00
> The plugin API is in a **beta** state as of Prettier 1.10 and the API may change in the next release!
2017-12-26 12:23:50 +11:00
Plugins are ways of adding new languages to Prettier. Prettier's own implementations of all languages are expressed using the plugin API. The core `prettier` package contains JavaScript and other web-focussed languages built in. For additional languages you'll need to install a plugin.
## Using Plugins
2018-01-06 02:48:47 +11:00
Plugins are automatically loaded if you have them installed in your `package.json`. Prettier plugin package names must start with `@prettier/plugin-` or `prettier-plugin-` to be registered.
2017-12-26 12:23:50 +11:00
2018-01-06 02:48:47 +11:00
If the plugin is unable to be found automatically, you can load them with:
2017-12-26 12:23:50 +11:00
2018-01-06 02:48:47 +11:00
* The [CLI](./cli.md), via the `--plugin` flag:
2017-12-26 12:23:50 +11:00
2018-01-06 02:48:47 +11:00
```bash
prettier --write main.foo --plugin=./foo-plugin
```
2017-12-26 12:23:50 +11:00
2018-01-06 02:48:47 +11:00
> Tip: You can pass multiple `--plugin` flags.
2017-12-26 12:23:50 +11:00
2018-01-06 02:48:47 +11:00
* Or the [API](./api.md), via the `plugins` field:
2017-12-26 12:23:50 +11:00
2018-01-06 02:48:47 +11:00
```js
prettier.format("code", {
parser: "foo",
plugins: ["./foo-plugin"]
});
```
2017-12-26 12:23:50 +11:00
## Official Plugins
2018-03-05 01:57:59 +02:00
* [`@prettier/plugin-python`](https://github.com/prettier/plugin-python)
* [`@prettier/plugin-php`](https://github.com/prettier/plugin-php)
* [`@prettier/plugin-swift`](https://github.com/prettier/plugin-swift)
2017-12-26 12:23:50 +11:00
## Community Plugins
2018-03-16 14:27:47 +00:00
* [`prettier-plugin-elm`](https://github.com/gicentre/prettier-plugin-elm) by [**@giCentre**](https://github.com/gicentre)
* [`prettier-plugin-java`](https://github.com/thorbenvh8/prettier-java) by [**@thorbenvh8**](https://github.com/thorbenvh8)
* [`prettier-plugin-pg`](https://github.com/benjie/prettier-plugin-pg) by [**@benjie**](https://github.com/benjie)
* [`prettier-plugin-ruby`](https://github.com/iamsolankiamit/prettier-ruby) by [**@iamsolankiamit**](https://github.com/iamsolankiamit)
2017-12-26 12:23:50 +11:00
## Developing Plugins
Prettier plugins are regular JavaScript modules with five exports:
* `languages`
* `parsers`
* `printers`
* `options`
* `defaultOptions`
2017-12-26 12:23:50 +11:00
### `languages`
Languages is an array of language definitions that your plugin will contribute to Prettier. It can include all of the fields specified in [`prettier.getSupportInfo()`](./api.md#prettiergetsupportinfo-version).
It **must** include `name` and `parsers`.
```js
export const languages = [
{
// The language name
name: "InterpretedDanceScript",
// Parsers that can parse this language.
// This can be built-in parsers, or parsers you have contributed via this plugin.
parsers: ["dance-parse"]
}
];
```
### `parsers`
Parsers convert code as a string into an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree).
2018-02-10 03:01:19 +01:00
The key must match the name in the `parsers` array from `languages`. The value contains a parse function, an AST format name, and two location extraction functions (`locStart` and `locEnd`).
2017-12-26 12:23:50 +11:00
```js
export const parsers = {
"dance-parse": {
parse,
// The name of the AST that
2018-02-10 03:01:19 +01:00
astFormat: "dance-ast",
hasPragma,
2018-02-10 03:01:19 +01:00
locStart,
locEnd
2017-12-26 12:23:50 +11:00
}
};
```
The signature of the `parse` function is:
```ts
function parse(text: string, parsers: object, options: object): AST;
```
2018-03-04 17:00:47 +01:00
The location extraction functions (`locStart` and `locEnd`) return the starting and ending locations of a given AST node:
2018-02-10 03:01:19 +01:00
```ts
function locStart(node: object): number;
```
The pragma detection function (`hasPragma`) should return if the text contains the pragma comment.
```ts
function hasPragma(text: string): boolean;
```
2017-12-26 12:23:50 +11:00
### `printers`
Printers convert ASTs into a Prettier intermediate representation, also known as a Doc.
The key must match the `astFormat` that the parser produces. The value contains an object with a `print` function and (optionally) an `embed` function.
```js
export const printers = {
"dance-ast": {
print,
embed,
insertPragma
2017-12-26 12:23:50 +11:00
}
};
```
2018-03-04 17:00:47 +01:00
Printing is a recursive process of converting an AST node (represented by a path to that node) into a doc. The doc is constructed using the [builder commands](https://github.com/prettier/prettier/blob/master/commands.md):
2017-12-26 12:23:50 +11:00
```js
const { concat, join, line, ifBreak, group } = require("prettier").doc.builders;
```
The signature of the `print` function is:
```ts
function print(
// Path to the AST node to print
path: FastPath,
options: object,
// Recursively print a child node
print: (path: FastPath) => Doc
): Doc;
```
Check out [prettier-python's printer](https://github.com/prettier/prettier-python/blob/034ba8a9551f3fa22cead41b323be0b28d06d13b/src/printer.js#L174) as an example.
Embedding refers to printing one language inside another. Examples of this are CSS-in-JS and Markdown code blocks. Plugins can switch to alternate languages using the `embed` function. Its signature is:
```ts
function embed(
// Path to the current AST node
path: FastPath,
// Print a node with the current printer
print: (path: FastPath) => Doc,
// Parse and print some text using a different parser.
// You should set `options.parser` to specify which parser to use.
textToDoc: (text: string, options: object) => Doc,
// Current options
options: object
): Doc | null;
```
If you don't want to switch to a different parser, simply return `null` or `undefined`.
A plugin can implement how a pragma comment is inserted in the resulting code when the `--insert-pragma` option is used, in the `insertPragma` function. Its signature is:
```ts
function insertPragma(text: string): string;
```
### `options`
`options` is an object containing the custom options your plugin supports.
Example:
```js
options: {
openingBraceNewLine: {
type: "boolean",
category: "Global",
default: true,
description: "Move open brace for code blocks onto new line."
}
}
```
### `defaultOptions`
2018-03-04 17:00:47 +01:00
If your plugin requires different default values for some of Prettier's core options, you can specify them in `defaultOptions`:
```
defaultOptions: {
tabWidth: 4
}
```
2018-02-10 03:01:19 +01:00
### Utility functions
2018-03-04 17:00:47 +01:00
A `util` module from Prettier core is considered a private API and is not meant to be consumed by plugins. Instead, the `util-shared` module provides the following limited set of utility functions for plugins:
2018-02-10 03:01:19 +01:00
```ts
makeString(rawContent: string, enclosingQuote: string, unescapeUnnecessarEscapes: boolean): string;
getNextNonSpaceNonCommentCharacterIndex(text: string, node: object, options: object): number;
isNextLineEmptyAfterIndex(text: string, index: number): boolean;
isNextLineEmpty(text: string, node: object, options: object): boolean;
mapDoc(doc: object, callback: function): void;
```
2017-12-26 12:23:50 +11:00
## Testing Plugins
Since plugins can be resolved using relative paths, when working on one you can do:
```js
const prettier = require("prettier");
const code = "(add 1 2)";
prettier.format(code, {
parser: "lisp",
plugins: ["."]
});
```
2018-03-04 17:00:47 +01:00
This will resolve a plugin relative to the current working directory.