diff --git a/README.md b/README.md index b08c7821..8d1bfa41 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,8 @@ They should be set via `Prettier`'s `overrides` option Example: `button(type="submit", (click)="play()", disabled)` - `'as-needed'` -> Only add commas between attributes where required. Example: `button(type="submit", (click)="play()" disabled)` + - `'none'` -> Never add commas between attributes. + Example: `button(type="submit" :style="styles" disabled)` - `closingBracketPosition` Position of closing bracket of attributes. diff --git a/src/options/attribute-separator.ts b/src/options/attribute-separator.ts index 568ad840..293be736 100644 --- a/src/options/attribute-separator.ts +++ b/src/options/attribute-separator.ts @@ -16,6 +16,11 @@ export const ATTRIBUTE_SEPARATOR_OPTION = { value: 'as-needed', description: 'Only add commas between attributes where required. Example: `button(type="submit", (click)="play()" disabled)`' + }, + { + value: 'none', + description: + 'Never add commas between attributes. Example: `button(type="submit" :style="styles" disabled)`' } ] }; @@ -38,20 +43,25 @@ export const PUG_ATTRIBUTE_SEPARATOR_OPTION = { value: 'as-needed', description: 'Only add commas between attributes where required. Example: `button(type="submit", (click)="play()" disabled)`' + }, + { + value: 'none', + description: + 'Never add commas between attributes. Example: `button(type="submit" :style="styles" disabled)`' } ] }; -export type AttributeSeparator = 'always' | 'as-needed'; +export type AttributeSeparator = 'always' | 'as-needed' | 'none'; -export function resolveAttributeSeparatorOption(attributeSeparator: AttributeSeparator): boolean { +export function resolveAttributeSeparatorOption(attributeSeparator: AttributeSeparator): AttributeSeparator { switch (attributeSeparator) { case 'always': - return true; case 'as-needed': - return false; + case 'none': + return attributeSeparator } throw new Error( - `Invalid option for pug attributeSeparator. Found '${attributeSeparator}'. Possible options: 'always' or 'as-needed'` + `Invalid option for pug attributeSeparator. Found '${attributeSeparator}'. Possible options: 'always', 'as-needed' or 'none'` ); } diff --git a/src/printer.ts b/src/printer.ts index e6d1ef53..633e4468 100644 --- a/src/printer.ts +++ b/src/printer.ts @@ -103,6 +103,7 @@ export class PugPrinter { private readonly otherQuotes: "'" | '"'; private readonly alwaysUseAttributeSeparator: boolean; + private readonly neverUseAttributeSeparator: boolean; private readonly closingBracketRemainsAtNewLine: boolean; private readonly codeInterpolationOptions: Pick; @@ -119,7 +120,9 @@ export class PugPrinter { this.indentString = options.pugUseTabs ? '\t' : ' '.repeat(options.pugTabWidth); this.quotes = this.options.pugSingleQuote ? "'" : '"'; this.otherQuotes = this.options.pugSingleQuote ? '"' : "'"; - this.alwaysUseAttributeSeparator = resolveAttributeSeparatorOption(options.attributeSeparator); + const attributeSeparator = resolveAttributeSeparatorOption(options.attributeSeparator); + this.alwaysUseAttributeSeparator = attributeSeparator === 'always'; + this.neverUseAttributeSeparator = attributeSeparator === 'none'; this.closingBracketRemainsAtNewLine = resolveClosingBracketPositionOption(options.closingBracketPosition); const codeSingleQuote = !options.pugSingleQuote; this.codeInterpolationOptions = { @@ -525,7 +528,7 @@ export class PugPrinter { this.currentIndex ); if (this.previousToken?.type === 'attribute' && (!this.previousAttributeRemapped || hasNormalPreviousToken)) { - if (this.alwaysUseAttributeSeparator || /^(\(|\[|:).*/.test(token.name)) { + if (!this.neverUseAttributeSeparator && (this.alwaysUseAttributeSeparator || /^(\(|\[|:).*/.test(token.name))) { this.result += ','; } if (!this.wrapAttributes) { diff --git a/tests/options/attributeSeparator/none/formatted.pug b/tests/options/attributeSeparator/none/formatted.pug new file mode 100644 index 00000000..a4e9d16a --- /dev/null +++ b/tests/options/attributeSeparator/none/formatted.pug @@ -0,0 +1,12 @@ +button(type="submit" :styles="styles" @click="play()" disabled) + +nav-component(locale-relative-redirect="true" highlight="home" pin="false") + +.wrapper( + data-nav + data-next="Next" + data-prev="Prev" + data-slides=4 + data-arr=[1, 2, 3, 4, 5, 6] + data-obj={ att: 1, attr2: 2 } +) diff --git a/tests/options/attributeSeparator/none/none.test.ts b/tests/options/attributeSeparator/none/none.test.ts new file mode 100644 index 00000000..145f698a --- /dev/null +++ b/tests/options/attributeSeparator/none/none.test.ts @@ -0,0 +1,21 @@ +import { readFileSync } from 'fs'; +import { resolve } from 'path'; +import { format } from 'prettier'; +import { plugin } from './../../../../src/index'; + +describe('Options', () => { + describe('attributeSeparator', () => { + test('should never insert commas between attributes', () => { + const expected: string = readFileSync(resolve(__dirname, 'formatted.pug'), 'utf8'); + const code: string = readFileSync(resolve(__dirname, 'unformatted.pug'), 'utf8'); + const actual: string = format(code, { + parser: 'pug' as any, + plugins: [plugin], + // @ts-expect-error + attributeSeparator: 'none' + }); + + expect(actual).toBe(expected); + }); + }); +}); diff --git a/tests/options/attributeSeparator/none/unformatted.pug b/tests/options/attributeSeparator/none/unformatted.pug new file mode 100644 index 00000000..cd82ecb1 --- /dev/null +++ b/tests/options/attributeSeparator/none/unformatted.pug @@ -0,0 +1,5 @@ +button(type="submit", :styles="styles", @click="play()", disabled) + +nav-component(locale-relative-redirect="true", highlight="home", pin="false") + +.wrapper(data-nav=true data-next="Next" data-prev="Prev" data-slides=4 data-arr=[1,2,3,4,5,6] data-obj={att: 1, attr2: 2})