`. The default s
- `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.
- `attribute` (`integer`) ... The multiplier of indentation for attributes. Default is `1`.
- `baseIndent` (`integer`) ... The multiplier of indentation for top-level statements. Default is `1`.
-- `closeBracket` (`integer`) ... The multiplier of indentation for right brackets. Default is `0`.
+- `closeBracket` (`integer | object`) ... The multiplier of indentation for right brackets. Default is `0`.
+ You can apply all of the following by setting a number value.
+ - `closeBracket.startTag` (`integer`) ... The multiplier of indentation for right brackets of start tags (``). Default is `0`.
+ - `closeBracket.endTag` (`integer`) ... The multiplier of indentation for right brackets of end tags (`
`). Default is `0`.
+ - `closeBracket.selfClosingTag` (`integer`) ... The multiplier of indentation for right brackets of start tags (``). Default is `0`.
- `alignAttributesVertically` (`boolean`) ... Condition for whether attributes should be vertically aligned to the first attribute in multiline case or not. Default is `true`
- `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.
diff --git a/lib/rules/html-indent.js b/lib/rules/html-indent.js
index d62f6f3a5..9cbea60c7 100644
--- a/lib/rules/html-indent.js
+++ b/lib/rules/html-indent.js
@@ -44,7 +44,20 @@ module.exports = {
properties: {
attribute: { type: 'integer', minimum: 0 },
baseIndent: { type: 'integer', minimum: 0 },
- closeBracket: { type: 'integer', minimum: 0 },
+ closeBracket: {
+ anyOf: [
+ { type: 'integer', minimum: 0 },
+ {
+ type: 'object',
+ properties: {
+ startTag: { type: 'integer', minimum: 0 },
+ endTag: { type: 'integer', minimum: 0 },
+ selfClosingTag: { type: 'integer', minimum: 0 }
+ },
+ additionalProperties: false
+ }
+ ]
+ },
switchCase: { type: 'integer', minimum: 0 },
alignAttributesVertically: { type: 'boolean' },
ignores: {
diff --git a/lib/utils/indent-common.js b/lib/utils/indent-common.js
index 1c8c3838a..a69d7a5d2 100644
--- a/lib/utils/indent-common.js
+++ b/lib/utils/indent-common.js
@@ -21,12 +21,26 @@ const BLOCK_COMMENT_PREFIX = /^\s*\*/
const ITERATION_OPTS = Object.freeze({ includeComments: true, filter: isNotWhitespace })
const PREFORMATTED_ELEMENT_NAMES = ['pre', 'textarea']
+/**
+ * @typedef {object} IndentOptions
+ * @property { " " | "\t" } IndentOptions.indentChar
+ * @property {number} IndentOptions.indentSize
+ * @property {number} IndentOptions.baseIndent
+ * @property {number} IndentOptions.attribute
+ * @property {object} IndentOptions.closeBracket
+ * @property {number} IndentOptions.closeBracket.startTag
+ * @property {number} IndentOptions.closeBracket.endTag
+ * @property {number} IndentOptions.closeBracket.selfClosingTag
+ * @property {number} IndentOptions.switchCase
+ * @property {boolean} IndentOptions.alignAttributesVertically
+ * @property {string[]} IndentOptions.ignores
+ */
/**
* Normalize options.
* @param {number|"tab"|undefined} type The type of indentation.
* @param {Object} options Other options.
* @param {Object} defaultOptions The default value of options.
- * @returns {{indentChar:" "|"\t",indentSize:number,baseIndent:number,attribute:number,closeBracket:number,switchCase:number,alignAttributesVertically:boolean,ignores:string[]}} Normalized options.
+ * @returns {IndentOptions} Normalized options.
*/
function parseOptions (type, options, defaultOptions) {
const ret = Object.assign({
@@ -34,7 +48,11 @@ function parseOptions (type, options, defaultOptions) {
indentSize: 2,
baseIndent: 0,
attribute: 1,
- closeBracket: 0,
+ closeBracket: {
+ startTag: 0,
+ endTag: 0,
+ selfClosingTag: 0
+ },
switchCase: 0,
alignAttributesVertically: true,
ignores: []
@@ -54,7 +72,21 @@ function parseOptions (type, options, defaultOptions) {
ret.attribute = options.attribute
}
if (Number.isSafeInteger(options.closeBracket)) {
- ret.closeBracket = options.closeBracket
+ const num = options.closeBracket
+ ret.closeBracket = {
+ startTag: num,
+ endTag: num,
+ selfClosingTag: num
+ }
+ } else if (options.closeBracket) {
+ ret.closeBracket = Object.assign(
+ {
+ startTag: 0,
+ endTag: 0,
+ selfClosingTag: 0
+ },
+ options.closeBracket
+ )
}
if (Number.isSafeInteger(options.switchCase)) {
ret.switchCase = options.switchCase
@@ -919,11 +951,12 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
},
VEndTag (node) {
- const openToken = tokenStore.getFirstToken(node)
+ const element = node.parent
+ const startTagOpenToken = tokenStore.getFirstToken(element.startTag)
const closeToken = tokenStore.getLastToken(node)
if (closeToken.type.endsWith('TagClose')) {
- setOffset(closeToken, options.closeBracket, openToken)
+ setOffset(closeToken, options.closeBracket.endTag, startTagOpenToken)
}
},
@@ -996,7 +1029,10 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
options.alignAttributesVertically
)
if (closeToken != null && closeToken.type.endsWith('TagClose')) {
- setOffset(closeToken, options.closeBracket, openToken)
+ const offset = closeToken.type !== 'HTMLSelfClosingTagClose'
+ ? options.closeBracket.startTag
+ : options.closeBracket.selfClosingTag
+ setOffset(closeToken, offset, openToken)
}
},
diff --git a/tests/fixtures/html-indent/close-bracket-01.vue b/tests/fixtures/html-indent/close-bracket-01.vue
new file mode 100644
index 000000000..3307b1454
--- /dev/null
+++ b/tests/fixtures/html-indent/close-bracket-01.vue
@@ -0,0 +1,16 @@
+
+
+ Link 1
+
+ Link 2
+ Content
+
+
diff --git a/tests/fixtures/html-indent/close-bracket-02.vue b/tests/fixtures/html-indent/close-bracket-02.vue
new file mode 100644
index 000000000..3f171a69a
--- /dev/null
+++ b/tests/fixtures/html-indent/close-bracket-02.vue
@@ -0,0 +1,16 @@
+
+
+ Link 1
+
+ Link 2
+ Content
+
+
diff --git a/tests/fixtures/html-indent/close-bracket-03.vue b/tests/fixtures/html-indent/close-bracket-03.vue
new file mode 100644
index 000000000..518423c41
--- /dev/null
+++ b/tests/fixtures/html-indent/close-bracket-03.vue
@@ -0,0 +1,16 @@
+
+
+ Link 1
+
+ Link 2
+ Content
+
+
diff --git a/tests/fixtures/html-indent/close-bracket-04.vue b/tests/fixtures/html-indent/close-bracket-04.vue
new file mode 100644
index 000000000..f90ffc4de
--- /dev/null
+++ b/tests/fixtures/html-indent/close-bracket-04.vue
@@ -0,0 +1,16 @@
+
+
+ Link 1
+
+ Link 2
+ Content
+
+
diff --git a/tests/fixtures/html-indent/close-bracket-05.vue b/tests/fixtures/html-indent/close-bracket-05.vue
new file mode 100644
index 000000000..b5d48275a
--- /dev/null
+++ b/tests/fixtures/html-indent/close-bracket-05.vue
@@ -0,0 +1,16 @@
+
+
+ Link 1
+
+ Link 2
+ Content
+
+
diff --git a/tests/fixtures/html-indent/close-bracket-06.vue b/tests/fixtures/html-indent/close-bracket-06.vue
new file mode 100644
index 000000000..d5bae8ed4
--- /dev/null
+++ b/tests/fixtures/html-indent/close-bracket-06.vue
@@ -0,0 +1,16 @@
+
+
+ Link 1
+
+ Link 2
+ Content
+
+