Skip to content

Removal of ; in enums interacts poorly with VSCode #1782

@stereotype441

Description

@stereotype441

One of the default behaviors of the VSCode Dart plugin is to run the formatter whenever the user presses ;. Usually this is really desirable. But it leads to a frustrating scenario with enums.

If the user has a "classic" (non-enhanced) enum, e.g.:

enum E { v1, v2 }

And they want to turn it into an enhanced enum, e.g.:

enum E {
  v1,
  v2;

  const E();
}

The natural way to start is to place the cursor after the identifier v2 and type ;. This causes the formatter to automatically run, and the formatter removes the ;. So what the user sees is a ; that appears briefly and then disappears. That's a very annoying user experience! When this happens to me (and it's cropped up more than a few times), I generally wind up absent-mindedly pressing ; over and over and getting increasingly frustrated before remembering that I have to do a workaround.

So far the best workaround I've found is to deliberately introduce a syntax error somewhere else in the file (which effectively disables the formatter), then type ; const E();, then remove the syntax error. This works, but it feels really wonky to have to do it.

A similar problem occurs if the classic enum is long enough to be formatted on multiple lines, e.g.:

enum E {
  reallyLongEnumeratedValueName1,
  reallyLongEnumeratedValueName2,
  reallyLongEnumeratedValueName3,
}

In this case the natural thing to do is to select the , that follows reallyLongEnumeratedValueName3 and type ;. Again, this automatically runs the formatter, which then turns the ; back into a ,. Again, very annoying!

Two possible solutions that occur to me:

(1) The formatter could consider the standard way to format an enum to include a ; after the last enumerated value. So in the short case we would have:

enum E { v1, v2; }

And in the long case we would have:

enum E {
  reallyLongEnumeratedValueName1,
  reallyLongEnumeratedValueName2,
  reallyLongEnumeratedValueName3;
}

With this change, the natural way to start changing to an enhanced enum would be to place the cursor after the ; and to start typing the next declaration, which would work just fine.

A disadvantage of this approach is that it would make classic enums look uglier than they do today.

(2) The formatter could stop trying to normalize away the redundant trailing ; in a classic enum. In other words, stop trying to convert enum E { v1, v2; } into enum E { v1, v2 } and so on.

A nice thing about this approach is that it wouldn't change the formatting of any existing code.

A disadvantage of this approach is that it leaves it up to the user to decide (and bikeshed about) whether to include a ; in a classic enum or not. That feels kind of contrary to the general philosophy that the formatter tries to be opinionated in order to prevent users from having to have bikeshedding arguments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions