prettier-plugin-multipass
v0.0.1
Published
A tiny Prettier traffic cop for plugins that need to take turns.
Readme
prettier-plugin-multipass
A tiny Prettier traffic cop for plugins that need to take turns.
Prettier does not compose parser/printer hooks for the same language. When multiple plugins register the same parser or printer, Prettier picks the last one, & the earlier plugins do not run (see: prettier/prettier#12807).
Installation
npm i -D prettier@3 prettier-plugin-multipassUsage
Add prettier-plugin-multipass as the top-level plugin, then put the real formatter plugins in passes.
// prettier.config.js
export default {
plugins: ['prettier-plugin-multipass'],
passes: [
// Each pass is an array of plugin specifiers, optionally followed by an options object for that pass.
['plugin-a']
{ pluginAOption: true },
['plugin-b', 'plugin-c'],
{
pluginBOption: false,
pluginBOption2: 'value',
pluginCOption: 67,
},
['prettier-plugin-jsdoc'],
{ jsdocCapitalizeDescription: false },
]
};Then run Prettier as usual:
npx prettier --write .[!NOTE]
passes: []is a no-op & behaves like normal Prettier.
[!IMPORTANT]
If you are using plugins with merging tools like
prettier-plugin-merge, you should colocate them in the same pass.
[!WARNING]
This plugin does not work for plugins that depend on user-written formatting as input to change the printer behaviour, as earlier/later passes will have applied default prettier behaviour. For example, a plugin that checks the first whitespace character in a function block to decide whether to break it into multiple lines may see different input after an earlier pass. (i.e.
prettier-plugin-inline-blocks).
How It Works
prettier-plugin-multipass wraps Prettier's babel, babel-ts, & typescript parsers.
For each file, it runs prettier.format once per configured pass. The output from pass one becomes the input for pass two, & so on. At the end, the final text is handed back to Prettier.
That means every pass incurs another parse/print cycle. If plugins can be combined into one pass & still work correctly, do that.
Actual Example
// prettier.config.js
export default {
plugins: ['prettier-plugin-multipass'],
passes: [
['prettier-plugin-jsdoc'],
{
jsdocNamedImportPadding: true,
jsdocNamedImportLineSplitting: false,
jsdocCapitalizeDescription: false,
jsdocTagsOrder: '{"template": 24.5}',
},
['prettier-plugin-sql-cst', 'prettier-plugin-embed'],
{
embeddedSqlTags: ['sql', 'sql.transaction'],
embeddedSqlPlugin: 'prettier-plugin-sql-cst',
embeddedSqlParser: 'sqlite',
sqlKeywordCase: 'lower',
sqlLiteralCase: 'lower',
sqlTypeCase: 'lower',
sqlParamTypes: ['$name', '${name}', '?', '?nr', '$nr', ':name'],
},
[
'prettier-plugin-tailwindcss',
'prettier-plugin-classnames',
'prettier-plugin-merge',
],
{
tailwindStylesheet: './src/theme/index.css',
tailwindFunctions: ['clsx', 'tw'],
customFunctions: ['clsx', 'tw'],
endingPosition: 'absolute',
},
],
};TO-DO
- [ ] Support range formatting & cursor formatting
- [ ] Support more languages outside of JavaScript/TypeScript
- [ ] More tests
License
MIT
