Skip to content

Break lines before binary operators#7111

Merged
sosukesuzuki merged 11 commits intoprettier:mainfrom
btmills:issue3806
Jan 3, 2025
Merged

Break lines before binary operators#7111
sosukesuzuki merged 11 commits intoprettier:mainfrom
btmills:issue3806

Conversation

@btmills
Copy link
Copy Markdown
Contributor

@btmills btmills commented Dec 9, 2019

On Friday, @evilebottnawi requested a PR to resolve #3806 in v2.0 by breaking lines, where necessary, before binary operators rather than after them, putting the operators at the beginning of each line.

Previously, there was special case logic to break lines before pipe operators but after all other operators. I removed the special case handling so that line breaks occur before all operators.

I left the implementation, tests, and changelog as separate commits to help ease review. Happy to squash or make any other changes as necessary to help get this in!

fixes #3806

  • I’ve added tests to confirm my change works.
  • (If changing the API or CLI) I’ve documented the changes I’ve made (in the docs/ directory)
  • (If the change is user-facing) I’ve added my changes to changelog_unreleased/*/pr-XXXX.md file following changelog_unreleased/TEMPLATE.md.
  • I’ve read the contributing guidelines.

Try the playground for this PR

@alexander-akait
Copy link
Copy Markdown
Member

/cc @prettier/core will be great if you look at this

@thorn0
Copy link
Copy Markdown
Member

thorn0 commented Dec 9, 2019

I thought there was a consensus that 2.0 would be focused on deprecating old Node versions etc. Updating to 2.0 should not lead to massive code reformatting. Otherwise too many people might prefer to keep using 1.x.

@GrimzEcho
Copy link
Copy Markdown

The main 2.0 thread(s) have mainly talked about Node versions, but there have also been many comments on not introducing changes that there is disagreement or lack of consensus on.

But there seems to be a very strong consensus on the proposed fix to #3806. The only argument offered against the change is that it would be breaking and shouldn't be implemented in a minor version. However, for the change itself, there is widespread agreement both in the issue thread and in the JavaScript community.

AirBnB Issue: airbnb/javascript#1281
AirBnB Style Guidelines: https://github.com/airbnb/javascript#comparison--nested-ternaries

StandardJS (based on ESLint, widely used): https://standardjs.com/rules.html

@thorn0
Copy link
Copy Markdown
Member

thorn0 commented Dec 10, 2019

@BrianHVB You completely miss the point of why the ex-2.0 was renamed to 3.0. I'm not saying that there is no consensus about this change, only that first things first.

@thorn0 thorn0 modified the milestones: 2.0, 3.0 Jan 9, 2020
@thorn0 thorn0 force-pushed the next branch 2 times, most recently from e16f758 to 7d88fb8 Compare January 10, 2020 00:39
@fisker
Copy link
Copy Markdown
Member

fisker commented Jan 31, 2020

Anyone considered break line both before and after?

const isEventTarget = value != null
  && 
    typeof value.addEventListener === "function"
  && 
    typeof value.removeEventListener === "function"
  && 
    typeof value.dispatchEvent === "function"
  && 
    typeof value.dispatchEvent === "function"
  -
    Also_Nice_With_A_Shorter_Operator_Inside
  ?
    SOME_OTHER_EXPRESSION
  ??
    SOME_OTHER_EXPRESSION
  instanceof
    Even_Longer_Operator

@btmills btmills force-pushed the issue3806 branch 3 times, most recently from ba9d939 to 300b900 Compare February 3, 2020 06:00
@btmills
Copy link
Copy Markdown
Contributor Author

btmills commented Feb 3, 2020

I've rebased this change on next to resolve merge conflicts, added tests verifying that this change only moves binary operators to the beginning of lines while leaving assignment operators on their previous lines, and corrected the changelog in 300b900.

@VincentLanglet
Copy link
Copy Markdown

@btmills There is still a conflict

Comment on lines +16 to +19
(isAnyValueSelected
&& node.getAttribute(radioAttr.toLowerCase()) === radioValue)
|| (!isAnyValueSelected && values[a].default === true)
|| a === 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to also change this case where the multiline operators are nested? When I encounter such a case in my code, I usually refactor it so that prettier doesn't make it ugly like that. If I was writing it manually I would write something like:

  (
    isAnyValueSelected
    && node.getAttribute(radioAttr.toLowerCase()) === radioValue
  )
  || (
    !isAnyValueSelected 
    && values[a].default === true
  )
  || a === 0;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to keep this change as small as possible to improve the odds the team decides to merge it. Based on the volume of 👍s on #3806, putting binary operators at the beginning of lines has pretty widespread support. It helps that the logic change to do that exclusively deletes code. I'm concerned that expanding the scope could reduce the chance it gets merged at all.

Copy link
Copy Markdown

@phaux phaux Mar 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I didn't mean this comment to show as a "review" of this PR. It was just a random question 😅 This needs a separate issue.

@btmills
Copy link
Copy Markdown
Contributor Author

btmills commented Mar 2, 2020

@btmills There is still a conflict

@VincentLanglet I'm not surprised one of the snapshots has been updated since I last rebased. Rebasing the branch takes several minutes, so I haven't been actively monitoring this PR to keep it up to date. If the team indicates they're interested in merging, I'll certainly do another rebase as soon as possible!

@thorn0 thorn0 closed this Mar 22, 2020
@thorn0 thorn0 reopened this Mar 22, 2020
@thorn0 thorn0 changed the base branch from next to master March 22, 2020 21:11
@btmills btmills force-pushed the issue3806 branch 2 times, most recently from f5f93ae to 8723d6b Compare March 22, 2020 23:12
@btmills
Copy link
Copy Markdown
Contributor Author

btmills commented Mar 23, 2020

I’ve rebased this on top of master now that 2.0 has been released.

@tattali
Copy link
Copy Markdown

tattali commented Jul 13, 2020

Hi, it looks like the conflicting files are just snapshots and this for years.
Are there any plans to merge this pull request into a milestone?

There has been a lot of discussion around this PR I think it is a quite important one.

Thank you!

@storm85049
Copy link
Copy Markdown

Any chance of merging this ? 🥹

@fisker fisker mentioned this pull request Nov 24, 2024
11 tasks
@fisker fisker changed the title JS: Break lines before binary operators (fixes #3806) JS: Break lines before binary operators Nov 24, 2024
@fisker fisker changed the title JS: Break lines before binary operators Break lines before binary operators Nov 24, 2024
@sosukesuzuki sosukesuzuki modified the milestones: 4.0, 3.5 Nov 24, 2024
btmills and others added 10 commits November 24, 2024 16:27
Refs prettier#3806

These cover a few edge cases I encountered while maintaining
`@btmills/prettier` over the last few years. I'm adding them up front to
demonstrate that the `experimentalOperatorPosition` changes in a later
commit have no effect on this formatting when the flag is not enabled.
Refs prettier#3806

This merely defines the flag. A future commit will use it in updated
logic.
Right now, this flag isn't implemented, so these tests duplicate the
existing behavior. I'm adding them now so that when I implement the
flag's logic in a future commit, the changed formatting will be obvious
in the diff and easier to review.
Fixes prettier#3806 as requested in prettier#7111 (comment)

The flag's tests were already added in a previous commit, so the test
changes you see in this commit are specifically due to the new flag's
implementation.
This clones TypeScript's type union operator tests in `union-parens.ts`
and swaps the operators (& <-> |) to test the the type interesection
operator. It also runs intersection tests with the new
`experimentalOperatorPosition: "start"` flag. This does _not_ yet update
the implementation to consider the flag; to ease review, I'll make that
change in the next commit to isolate the impact of the change.
The type union operator was already formatted at the beginning of lines
by default, so that logic didn't need to be updated.
I rebased from 1dfe28f to c706678 to fix test failures related to
prettier#16601. The rebase applied
cleanly, and this was the only change to tests. Since the PR has
already been approved, I'll keep this as a separate commit rather than
squashing into the prior commits.
@btmills
Copy link
Copy Markdown
Contributor Author

btmills commented Nov 24, 2024

I rebased from 1dfe28f to c706678 (main as of writing) to fix test failures in the most recent CI run related to #16601/#16642. The rebase applied without conflicts, and 32de8ac was the only change from yarn test -u. Since this PR has already been approved, I'll keep 32de8ac as a separate commit rather than squashing into the prior commits.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Jan 3, 2025

Open in Stackblitz

npm i https://pkg.pr.new/prettier@7111

commit: 8c6ed25

@sosukesuzuki
Copy link
Copy Markdown
Contributor

CI is failing due to causes unrelated to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Placing operators at the beginning of lines