Skip to content

Fix ternary formatting for all cases. #54362

@stagas

Description

@stagas

Ternary formatting currently only supports a single syntax, and it's not the ideal one.

These are the possibilities:

Case 1, current behavior:

const result =
  some_long_expression === 'a'
    ? 1
    : some_long_expression === 'b'
      ? 2
      : some_long_expression === 'c'
        ? 3
        : some_long_expression === 'd'
          ? 4
          : some_long_expression === 'e'
            ? 5
            : some_long_expression === 'f'
              ? 6
              : 7

This is clearly not the ideal formatting when doing a long ternary chain as the indentation is increasing continuously and unnecessary. The rule here is always indent an expression spanning next line.

Case 2

const result =
  some_long_expression === 'a'
    ? 1
    : some_long_expression === 'b'
    ? 2
    : some_long_expression === 'c'
    ? 3
    : some_long_expression === 'd'
    ? 4
    : some_long_expression === 'e'
    ? 5
    : some_long_expression === 'f'
    ? 6
    : 7

Here we no longer indent with the rule if the expression branch comes from a ternary's else branch, skip indent. Better. Still not very readable because the expression match result is all the way to the left, which makes it hard to read when you have many such chained, depending on the distance you have to move your eyes, you can easily skip a line, so you have to constantly look all the way to the right and all the way to the left multiple times to make sense of the positive branches.

Here's the two ideal cases,

Case 3:

const result =
  some_long_expression === 'a' ? 1 : 
  some_long_expression === 'b' ? 2 : 
  some_long_expression === 'c' ? 3 :
  some_long_expression === 'd' ? 4 :
  some_long_expression === 'e' ? 5 :
  some_long_expression === 'f' ? 6 :
  7

Case 4

const result =
  some_long_expression === 'a' ? 1
  : some_long_expression === 'b' ? 2  
  : some_long_expression === 'c' ? 3 
  : some_long_expression === 'd' ? 4 
  : some_long_expression === 'e' ? 5 
  : some_long_expression === 'f' ? 6 
  : 7

Either of the two latter are a significant improvement over the current formatting behavior. The output is closer to the expression being tested, it also resembles the "match" syntax found in Rust. Much faster to read/scan/make sense of.

This has been suggested before by @fqborges in microsoft/vscode#28560 but was dismissed, but I believe it should be reexamined.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: FormatterThe issue relates to the built-in formatterHelp WantedYou can do thisPossible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some cases

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions