From b96c3b4464d5d59ae7d02e3c9f21ab73b8a39645 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 11 Nov 2019 14:21:03 +0100 Subject: [PATCH] Allow to offset ternary expressions --- docs/rules/indent.md | 71 +++++++++++++++++++++++++++++++++++++++ lib/rules/indent.js | 11 ++++-- tests/lib/rules/indent.js | 32 ++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) diff --git a/docs/rules/indent.md b/docs/rules/indent.md index 0e58352fcbdd..39d62ef83f43 100644 --- a/docs/rules/indent.md +++ b/docs/rules/indent.md @@ -84,6 +84,7 @@ This rule has an object option: * `"ObjectExpression"` (default: 1) enforces indentation level for properties in objects. It can be set to the string `"first"`, indicating that all properties in the object should be aligned with the first property. This can also be set to `"off"` to disable checking for object properties. * `"ImportDeclaration"` (default: 1) enforces indentation level for import statements. It can be set to the string `"first"`, indicating that all imported members from a module should be aligned with the first member in the list. This can also be set to `"off"` to disable checking for imported module members. * `"flatTernaryExpressions": true` (`false` by default) requires no indentation for ternary expressions which are nested in other ternary expressions. +* `"offsetTernaryExpressions": true` (`false` by default) requires indentation for values of ternary expressions * `"ignoredNodes"` accepts an array of [selectors](/docs/developer-guide/selectors.md). If an AST node is matched by any of the selectors, the indentation of tokens which are direct children of that node will be ignored. This can be used as an escape hatch to relax the rule if you disagree with the indentation that it enforces for a particular syntactic pattern. * `"ignoreComments"` (default: false) can be used when comments do not need to be aligned with nodes on the previous or next line. @@ -643,6 +644,76 @@ var a = boop; ``` +### offsetTernaryExpressions + +Examples of **incorrect** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/ + +condition + ? () => { + return true + } + : () => { + false + } +``` + +Examples of **correct** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/ + +condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } +``` + +Examples of **incorrect** code for this rule with the `2, { "offsetTernaryExpressions": true }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/ + +condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } +``` + +Examples of **correct** code for this rule with the `2, { "offsetTernaryExpressions": true }` option: + +```js +/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/ + +condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } +``` + ### ignoredNodes The following configuration ignores the indentation of `ConditionalExpression` ("ternary expression") nodes: diff --git a/lib/rules/indent.js b/lib/rules/indent.js index 94c83692b39f..57b2001a96d9 100644 --- a/lib/rules/indent.js +++ b/lib/rules/indent.js @@ -590,6 +590,10 @@ module.exports = { type: "boolean", default: false }, + offsetTernaryExpressions: { + type: "boolean", + default: false + }, ignoredNodes: { type: "array", items: { @@ -1142,7 +1146,8 @@ module.exports = { offsets.setDesiredOffset(questionMarkToken, firstToken, 1); offsets.setDesiredOffset(colonToken, firstToken, 1); - offsets.setDesiredOffset(firstConsequentToken, firstToken, 1); + offsets.setDesiredOffset(firstConsequentToken, firstToken, + options.offsetTernaryExpressions ? 2 : 1); /* * The alternate and the consequent should usually have the same indentation. @@ -1167,7 +1172,9 @@ module.exports = { * If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up * having no expected indentation. */ - offsets.setDesiredOffset(firstAlternateToken, firstToken, 1); + offsets.setDesiredOffset(firstAlternateToken, firstToken, + firstAlternateToken.type === "Punctuator" && + options.offsetTernaryExpressions ? 2 : 1); } } }, diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js index 96b7463921c8..1f282fb88438 100644 --- a/tests/lib/rules/indent.js +++ b/tests/lib/rules/indent.js @@ -2097,6 +2097,38 @@ ruleTester.run("indent", rule, { `, options: [2] }, + { + code: unIndent` + condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } + `, + options: [2] + }, + { + code: unIndent` + condition + ? () => { + return true + } + : condition2 + ? () => { + return true + } + : () => { + return false + } + `, + options: [2, { offsetTernaryExpressions: true }] + }, unIndent` [ foo ?