Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: introduce option to force format extracted fragements #561

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strong-lions-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-prettier": minor
---

Introduce option to force format extracted fragements
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.changeset/
# this file doesn't exist, but we use it as a filename that should be ignored
# by prettier in the tests
ignore-me.js
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,22 @@ If you’re fixing large of amounts of previously unformatted code, consider tem
}
```

- `forceFormatExtracted`: Enables formatting of extracted fragements, (default: `false`).
ESLint supports processors that let you extract and lint JS fragments within a non-JS language, for example using `eslint-plugin-markdown` to extract and lint a code block inside a Markdown file. Usually, you don't want to have the fragement itself formatted by Prettier as the whole file
might already be formatted anyway. This is why `eslint-plugin-prettier` ignores such fragements by default. However, for cases you want to have such extracted fragements formatted by Prettier you can use this option to force it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, for cases you want to have such extracted fragements formatted by Prettier you can use this option to force it.

So, the case is, you want to format js in markdown via prettier, but not the markdown file itself? cc @BPScott

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sort of. Actually I'd like to be able to apply a different set of Prettier rules to code blocks in Markdown files resp. be able to individually handle those blocks (for example disabling Prettier for JS code blocks, while formatting other code blocks like JSON). This can be achieved via ESLint rules on Markdown files processed with eslint-plugin-markdown. This set-up is working fine, but only if I'm able to disable the default behavior of eslint-plugin-prettier with this newly introduced option to not skip those code blocks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented down below. I think there's ways of doing this without introducing a new option.


```json
{
"prettier/prettier": [
"error",
{},
{
"forceFormatExtracted": true
}
]
}
```

- `fileInfoOptions`: Options that are passed to [prettier.getFileInfo](https://prettier.io/docs/en/api.html#prettiergetfileinfofilepath--options) to decide whether a file needs to be formatted. Can be used for example to opt-out from ignoring files located in `node_modules` directories.

```json
Expand Down
5 changes: 4 additions & 1 deletion eslint-plugin-prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @typedef {import('eslint').AST.SourceLocation} SourceLocation
* @typedef {import('eslint').ESLint.Plugin} Plugin
* @typedef {import('prettier').FileInfoOptions} FileInfoOptions
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean }} Options
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean, forceFormatExtracted?: boolean }} Options
*/

'use strict';
Expand Down Expand Up @@ -107,6 +107,7 @@ const eslintPluginPrettier = {
type: 'object',
properties: {
usePrettierrc: { type: 'boolean' },
forceFormatExtracted: { type: 'boolean' },
fileInfoOptions: {
type: 'object',
properties: {},
Expand All @@ -125,6 +126,7 @@ const eslintPluginPrettier = {
create(context) {
const usePrettierrc =
!context.options[1] || context.options[1].usePrettierrc !== false;
const forceFormatExtracted = !!context.options[1]?.forceFormatExtracted;
/**
* @type {FileInfoOptions}
*/
Expand Down Expand Up @@ -175,6 +177,7 @@ const eslintPluginPrettier = {
onDiskFilepath,
parserPath: context.parserPath,
usePrettierrc,
forceFormatExtracted,
},
fileInfoOptions,
);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"eslint-config-prettier": "^8.5.0",
"eslint-mdx": "^2.0.2",
"eslint-plugin-eslint-plugin": "^5.0.6",
"eslint-plugin-markdown": "^3.0.0",
"eslint-plugin-mdx": "^2.0.2",
"eslint-plugin-self": "^1.2.1",
"eslint-plugin-svelte": "^2.7.0",
Expand Down
3 changes: 3 additions & 0 deletions test/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
4 changes: 4 additions & 0 deletions test/fixtures/md.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Example
```js
const example = "example"
```
37 changes: 37 additions & 0 deletions test/prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ const eslint = new ESLint({
'mdx/code-block': true,
},
},
// To test 'forceFormatExtracted' option
{
files: '**/*.md',
plugins: ['markdown'],
processor: 'markdown/markdown',
rules: {
'prettier/prettier': 'off',
},
},
{
files: '**/*.md/*.js',
rules: {
'prettier/prettier': ['error', {}, { forceFormatExtracted: true }],
},
},
{
files: '**/eslint-plugin-svelte3/*.svelte',
plugins: ['svelte3'],
Expand Down Expand Up @@ -261,6 +276,28 @@ runFixture('*.mdx', [
],
]);

// Testing 'forceFormatExtracted' option
// (should only format code block, not the whole file)
runFixture('*.md', [
[
{
column: 17,
endColumn: 26,
endLine: 3,
fix: {
range: [32, 41],
text: "'example';",
},
line: 3,
message: 'Replace `"example"` with `\'example\';`',
messageId: 'replace',
nodeType: null,
ruleId: 'prettier/prettier',
severity: 2,
},
],
]);

runFixture('eslint-plugin-svelte/*.svelte', [
[
{
Expand Down
5 changes: 3 additions & 2 deletions worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/**
* @typedef {import('prettier').FileInfoOptions} FileInfoOptions
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean }} Options
* @typedef {import('prettier').Options & { onDiskFilepath: string, parserPath: string, usePrettierrc?: boolean, forceFormatExtracted?: boolean }} Options
*/

const { runAsWorker } = require('synckit');
Expand All @@ -26,6 +26,7 @@ runAsWorker(
onDiskFilepath,
parserPath,
usePrettierrc,
forceFormatExtracted,
...eslintPrettierOptions
},
eslintFileInfoOptions,
Expand Down Expand Up @@ -124,7 +125,7 @@ runAsWorker(
if (inferParserToBabel) {
initialOptions.parser = 'babel';
}
} else {
} else if (!forceFormatExtracted) {
// Similar to https://github.com/prettier/stylelint-prettier/pull/22
// In all of the following cases ESLint extracts a part of a file to
// be formatted and there exists a prettier parser for the whole file.
Expand Down
Loading