diff --git a/docs/rules/indent.md b/docs/rules/indent.md index c46053c6..7e9bde25 100644 --- a/docs/rules/indent.md +++ b/docs/rules/indent.md @@ -129,3 +129,5 @@ This rule has an object option: - `Attribute` (default: 1): Specifies the attribute indentation level. e.g. indent of 2 spaces with `Attribute` set to `2` will indent the attributes with `4` spaces (2 x 2). - `tagChildrenIndent` (default: `{}`): Specifies the indent increment of the child tags of the specified tag. e.g. For example, `"tagChildrenIndent": { "html": 0 }` will set the `` tag children to 0 indent (2 x 0). + +- `ignoreComment` (default: `false`): When set to `true`, the indentation of HTML comments (including opening ``, and content) will not be checked. This is useful when you want to allow free-form indentation for comments. diff --git a/packages/eslint-plugin/lib/rules/indent/indent.js b/packages/eslint-plugin/lib/rules/indent/indent.js index 13da640d..0f8ff3d5 100644 --- a/packages/eslint-plugin/lib/rules/indent/indent.js +++ b/packages/eslint-plugin/lib/rules/indent/indent.js @@ -18,6 +18,7 @@ * @typedef {Object} Option2 * @property {number} [Option2.Attribute] * @property {Record} [Option2.tagChildrenIndent] + * @property {boolean} [Option2.ignoreComment] */ const { parseTemplateLiteral } = require("../utils/template-literal"); @@ -97,6 +98,10 @@ module.exports = { }, additionalProperties: false, }, + ignoreComment: { + type: "boolean", + default: false, + }, }, additionalProperties: false, }, @@ -110,6 +115,7 @@ module.exports = { const sourceCode = getSourceCode(context); const indentLevelOptions = (context.options && context.options[1]) || {}; const lines = sourceCode.getLines(); + const ignoreComment = indentLevelOptions.ignoreComment === true; const { indentType, indentSize, indentChar } = getIndentOptionInfo(context); /** @@ -265,6 +271,48 @@ module.exports = { } } + /** + * @type {RuleListener} + */ + const commentVisitor = { + Comment(node) { + indentLevel.indent(node); + }, + CommentOpen: checkIndent, + CommentContent(node) { + indentLevel.indent(node); + if (hasTemplate(node)) { + node.parts.forEach((part) => { + if (part.type !== NODE_TYPES.Part) { + if (part.open) { + checkIndent(part.open); + } + if (part.close) { + checkIndent(part.close); + } + } + }); + } + + const lineNodes = splitToLineNodes(node); + lineNodes.forEach((lineNode) => { + if (lineNode.hasTemplate) { + return; + } + if (lineNode.value.trim().length) { + checkIndent(lineNode); + } + }); + }, + CommentClose: checkIndent, + "Comment:exit"(node) { + indentLevel.dedent(node); + }, + "CommentContent:exit"(node) { + indentLevel.dedent(node); + }, + }; + /** * @type {RuleListener} */ @@ -342,42 +390,7 @@ module.exports = { "Text:exit"(node) { indentLevel.dedent(node); }, - Comment(node) { - indentLevel.indent(node); - }, - CommentOpen: checkIndent, - CommentContent(node) { - indentLevel.indent(node); - if (hasTemplate(node)) { - node.parts.forEach((part) => { - if (part.type !== NODE_TYPES.Part) { - if (part.open) { - checkIndent(part.open); - } - if (part.close) { - checkIndent(part.close); - } - } - }); - } - - const lineNodes = splitToLineNodes(node); - lineNodes.forEach((lineNode) => { - if (lineNode.hasTemplate) { - return; - } - if (lineNode.value.trim().length) { - checkIndent(lineNode); - } - }); - }, - CommentClose: checkIndent, - "Comment:exit"(node) { - indentLevel.dedent(node); - }, - "CommentContent:exit"(node) { - indentLevel.dedent(node); - }, + ...(ignoreComment ? {} : commentVisitor), }; return visitor; } diff --git a/packages/eslint-plugin/tests/rules/indent.test.js b/packages/eslint-plugin/tests/rules/indent.test.js index 9d1af6fe..ce8f6fab 100644 --- a/packages/eslint-plugin/tests/rules/indent.test.js +++ b/packages/eslint-plugin/tests/rules/indent.test.js @@ -519,6 +519,40 @@ text }, ], }, + { + code: ` +
+ text + +
+ `, + options: [ + 2, + { + ignoreComment: true, + }, + ], + }, + { + code: ` +
+ text + +
+ `, + options: [ + 2, + { + ignoreComment: true, + }, + ], + }, ], invalid: [ { @@ -1409,6 +1443,33 @@ text `, }, + { + code: ` +
+ text + +
+ `, + output: ` +
+ text + +
+ `, + options: [ + 2, + { + ignoreComment: false, + }, + ], + errors: wrongIndentErrors(2), + }, ], }; }