Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please include the ability to configure indent on conditional expressions #12674

Closed
t-rad679 opened this issue Dec 16, 2019 · 6 comments
Closed
Labels
archived due to age This issue has been archived; please open a new issue for any further discussion auto closed The bot closed this issue enhancement This change enhances an existing feature of ESLint evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion rule Relates to ESLint's core rules

Comments

@t-rad679
Copy link

What rule do you want to change?
indent

Does this change cause the rule to produce more or fewer warnings?
more

How will the change be implemented? (New option, new default behavior, etc.)?
new option

Please provide some example code that this change will affect:

Existing:

        'indent': [
            'error',
            4,
            {
                'CallExpression': {
                    'arguments': 2,
                },
                'FunctionDeclaration': {
                    'body': 1,
                    'parameters': 2,
                },
                'FunctionExpression': {
                    'body': 1,
                    'parameters': 2,
                },
                'MemberExpression': 2,
                'ObjectExpression': 1,
                'SwitchCase': 1,
                'ignoredNodes': [
                    'ConditionalExpression',
                ],
            },
        ],

Desired (Example):

        'indent': [
            'error',
            4,
            {
                'CallExpression': {
                    'arguments': 2,
                },
                'FunctionDeclaration': {
                    'body': 1,
                    'parameters': 2,
                },
                'FunctionExpression': {
                    'body': 1,
                    'parameters': 2,
                },
                'MemberExpression': 2,
                'ObjectExpression': 1,
                'SwitchCase': 1,
                'ConditionalExpression: 1,
            },
        ],

What does the rule currently do for this code?
The only way to configure indent behavior for conditional (ternary) expressions is to ignore them completely

What will the rule do after it's changed?
Conditional expressions will be configurable, just as every other kind of expression. At the very least, it should be possible to automatically bring conditional expressions into conformance with the rest of the code base, which it does not currently seem to do.

Are you willing to submit a pull request to implement this change?
I have no idea how to do that. Maybe if you can give me enough of a description on how to make it happen, I could give it a shot, but I am not familiar at all with JS, so my code might be less than great.

@t-rad679 t-rad679 added enhancement This change enhances an existing feature of ESLint rule Relates to ESLint's core rules triage An ESLint team member will look at this issue soon labels Dec 16, 2019
@kaicataldo kaicataldo added evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion and removed triage An ESLint team member will look at this issue soon labels Dec 16, 2019
@kaicataldo
Copy link
Member

It would be really helpful to us in evaluating your proposal if you include what the rule will actually allow/disallow using code examples. Some specific questions I have:

  1. I'm assuming this will only apply to multiline ternary expressions. What's the expected behavior for the following cases?
const a = b 
    ? c 
    : d;

const a = b ? 
    c :
    d;

const a = b ? c :
    d;

const a = b
    ? c :
    d;

const a = (
        b || c
    ) ? d :
    {
        e: true
    };
  1. How would this new option interact with the existing flatTernaryExpressions option?

I personally think a more generic option that configures the indentation of multiline expressions might be more useful (see #12248).

@kaicataldo
Copy link
Member

Ah, I found it! Sorry, thought it was an issue. #12556

Do the proposed changes in that PR satisfy your use case?

@t-rad679
Copy link
Author

Thank you for your prompt reply!

Yeah, a generalized multiline expression config would be better. I was under the impression that was already happening for most expressions, though. In most cases, it seems to correctly handle my multiline cases...i.e.

for (blah in blahs) {
    const thisStatementIsMultiline =
            someReallyLongStuffThatDeservesItsOwnLine();
}

This seems to be handled correctly.

However, in looking through the codebase to make sure I have everything I'm telling you correct, I did run across an odd case:

function isAVuexModule() {
   return (
        _.isPlainObject(options) &&
  _.isPlainObject(options.state) &&
  _.isPlainObject(options.getters) &&
  _.isPlainObject(options.mutations) &&
  _.isPlainObject(options.actions)
    );
}

This is unexpected in several ways (I recognize that not all of these are relevant to this PR):

  • The opening paren is on a different line than the first element
  • The first element is the first continuation line (the second element should be
    first continuation line)
  • The first continuation line is only indented 4 spaces (8 expected)
  • The subsequent continuation lines are not indented at all
  • The closing paren (which should be on the same line as the last element) is
    indented two additional spaces. Even if you wanted your closing paren on the
    next line, this is an incorrect indentation. IIUC, nothing is configured for 2 spaces.

Whatever solution we come to also ought to fix this; so, I agree, doing this just for Conditional Expressions is not the best way to proceed. What I would expect in this scenario is:

function isAVuexModule() {
        return (_.isPlainObject(options) &&
                _.isPlainObject(options.state) &&
                _.isPlainObject(options.getters) &&
                _.isPlainObject(options.mutations) &&
                _.isPlainObject(options.actions));
}

(To be clear, the behavior I want is not to have the continuations line up with the argument on the first line. It's all about 8 spaces aka double the normal indent)

Now to answer your questions:

// Ideally, one this short would be on one line. If it's broken, it would be
// the following.

// The first 4 should look like this
const a = b ?
        c :
        d;

const a = (b || c) ?
        d :
        {e: true};
// Or, if the inline object is too long for one line
const a = (b || c) ?
        d :
        {
            e : true
        };
  1. If used in conjunction with flatTernaryExpressions, it depends on a number of things, really. First of all, I find the example very difficult to read as is. I think something like this would be ideal:
var a = foo ?
        bar :
        baz ? qux : boop;

With flatTernaryExpressions set to false, it should look like this:

var a = foo ?
        bar :
                baz ? qux : boop;

If qux : boop is too long, it should look like this:

var a = foo ?
        bar :
                baz ?
                        qux :
                        boop;

Does that help?

@t-rad679
Copy link
Author

Just looked at that PR you linked. I don't think it addresses the issue, though it is important. Correct me if I'm wrong, but it seems like that PR would allow for the following:

// Format...
foo ?
    bar => {
    function();
    } :
    baz;
// Into...
foo ?
    bar => {
        function();
    } :
    baz;

This seems important; the latter seems like the correct behavior. However, what I'm looking for is the following:

// Format...
foo ?
    bar => {
        function();
    } :
    baz;
// Into...
foo ?
        bar => {
            function();
        } :
        baz;

@kaicataldo
Copy link
Member

These seem like two separate issues to me - do you mind creating a separate issue for the latter one?

I don't think we're quite on the same page. The indent rule enforces indentation but doesn't add newlines. You can see an example here.

It sounds like what you're looking for is the following:

/*eslint indent: ["error", 4, { "ConditionalExpression": 2 }]*/

// Incorrect
foo ?
    bar => {
        function();
    } :
    baz;

// Correct
foo ?
        bar => {
            function();
        } :
        baz;
/*eslint indent: ["error", 4, { "ConditionalExpression": 2, "flatTernaryExpressions": false }]*/

// Incorrect
var a =
    foo ? bar :
    baz ? qux :
    boop;


// Correct
var a =
    foo ? bar :
            baz ? qux :
                    boop;
/*eslint indent: ["error", 4, { "ConditionalExpression": 2, "flatTernaryExpressions": true }]*/

// Inorrect
var a =
    foo ? bar :
            baz ? qux :
                    boop;

// Correct
var a =
        foo ? bar :
        baz ? qux :
        boop;

@eslint-deprecated eslint-deprecated bot added the auto closed The bot closed this issue label Jan 18, 2020
@eslint-deprecated
Copy link

Unfortunately, it looks like there wasn't enough interest from the team
or community to implement this change. While we wish we'd be able to
accommodate everyone's requests, we do need to prioritize. We've found
that issues failing to reach accepted status after 21 days tend to
never be accepted, and as such, we close those issues.
This doesn't mean the idea isn't interesting or useful, just that it's
not something the team can commit to.

Thanks for contributing to ESLint and we appreciate your understanding.

@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Jul 18, 2020
@eslint-deprecated eslint-deprecated bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Jul 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
archived due to age This issue has been archived; please open a new issue for any further discussion auto closed The bot closed this issue enhancement This change enhances an existing feature of ESLint evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion rule Relates to ESLint's core rules
Projects
None yet
Development

No branches or pull requests

2 participants