Skip to content

Commit b09da87

Browse files
authored
Add option to set indent depth of closing brackets (#502)
1 parent d9a44b1 commit b09da87

10 files changed

Lines changed: 258 additions & 1 deletion

File tree

docs/guide/pug-specific-options.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,74 @@ Output:
540540
```pug
541541
.text-red-400()&attributes(attributes)
542542
```
543+
544+
---
545+
546+
## Indent Closing Bracket in Multiline Elements
547+
548+
`pugClosingBracketIndentDepth`
549+
550+
### Description
551+
552+
Define if the closing bracket of a multiline element should be indented to align with the element or its attributes. This only takes effect if the `bracketSameLine` or `pugBracketSameLine` options are set to false.
553+
554+
The benefit of aligning closing brackets with the element's attributes is that elements are easier to comment out.
555+
556+
### Options
557+
558+
**Type:** `choice`
559+
**Default:** `0`
560+
561+
#### `0`
562+
563+
Input:
564+
565+
```pug
566+
foo(
567+
bar="baz"
568+
)
569+
```
570+
571+
Output:
572+
573+
```pug
574+
foo(
575+
bar="baz"
576+
)
577+
```
578+
579+
Comment example:
580+
581+
```pug
582+
// This will error.
583+
//foo(
584+
bar="baz"
585+
)
586+
```
587+
588+
#### `1`
589+
590+
Input:
591+
592+
```pug
593+
foo(
594+
bar="baz"
595+
)
596+
```
597+
598+
Output:
599+
600+
```pug
601+
foo(
602+
bar="baz"
603+
)
604+
```
605+
606+
Comment example:
607+
608+
```pug
609+
// This will work as expected.
610+
//foo(
611+
bar="baz"
612+
)
613+
```

src/options/converge.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ export function convergeOptions(
5151
pugFramework: options.pugFramework,
5252
pugExplicitDiv: options.pugExplicitDiv,
5353
pugPreserveAttributeBrackets: options.pugPreserveAttributeBrackets,
54+
pugClosingBracketIndentDepth: options.pugClosingBracketIndentDepth ?? 0,
5455
};
5556
}

src/options/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import { PUG_ATTRIBUTE_SEPARATOR_OPTION } from './pug-attribute-separator';
2222
import { PUG_CLASS_LOCATION } from './pug-class-location';
2323
import { PUG_CLASS_NOTATION } from './pug-class-notation';
24+
import { PUG_CLOSING_BRACKET_INDENT_DEPTH_OPTION } from './pug-closing-bracket-indent-depth';
2425
import { PUG_COMMENT_PRESERVE_SPACES_OPTION } from './pug-comment-preserve-spaces';
2526
import { PUG_EXPLICIT_DIV } from './pug-explicit-div';
2627
import { PUG_FRAMEWORK } from './pug-framework';
@@ -44,6 +45,7 @@ export const options: SupportOptions = {
4445
pugArrowParens: PUG_ARROW_PARENS_OPTION,
4546
pugSemi: PUG_SEMI_OPTION,
4647
pugBracketSameLine: PUG_BRACKET_SAME_LINE_OPTION,
48+
pugClosingBracketIndentDepth: PUG_CLOSING_BRACKET_INDENT_DEPTH_OPTION,
4749
pugAttributeSeparator: PUG_ATTRIBUTE_SEPARATOR_OPTION,
4850
pugCommentPreserveSpaces: PUG_COMMENT_PRESERVE_SPACES_OPTION,
4951
pugSortAttributes: PUG_SORT_ATTRIBUTES_OPTION,
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import type { ChoiceSupportOption } from 'prettier';
2+
import { CATEGORY_PUG } from './constants';
3+
4+
/** Pug bracket same line option. */
5+
export const PUG_CLOSING_BRACKET_INDENT_DEPTH_OPTION: ChoiceSupportOption<PugClosingBracketIndentDepth> =
6+
{
7+
// since: '3.1.0',
8+
category: CATEGORY_PUG,
9+
type: 'choice',
10+
default: 0,
11+
description:
12+
'Determines the indent level of closing brackets when wrapping attributes.',
13+
choices: [
14+
{
15+
value: 0,
16+
description: `
17+
Closing bracket aligns with the element.
18+
Example:
19+
input(
20+
type='text',
21+
value='my_value',
22+
name='my_name',
23+
alt='my_alt',
24+
autocomplete='on'
25+
)
26+
`,
27+
},
28+
{
29+
value: 1,
30+
description: `
31+
Closing bracket aligns with the element's attributes.
32+
Example:
33+
input(
34+
type='text',
35+
value='my_value',
36+
name='my_name',
37+
alt='my_alt',
38+
autocomplete='on'
39+
)
40+
`,
41+
},
42+
],
43+
};
44+
45+
/** Pug closing bracket indent depth. */
46+
export type PugClosingBracketIndentDepth = 0 | 1;

src/options/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
import type { PugAttributeSeparator } from './pug-attribute-separator';
99
import type { PugClassLocation } from './pug-class-location';
1010
import type { PugClassNotation } from './pug-class-notation';
11+
import type { PugClosingBracketIndentDepth } from './pug-closing-bracket-indent-depth';
1112
import type { PugCommentPreserveSpaces } from './pug-comment-preserve-spaces';
1213
import type { PugFramework } from './pug-framework';
1314
import type { PugIdNotation } from './pug-id-notation';
@@ -35,6 +36,7 @@ export interface PugParserOptions
3536
pugArrowParens: ArrowParens | null;
3637
pugSemi: boolean | null;
3738
pugBracketSameLine: boolean | null;
39+
pugClosingBracketIndentDepth: PugClosingBracketIndentDepth;
3840

3941
pugAttributeSeparator: PugAttributeSeparator;
4042

src/printer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import type { PugAttributeSeparator } from './options/pug-attribute-separator';
7171
import { resolvePugAttributeSeparatorOption } from './options/pug-attribute-separator';
7272
import type { PugClassLocation } from './options/pug-class-location';
7373
import type { PugClassNotation } from './options/pug-class-notation';
74+
import type { PugClosingBracketIndentDepth } from './options/pug-closing-bracket-indent-depth';
7475
import type { PugCommentPreserveSpaces } from './options/pug-comment-preserve-spaces';
7576
import { formatPugCommentPreserveSpaces } from './options/pug-comment-preserve-spaces';
7677
import type { PugFramework } from './options/pug-framework';
@@ -143,6 +144,7 @@ export interface PugPrinterOptions {
143144
readonly pugFramework: PugFramework;
144145
readonly pugExplicitDiv: boolean;
145146
readonly pugPreserveAttributeBrackets: boolean;
147+
readonly pugClosingBracketIndentDepth: PugClosingBracketIndentDepth;
146148
}
147149

148150
/**
@@ -1168,7 +1170,9 @@ export class PugPrinter {
11681170
if (!this.options.pugBracketSameLine) {
11691171
this.result += '\n';
11701172
}
1171-
this.result += this.indentString.repeat(this.indentLevel);
1173+
this.result += this.indentString.repeat(
1174+
this.indentLevel + this.options.pugClosingBracketIndentDepth,
1175+
);
11721176
}
11731177
this.wrapAttributes = false;
11741178

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
button(type="submit", (click)="play()", disabled)
2+
3+
hello-framework(
4+
[name]="name",
5+
[version]="version",
6+
(release)="onVersionRelease()"
7+
)
8+
9+
nav-component(locale-relative-redirect="true", highlight="home", pin="false")
10+
11+
.wrapper(
12+
data-nav,
13+
data-next="Next",
14+
data-prev="Prev",
15+
data-slides=4,
16+
data-arr=[1, 2, 3, 4, 5, 6],
17+
data-obj={ att: 1, attr2: 2 }
18+
)
19+
20+
div
21+
.nested-div-1(
22+
type="text",
23+
value="my_value1",
24+
name="my_name1",
25+
alt="my_alt1",
26+
autocomplete="on"
27+
)
28+
.nested-div-2(
29+
type="text",
30+
value="my_value2",
31+
name="my_name2",
32+
alt="my_alt2",
33+
autocomplete="on"
34+
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
button(type="submit", (click)="play()", disabled)
2+
3+
hello-framework(
4+
[name]="name",
5+
[version]="version",
6+
(release)="onVersionRelease()"
7+
)
8+
9+
nav-component(locale-relative-redirect="true", highlight="home", pin="false")
10+
11+
.wrapper(
12+
data-nav,
13+
data-next="Next",
14+
data-prev="Prev",
15+
data-slides=4,
16+
data-arr=[1, 2, 3, 4, 5, 6],
17+
data-obj={ att: 1, attr2: 2 }
18+
)
19+
20+
div
21+
.nested-div-1(
22+
type="text",
23+
value="my_value1",
24+
name="my_name1",
25+
alt="my_alt1",
26+
autocomplete="on"
27+
)
28+
.nested-div-2(
29+
type="text",
30+
value="my_value2",
31+
name="my_name2",
32+
alt="my_alt2",
33+
autocomplete="on"
34+
)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { compareFiles } from 'tests/common';
2+
import { describe, expect, it } from 'vitest';
3+
4+
describe('Options', () => {
5+
describe('pugClosingBracketIndentDepth', () => {
6+
it('should handle pugClosingBracketIndentDepth:0', async () => {
7+
const { actual, expected } = await compareFiles(import.meta.url, {
8+
target: 'depth-0.pug',
9+
formatOptions: {
10+
pugBracketSameLine: false,
11+
pugClosingBracketIndentDepth: 0,
12+
},
13+
});
14+
expect(actual).toBe(expected);
15+
});
16+
17+
it('should handle pugClosingBracketIndentDepth:1', async () => {
18+
const { actual, expected } = await compareFiles(import.meta.url, {
19+
target: 'depth-1.pug',
20+
formatOptions: {
21+
pugBracketSameLine: false,
22+
pugClosingBracketIndentDepth: 1,
23+
},
24+
});
25+
expect(actual).toBe(expected);
26+
});
27+
28+
it('should default to 0', async () => {
29+
const { actual, expected } = await compareFiles(import.meta.url, {
30+
target: 'depth-0.pug',
31+
formatOptions: {
32+
pugBracketSameLine: false,
33+
},
34+
});
35+
expect(actual).toBe(expected);
36+
});
37+
});
38+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
button(type="submit", (click)="play()", disabled)
2+
3+
hello-framework([name]="name", [version]="version", (release)="onVersionRelease()")
4+
5+
nav-component(locale-relative-redirect="true", highlight="home", pin="false")
6+
7+
.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})
8+
9+
div
10+
div(
11+
class="nested-div-1",
12+
type="text",
13+
value="my_value1",
14+
name="my_name1",
15+
alt="my_alt1",
16+
autocomplete="on"
17+
)
18+
div(
19+
class="nested-div-2",
20+
type="text",
21+
value="my_value2",
22+
name="my_name2",
23+
alt="my_alt2",
24+
autocomplete="on"
25+
)

0 commit comments

Comments
 (0)