Skip to content

Commit c423ee6

Browse files
committed
Update: add alignAttributesVertically
1 parent 6dadd33 commit c423ee6

File tree

5 files changed

+132
-56
lines changed

5 files changed

+132
-56
lines changed

docs/rules/html-indent.md

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,94 +23,123 @@ This rule enforces a consistent indentation style in `<template>`. The default s
2323

2424
```html
2525
<template>
26-
<div class="foo">
27-
Hello.
28-
</div>
26+
<div class="foo">
27+
Hello.
28+
</div>
2929
</template>
3030
```
3131

3232
```html
3333
<template>
34-
<div class="foo">
35-
Hello.
36-
</div>
37-
<div
38-
id="a"
39-
class="b"
40-
:other-attr="{
41-
aaa: 1,
42-
bbb: 2
43-
}"
44-
@other-attr2="
45-
foo();
46-
bar();
47-
"
48-
>
49-
{{
50-
displayMessage
51-
}}
52-
</div>
34+
<div class="foo">
35+
Hello.
36+
</div>
37+
<div class="foo"
38+
:foo="bar"
39+
>
40+
World.
41+
</div>
42+
<div
43+
id="a"
44+
class="b"
45+
:other-attr="{
46+
aaa: 1,
47+
bbb: 2
48+
}"
49+
@other-attr2="
50+
foo();
51+
bar();
52+
"
53+
>
54+
{{
55+
displayMessage
56+
}}
57+
</div>
5358
</template>
5459
```
5560

5661
## :wrench: Options
5762

5863
```json
5964
{
60-
"vue/html-indent": ["error", type, {
61-
"attribute": 1,
62-
"closeBracket": 0,
63-
"ignores": []
64-
}]
65+
"vue/html-indent": ["error", type, {
66+
"attribute": 1,
67+
"closeBracket": 0,
68+
"alignAttributesVertically": true,
69+
"ignores": []
70+
}]
6571
}
6672
```
6773

6874
- `type` (`number | "tab"`) ... The type of indentation. Default is `2`. If this is a number, it's the number of spaces for one indent. If this is `"tab"`, it uses one tab for one indent.
6975
- `attribute` (`integer`) ... The multiplier of indentation for attributes. Default is `1`.
7076
- `closeBracket` (`integer`) ... The multiplier of indentation for right brackets. Default is `0`.
77+
- `alignAttributesVertically` (`boolean`) ... Condition for whether attributes should be vertically aligned to the first attribute in multiline case or not. Default is `true`
7178
- `ignores` (`string[]`) ... The selector to ignore nodes. The AST spec is [here](https://github.com/mysticatea/vue-eslint-parser/blob/master/docs/ast.md). You can use [esquery](https://github.com/estools/esquery#readme) to select nodes. Default is an empty array.
7279

7380
:+1: Examples of **correct** code for `{attribute: 1, closeBracket: 1}`:
7481

7582
```html
7683
<template>
77-
<div
78-
id="a"
79-
class="b"
80-
other-attr=
81-
"{longname: longvalue}"
82-
other-attr2
83-
="{longname: longvalue}"
84-
>
85-
Text
86-
</div>
84+
<div
85+
id="a"
86+
class="b"
87+
other-attr=
88+
"{longname: longvalue}"
89+
other-attr2
90+
="{longname: longvalue}"
91+
>
92+
Text
93+
</div>
8794
</template>
8895
```
8996

9097
:+1: Examples of **correct** code for `{attribute: 2, closeBracket: 1}`:
9198

9299
```html
93100
<template>
94-
<div
95-
id="a"
96-
class="b"
97-
other-attr=
98-
"{longname: longvalue}"
99-
other-attr2
100-
="{longname: longvalue}"
101-
>
102-
Text
103-
</div>
101+
<div
102+
id="a"
103+
class="b"
104+
other-attr=
105+
"{longname: longvalue}"
106+
other-attr2
107+
="{longname: longvalue}"
108+
>
109+
Text
110+
</div>
104111
</template>
105112
```
106113

107114
:+1: Examples of **correct** code for `{ignores: ["VAttribute"]}`:
108115

109116
```html
110117
<template>
111-
<div
112-
id=""
113-
class=""
114-
/>
118+
<div
119+
id=""
120+
class=""
121+
/>
122+
</template>
123+
```
124+
125+
:+1: Examples of **correct** code for `{alignAttributesVertically: true}`:
126+
127+
```html
128+
<template>
129+
<div id=""
130+
class=""
131+
some-attr=""
132+
/>
133+
</template>
134+
```
135+
136+
:+1: Examples of **correct** code for `{alignAttributesVertically: false}`:
137+
138+
```html
139+
<template>
140+
<div id=""
141+
class=""
142+
some-attr=""
143+
/>
115144
</template>
116145
```

lib/rules/html-indent.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module.exports = {
4444
'attribute': { type: 'integer', minimum: 0 },
4545
'closeBracket': { type: 'integer', minimum: 0 },
4646
'switchCase': { type: 'integer', minimum: 0 },
47+
'alignAttributesVertically': { type: 'boolean' },
4748
'ignores': {
4849
type: 'array',
4950
items: {

lib/utils/indent-common.js

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const BLOCK_COMMENT_PREFIX = /^\s*\*/
2424
* @param {number|"tab"|undefined} type The type of indentation.
2525
* @param {Object} options Other options.
2626
* @param {Object} defaultOptions The default value of options.
27-
* @returns {{indentChar:" "|"\t",indentSize:number,baseIndent:number,attribute:number,closeBracket:number,switchCase:number,ignores:string[]}} Normalized options.
27+
* @returns {{indentChar:" "|"\t",indentSize:number,baseIndent:number,attribute:number,closeBracket:number,switchCase:number,alignAttributesVertically:boolean,ignores:string[]}} Normalized options.
2828
*/
2929
function parseOptions (type, options, defaultOptions) {
3030
const ret = Object.assign({
@@ -34,6 +34,7 @@ function parseOptions (type, options, defaultOptions) {
3434
attribute: 1,
3535
closeBracket: 0,
3636
switchCase: 0,
37+
alignAttributesVertically: true,
3738
ignores: []
3839
}, defaultOptions)
3940

@@ -56,6 +57,10 @@ function parseOptions (type, options, defaultOptions) {
5657
if (Number.isSafeInteger(options.switchCase)) {
5758
ret.switchCase = options.switchCase
5859
}
60+
61+
if (options.alignAttributesVertically != null) {
62+
ret.alignAttributesVertically = options.alignAttributesVertically
63+
}
5964
if (options.ignores != null) {
6065
ret.ignores = options.ignores
6166
}
@@ -324,9 +329,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
324329
* @param {Node|null} leftToken The left parenthesis token.
325330
* @param {Node|null} rightToken The right parenthesis token.
326331
* @param {number} offset The offset to set.
332+
* @param {Node} [alignVertically=true] The flag to align vertically. If `false`, this doesn't align vertically even if the first node is not at beginning of line.
327333
* @returns {void}
328334
*/
329-
function processNodeList (nodeList, leftToken, rightToken, offset) {
335+
function processNodeList (nodeList, leftToken, rightToken, offset, alignVertically) {
330336
let t
331337

332338
if (nodeList.length >= 1) {
@@ -373,11 +379,18 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
373379
setOffset(baseToken, offset, leftToken)
374380
}
375381

376-
// Align the rest tokens to the first token.
382+
// Set baseline.
377383
if (nodeList.some(isBeginningOfLine)) {
378384
setBaseline(baseToken)
379385
}
380-
setOffset(alignTokens, 0, baseToken)
386+
387+
if (alignVertically === false) {
388+
// Align tokens relatively to the left token.
389+
setOffset(alignTokens, offset, leftToken)
390+
} else {
391+
// Align the rest tokens to the first token.
392+
setOffset(alignTokens, 0, baseToken)
393+
}
381394
}
382395
}
383396

@@ -800,7 +813,13 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
800813
const openToken = tokenStore.getFirstToken(node)
801814
const closeToken = tokenStore.getLastToken(node)
802815

803-
processNodeList(node.attributes, openToken, null, options.attribute)
816+
processNodeList(
817+
node.attributes,
818+
openToken,
819+
null,
820+
options.attribute,
821+
options.alignAttributesVertically
822+
)
804823
if (closeToken != null && closeToken.type.endsWith('TagClose')) {
805824
setOffset(closeToken, options.closeBracket, openToken)
806825
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!--{"options":[2,{"alignAttributesVertically":false}]}-->
2+
<template>
3+
<div
4+
a="a"
5+
b="b"
6+
c=
7+
"c"
8+
d
9+
="d"
10+
e
11+
f
12+
=
13+
></div>
14+
</template>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!--{"options":[2,{"alignAttributesVertically":false}]}-->
2+
<template>
3+
<div a="a"
4+
b="b"
5+
c=
6+
"c"
7+
d
8+
="d"
9+
e
10+
f
11+
=
12+
></div>
13+
</template>

0 commit comments

Comments
 (0)