Skip to content

Commit

Permalink
[patch] handle comments in the middle of an array
Browse files Browse the repository at this point in the history
GitHub: resolves #42
  • Loading branch information
electrovir committed Dec 15, 2024
1 parent e1b29d3 commit e7ee199
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 186 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ The order of your plugins array is very important, so if you have other plugins

This plugin provides two new options for your Prettier config:

- **`multilineArraysWrapThreshold`**: This should be set to a single number which controls when arrays wrap. If an array has _more_ elements than the number specified here, it will be forced to wrap. This option defaults to `-1`, which indicates that no automatic wrapping will take place. Example JSON: `"multilineArraysWrapThreshold": 3,`. To override this option for an individual array, precede the array with a comment like so: `// prettier-multiline-arrays-next-threshold: 4`.
- **`multilineArraysLinePattern`**: This should be set to a string which contains a space separated list of numbers. These numbers allow fine grained control over how many elements appear in each line. The pattern will repeat if an array has more elements than the pattern. See the `Examples` section for how this works. This defaults to just `1`, which indicates all array lines have just a single element. Example: `"multilineArraysLinePattern": "2 1"`, which means the first line will have 2 elements, the second will have 1, the third will have 2, the fourth will have 1, and so on. If set, _this option overrides Prettier's default wrapping; multiple elements on one line will not be wrapped even if they don't fit within the column count._ To override this option for an array, precede the array with a comment like so: `// prettier-multiline-arrays-next-line-pattern: 2 1`.
- **`multilineArraysWrapThreshold`**: This should be set to a single number which controls when arrays wrap. If an array has _more_ elements than the number specified here, it will be forced to wrap. This option defaults to `-1`, which indicates that no automatic wrapping will take place. Example JSON: `"multilineArraysWrapThreshold": 3,`. To override this option for an individual array, precede the array with a comment like so: `// prettier-multiline-arrays-next-threshold: 4`.
- **`multilineArraysLinePattern`**: This should be set to a string which contains a space separated list of numbers. These numbers allow fine grained control over how many elements appear in each line. The pattern will repeat if an array has more elements than the pattern. See the `Examples` section for how this works. This defaults to just `1`, which indicates all array lines have just a single element. Example: `"multilineArraysLinePattern": "2 1"`, which means the first line will have 2 elements, the second will have 1, the third will have 2, the fourth will have 1, and so on. If set, _this option overrides Prettier's default wrapping; multiple elements on one line will not be wrapped even if they don't fit within the column count._ To override this option for an array, precede the array with a comment like so: `// prettier-multiline-arrays-next-line-pattern: 2 1`.

## Comment overrides

- Add a comment starting with `prettier-multiline-arrays-next-threshold:` followed by a single number to control `multilineArraysWrapThreshold` for an array on the next line.
- Add a comment starting with `prettier-multiline-arrays-next-line-pattern:` followed by a pattern of numbers to control `multilineArraysLinePattern` for an array on the next line.
- Add a comment starting with `prettier-multiline-arrays-next-threshold:` followed by a single number to control `multilineArraysWrapThreshold` for an array on the next line.
- Add a comment starting with `prettier-multiline-arrays-next-line-pattern:` followed by a pattern of numbers to control `multilineArraysLinePattern` for an array on the next line.

To set a comment override for all arrays in a file following the comment, change `next` to `set`. Like so:

- `prettier-multiline-arrays-set-threshold: 5`
- `prettier-multiline-arrays-set-line-pattern: 2 1 3`
- `prettier-multiline-arrays-set-threshold: 5`
- `prettier-multiline-arrays-set-line-pattern: 2 1 3`

To later undo a `set` comment, use `prettier-multiline-arrays-reset`, which resets the options to whatever you have set in prettierrc, or the default values.

Expand All @@ -52,7 +52,7 @@ The precedence of forcing wrapping goes as follows:

## Examples

- Not formatted:
- Not formatted:

<!-- example-link: src/readme-examples/not-formatted.example.ts -->

Expand All @@ -65,7 +65,7 @@ The precedence of forcing wrapping goes as follows:
'a', 'b', 'c', 'd', 'e'] // note the leading new line which forces a wrap
```

- Removing the `prettier-ignore` comments leads to formatting like this (with the default options):
- Removing the `prettier-ignore` comments leads to formatting like this (with the default options):

<!-- example-link: src/readme-examples/formatted.example.ts -->

Expand All @@ -85,7 +85,7 @@ The precedence of forcing wrapping goes as follows:
]; // note the leading new line which forces a wrap
```

- Use comment overrides to affect wrapping:
- Use comment overrides to affect wrapping:

<!-- example-link: src/readme-examples/formatted-with-comments.example.ts -->

Expand Down Expand Up @@ -126,5 +126,5 @@ Tested to be compatible with the following plugins. It is likely compatible with

### Debugging

- Set the `NEW_LINE_DEBUG` environment variable to something truthy before formatting to get extra debug output when formatting.
- To debug in browser dev tools, run `npm run test:debug` and open Chrome's dev tools.
- Set the `MULTILINE_DEBUG` environment variable to something truthy before formatting to get extra debug output when formatting.
- To debug in browser dev tools, run `npm run test:debug` and open Chrome's dev tools.
6 changes: 2 additions & 4 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {getObjectTypedKeys, Values} from '@augment-vir/common';
import {SupportOptionType as PrettierOptionType} from 'prettier';

export const envDebugKey = 'NEW_LINE_DEBUG';
export const envDebugKey = 'MULTILINE_DEBUG';

export const nextLinePatternComment = 'prettier-multiline-arrays-next-line-pattern:';
// all the text up until the comment trigger
Expand Down Expand Up @@ -69,9 +69,7 @@ const optionTypeToPrettierOptionTypeMapping: Record<string, PrettierOptionType>
string: 'string',
} as const satisfies Record<'boolean' | 'number' | 'string', PrettierOptionType>;

export function getPrettierOptionType(
input: Values<MultilineArrayOptions>,
): PrettierOptionType {
export function getPrettierOptionType(input: Values<MultilineArrayOptions>): PrettierOptionType {
const mappedType = optionTypeToPrettierOptionTypeMapping[typeof input];

if (mappedType) {
Expand Down
19 changes: 0 additions & 19 deletions src/plugin-marker.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,2 @@
// used to find our own plugin
export const pluginMarker = {};

const varNoLine = ['a', 'b'];
const varOneNewLine = [
'a',
'b',
];
const nestedArray = [
'q',
'r',
['s', 't'],
];
// ${capitalizeFirst(nextLinePatternComment)} 2 1 3
const setNumberPerLine = [
'a',
'b',
'c',
'd',
'e',
];
108 changes: 65 additions & 43 deletions src/printer/insert-new-lines.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {getObjectTypedKeys, Values, type AnyObject} from '@augment-vir/common';
import {CallExpression} from 'estree';
import {getObjectTypedKeys, stringify, Values, type AnyObject} from '@augment-vir/common';
import {AstPath, Doc, doc, ParserOptions} from 'prettier';
import {isDocCommand, stringifyDoc} from '../augments/doc.js';
import {MultilineArrayOptions} from '../options.js';
Expand All @@ -9,9 +8,8 @@ import {
getCommentTriggers,
parseNextLineCounts,
} from './comment-triggers.js';
import {insertLinesIntoArguments} from './insert-new-lines-into-arguments.js';
import {containsLeadingNewline} from './leading-new-line.js';
import { isArrayLikeNode} from './supported-node-types.js';
import {isArrayLikeNode} from './supported-node-types.js';
import {containsTrailingComma} from './trailing-comma.js';

const nestingSyntaxOpen = '[{(`';
Expand Down Expand Up @@ -213,18 +211,19 @@ function insertLinesIntoArray(
if (debug) {
console.info({closingIndex, closingSibling});
}
if (closingSibling &&
typeof closingSibling === 'object' &&
!Array.isArray(closingSibling) &&
closingSibling.type === 'line'
) {
if (debug) {
console.info(
`found final line break inside of closing sibling`,
);
}
finalLineBreakExists = true;
if (
closingSibling &&
typeof closingSibling === 'object' &&
!Array.isArray(closingSibling) &&
closingSibling.type === 'line'
) {
if (debug) {
console.info(
`found final line break inside of closing sibling`,
);
}
finalLineBreakExists = true;
}
}
return false;
} else if (currentDoc && nestingSyntaxClose.includes(currentDoc)) {
Expand Down Expand Up @@ -258,7 +257,9 @@ function insertLinesIntoArray(
);
}
if (!Array.isArray(commaGrandParent.parent)) {
throw new TypeError(`Comma group grandparent is not an array.`);
throw new TypeError(
`Comma group grandparent is not an array.`,
);
}
siblingIndex = commaGrandParent.childIndexInThisParent + 1;
parentToMutate = commaGrandParent.parent;
Expand All @@ -274,25 +275,50 @@ function insertLinesIntoArray(

let maybeCommaSibling = parentToMutate[siblingIndex];

if (debug) {
console.info(
`Trying to find comma sibling at index ${siblingIndex}`,
stringify({parentToMutate, maybeCommaSibling}),
);
}

function isCommaSibling(
maybe: doc.builders.Doc | undefined,
): maybe is doc.builders.DocCommand | [doc.builders.DocCommand] {
return (
(isDocCommand(maybe) && maybe.type === 'line') ||
(Array.isArray(maybe) &&
isDocCommand(maybe[0]) &&
maybe[0].type === 'line')
);
}

while (
(!isDocCommand(maybeCommaSibling) ||
maybeCommaSibling.type !== 'line') &&
!isCommaSibling(maybeCommaSibling) &&
siblingIndex < parentToMutate.length
) {
siblingIndex++;
maybeCommaSibling = parentToMutate[siblingIndex];
if (debug) {
console.info(
`Trying to find comma sibling at index ${siblingIndex}`,
parentToMutate,
maybeCommaSibling,
);
}
siblingIndex++;
maybeCommaSibling = parentToMutate[siblingIndex];
}
if (
!isDocCommand(maybeCommaSibling) ||
maybeCommaSibling.type !== 'line'
) {

if (debug) {
console.info(
`Found comma sibling at index ${siblingIndex}`,
parentToMutate,
maybeCommaSibling,
);
}

if (!isCommaSibling(maybeCommaSibling)) {
throw new Error(
`Found comma but its following sibling is not a line: ${maybeCommaSibling}`,
`Found comma but its following sibling is not a line: ${stringify(maybeCommaSibling)}`,
);
}
const commaSibling = maybeCommaSibling;
Expand Down Expand Up @@ -338,9 +364,9 @@ function insertLinesIntoArray(
console.info(
isDocCommand(firstPart),
isDocCommand(secondPart),
(firstPart as any).type === 'line',
(firstPart as any).hard,
(secondPart as any).type === 'break-parent',
(firstPart as any)?.type === 'line',
(firstPart as any)?.hard,
(secondPart as any)?.type === 'break-parent',
);
}
if (
Expand Down Expand Up @@ -375,9 +401,7 @@ function insertLinesIntoArray(
);
}

const closingBracketIndex: number = parentDoc.indexOf(
']',
);
const closingBracketIndex: number = parentDoc.indexOf(']');
parentDoc.splice(closingBracketIndex, 0, doc.builders.hardlineWithoutBreakParent);
undoMutations.push(() => {
parentDoc.splice(closingBracketIndex, 1);
Expand Down Expand Up @@ -447,8 +471,9 @@ function getLatestSetValue<T extends object>(
},
'' as keyof T,
);
const relevantSetLineCount =
(triggers as AnyObject)[relevantSetLineCountsKey as any]?.data as Values<T> | undefined
const relevantSetLineCount = (triggers as AnyObject)[relevantSetLineCountsKey as any]?.data as
| Values<T>
| undefined;

return relevantSetLineCount;
}
Expand All @@ -467,10 +492,7 @@ export function printWithMultilineArrays(
}
const node = path.getNode();

if (
node &&
(isArrayLikeNode(node))
) {
if (node && isArrayLikeNode(node)) {
if (!node.loc) {
throw new Error(`Could not find location of node ${node.type}`);
}
Expand Down Expand Up @@ -538,12 +560,12 @@ export function printWithMultilineArrays(
// });

const newDoc = insertLinesIntoArray(
originalFormattedOutput,
manualWrap,
lineCounts,
wrapThreshold,
debug,
);
originalFormattedOutput,
manualWrap,
lineCounts,
wrapThreshold,
debug,
);
return newDoc;
}

Expand Down
Loading

0 comments on commit e7ee199

Please sign in to comment.