prettier: Respect/Enforce line break after class declaration

Respect/Enforce line break after class declaration, I’m talking about second line break after export class X {

Less readable:

export class SlackPeopleSync {
  constructor(setting: Setting) {
    this.setting = setting
    this.loader = new SlackLoader(this.setting)
  }

  async run() {
    console.log(`loading slack users`)
    const users = await this.loader.loadUsers()
    console.log(`loaded slack users`, users)
    const bits = await Promise.all(
      users.map(user => createOrUpdatePerson(user)),
    )
    console.log(`updated bits`, bits)
  }
}

More readable:

export class SlackPeopleSync {

  constructor(setting: Setting) {
    this.setting = setting
    this.loader = new SlackLoader(this.setting)
  }

  async run() {
    console.log(`loading slack users`)
    const users = await this.loader.loadUsers()
    console.log(`loaded slack users`, users)
    const bits = await Promise.all(
      users.map(user => createOrUpdatePerson(user)),
    )
    console.log(`updated bits`, bits)
  }

}

Less readable:

export class SlackPeopleSync {
  setting: Setting
  loader: SlackLoader

  constructor(setting: Setting) {
    this.setting = setting
    this.loader = new SlackLoader(this.setting)
  }

  async run() {
    console.log(`loading slack users`)
    const users = await this.loader.loadUsers()
    console.log(`loaded slack users`, users)
    const bits = await Promise.all(
      users.map(user => createOrUpdatePerson(user)),
    )
    console.log(`updated bits`, bits)
  }
}

More readable:

export class SlackPeopleSync {

  setting: Setting
  loader: SlackLoader

  constructor(setting: Setting) {
    this.setting = setting
    this.loader = new SlackLoader(this.setting)
  }

  async run() {
    console.log(`loading slack users`)
    const users = await this.loader.loadUsers()
    console.log(`loaded slack users`, users)
    const bits = await Promise.all(
      users.map(user => createOrUpdatePerson(user)),
    )
    console.log(`updated bits`, bits)
  }

}

All class-based languages I know follow the same formatting.

This proposal also adds line break before closing curly brace to keep consistence with opening line break.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 156
  • Comments: 68 (13 by maintainers)

Most upvoted comments

Since we don’t support this style anywhere else, I feel like we shouldn’t enforce a change to it because it would be inconsistent with the rest of the code. IMO the first one is just as readable so I don’t see the need to change this.

In your opinion its readable, and maybe its based on your addictions, maybe just like mine. For me its extremely messy and my eyes hurt when I read it. Return lines are very important to make code more readable, and one another thing I hate in prettier is that it does not allow me to add return line after method/function declaration. Example:

screenshot 2018-07-22 16 43 54 screenshot 2018-07-22 16 44 29

First code is how I usually write it, second is re-formatted by prettier. Which one you find more readable?

I would like you to take attention on this part:

screenshot 2018-07-22 16 47 38

If I could add a return line between method declaration and code it could look better.

After reading this and about 5 or 6 other issues where the owners of this project ignored the fact that the user wants to preserve space based on his/her own style requirements (which could just as easily be their team’s requirements) and also ignored that the user isn’t asking to change Prettier fundamentally, but let a feature be configurable, I decided to delete your extension and remove it from my projects.

Code readability is as much an opinionated viewpoint as is the stance that Prettier shouldn’t do this by default, and neither is wrong.

What I don’t understand is the stubborn position that you won’t even consider making an option like this configurable. What sense does that make?

It’s kind of like saying, “It’s our code formatting style or nothing”, which begs the question, “Why bother with Prettier at all?”, if you really just want to enforce a hard-handed approach that your style is the “right way”?

Why not just hard-code your style guide and not allow configuration at all?

It seems that the latest iteration is even removing spaces between certain types of code blocks, like in this Angular example:

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.css']
})   ///////////  I cannot get a space to stay here, unless I add a comment like // to force it
export class CartComponent implements OnInit {
  items: any[];
 //////////////////   I can put a space right here without issue, for some odd reason.
  constructor(
    //  prettier-ignore  I can't enforce this, even though it's an Angular style standard, without using "prettier-ignore" which is actually more code ....
    private cartService: CartService  
  ) {
    this.items = this.cartService.getItems();
  }
///// doesn't seem to be an issue with this space, either, I can remove it, it stays, too.
  ngOnInit() {}
}

It seems spending more time trying to enforce Prettier rules is less helpful that just using the linter standards instead.

@ikatyang I see, it just confirms current behaviour. I don’t remember any cases where I needed to use multiple blank lines, so this behaviour is fine I think. But empty line at the start of the block (function or method or class) make code cleaner if block starts with bulky code, and its important.

FYI, Rationale - Empty lines:

It turns out that empty lines are very hard to automatically generate. The approach that Prettier takes is to preserve empty lines the way they were in the original source code. There are two additional rules:

  • Prettier collapses multiple blank lines into a single blank line.
  • Empty lines at the start and end of blocks (and whole files) are removed. (Files always end with a single newline, though.)

I love prettier but this is the one thing that bothers me in prettier. Not having a blank line between class declaration and first property/constructor. It bothers me every time in all my files. I would love prettier to not remove it if I put one.

What if I just want to use Prettier to add all my semi-colons and manage my quotes? It seems that should be an option.

If you just want that, then you probably want to use ESLint. It’s highly configurable and you can set it up to mostly leave your code alone.

Would really love to see this implemented. It really hurts my eyes when there’s no line break between the class declaration and the first code line inside the class.

My mind keeps reading the first code line as a continuation of the class signature, and I have to consciously stop, traceback, and read again!

VERY PAINFUL!!!

Since we don’t support this style anywhere else, I feel like we shouldn’t enforce a change to it because it would be inconsistent with the rest of the code. IMO the first one is just as readable so I don’t see the need to change this.

This is exactly what I’m referring to in my comment above.

Awesome! So don’t enforce it- allow the option to configure it.

I find a lot of weird places where Prettier refuses to allow a single line break which definitely impacts my ability to read the code - and I’m the one writing it, so at the end of the day it’s my view that matters in that case, and next is whoever reads it next.

I have to doubt anyone doing a code review is going to be thrown for a loop because there’s a single break somewhere.

There should be a rule to simply allow single line breaks between any two closed objects (any ending parens or brackets) or any space you darn well please.

It seems rather than being a tool to enforce the users highly-opinionated style, this is instead becoming a tool to enforce only Prettier’s highly-opinionated style.

Those may be two, very different things and I think ignoring the use case possibilities is kind of missing the whole point of why this tool is useful.

What if I just want to use Prettier to add all my semi-colons and manage my quotes? It seems that should be an option.

This is, of course, just my opinion.

Five years ago @pleerock, in whose symbolic shadow we stand today, opened this issue. But five years later, the whitespace is still is not free. The life of our whitespace is still sadly crippled by the manacles of obliteration and the chains of discrimination. Five years later, the whitespace lives on a lonely island of poverty in the midst of a vast ocean of materially prosperous linting. Five years later the whitespace at the top of our class files still languishes, and finds himself exiled even in his own class.

And so I’ve come here today to dramatize a shameful condition, to remind Prettier authors of the fierce urgency of now. Now is the time to rise from the dark and desolate valley of exceptionism to the sunlit path of spatial justice. Now is the time to make whitespace a reality for all the source’s classes. This sweltering summer of the whitespace’s legitimate discontent will not pass until there is an invigorating autumn of spatiality and equality. 2023 is not an end, but a beginning. We can never be satisfied as long as our classes are stripped of their aesthetic and robbed of their dignity by linting constraints that state: no whitespace allowed. No, no, we are not satisfied, and we will not be satisfied until carriage returns roll down like waters, and newlines like a mighty stream!

We hold these truths to be self-evident, that all whitespace is created equal.

I have a dream that one day atop the class files of source, whitespace and printables will be able to sit down together at the table of brotherhood. I have a dream that we will one day live in a nation where my source files will not be judged by the compulsion of their lint, but by the content of their characters. I have a dream that one day every class file shall be indented, and every pyramid-of-doom flattened.

And when this happens, and when we allow whitespace-freedom to ring, when we let it ring from every file and every code-block, from every project and every repo, we will be able to speed up that day when all the world’s developers, Java and Perl coders, C sharpers and Noders, vi and emacs proponents, will be able to join hands and lint as with one voice: Free as asked. Free as asked. Thank God Almighty, space’s free as asked!

Its July 2022, still not added. What a pain.

prettier is highly adopted nowadays, and it’s a part of big infrastructure that we all use, we can’t simply use some other tool when everybody else use this tool and every IDE already adopted this because of high usage. That’s why we have to use it and annoy about something that we don’t like. There are only two things I hate in prettier - how it cuts my line breaks and how it formats long strings.

Just found this thread after trying out prettier for the first time. I really like prettier overall but reading code without a newline after function, class, and interface definitions is so much harder.

It seems like this issue has been around for a while and I can’t understand why it’s been ignored. Especially when this is their one exception to their rules about respecting whitespace.

Please listen to the vast amount of members in your community and try to find a fix for this

Thanks!

Ladies and gentlemen of the prettier development team,

Today, I stand before you to discuss a matter that may seem mundane at first glance, but I assure you its implications run much deeper than meets the eye. We find ourselves in the realm of software development, where the tiniest details can have a significant impact on the overall codebase. The topic at hand is the stringent practice employed by certain software package publishers, forbidding the use of blank lines after function or class declarations.

Let us draw a parallel for a moment, one that may resonate with your experiences in the world of literature. Imagine for a second that you are reading a captivating novel, one with a gripping storyline and rich characters. As you delve deeper into the narrative, you come across a curious phenomenon – the absence of blank lines between paragraphs. Every word and sentence is crammed together, without any breathing space.

In this literary context, the absence of blank lines would undoubtedly lead to a jarring and overwhelming reading experience. The lack of visual separation between paragraphs would hinder the flow of the story, making it difficult to distinguish one idea from another. The narrative’s essence would be lost, and the reader’s immersion disrupted.

Similarly, in the realm of software development, blank lines serve as vital visual cues that promote readability and clarity in the code. Function and class declarations are the building blocks of any software package, just like paragraphs form the structure of a compelling story. Denying the code these blank lines is akin to forcing the reader to face an intimidating wall of text, obscuring the logical divisions within the codebase.

Without the appropriate separation, developers would struggle to comprehend the code’s organization, leading to confusion and potential errors. Like the disrupted reading experience, the software’s maintainability and future enhancements become compromised. In the pursuit of efficient coding practices, we must not overlook the fundamental principle of code readability – a principle that blank lines after function and class declarations help us achieve.

Therefore, I implore you, esteemed jurors, to consider the importance of this seemingly trivial matter. Just as blank lines between paragraphs guide readers through a seamless literary journey, so do they guide developers through a smooth and comprehensible coding experience. Let us not underestimate the significance of these seemingly simple blank lines in fostering a well-structured and maintainable software package.

As you deliberate on this matter, remember that the devil lies in the details, and the little things can make all the difference. By upholding the significance of blank lines in code, we uphold the very essence of efficient and clear software development practices.

Thank you for your attention.

Is there a way to configure prettier to only remove multiple blank lines? I sometimes like have a blank line for spacing between functions, or immediately after a class definition (inside the resulting block).

If blanket, generalizable rules are what’s needed, then perhaps a configuration that will only collapse multiple adjacent new lines down to 1 new line could suite people with this preference

What the hell is going on? You can downvote my comment but people, you do project for community, so do the option comunity asks, simple adjustable option. Every man in this thread gave you well-reasoned arguments. The blanket of pure code without line breaks is bad option for many people. You can read such code then read it, but don’t force your point to others. I don’t like big words, but historically no one community tolerates such an attitude. If you don’t care your community (whoever they are: clients or like-minded people) needs - ok. You’ll lose this part of community.

Agree with @Dafeesh, the only thing stopping me from using prettier is this missing feature.

Has this seriously not been implemented yet…? This forced rule is insanely annoying and is making me regret switching to Prettier. All I want is an option to allow a blank line at start/end of blocks…

Not gonna lie… I saw that v2 was released and got super excited that they’d fixed this. It’s the last thing preventing me from using prettier everywhere.

Also currently when I have a function like this:

export class ReferencableToUID extends PremiereProElement
	implements Referencable {
	public getReferencedObject(xml: Document, type?: string) {
		const uRef = this.element.getAttribute('ObjectURef');
		let found = xml.querySelector(getQueryWithURef(uRef, type));
		if (!found) { // ...

I’d prefer to instead of adding a blank linke after a declaration like this:

export class ReferencableToUID extends PremiereProElement
	implements Referencable {
	
        public getReferencedObject(xml: Document, type?: string) {
		const uRef = this.element.getAttribute('ObjectURef');
		let found = xml.querySelector(getQueryWithURef(uRef, type));
		if (!found) { // ...

to instead do this:

export class ReferencableToUID extends PremiereProElement
	implements Referencable 
{
	public getReferencedObject(xml: Document, type?: string) {
		const uRef = this.element.getAttribute('ObjectURef');
		let found = xml.querySelector(getQueryWithURef(uRef, type));
		if (!found) { // ...

While admittedly still the second one is a lot more readable than the first!

Where did the opinion come from that there should never be a line break after a signature? Obviously, Prettier thinks single line breaks are good UNLESS its after a signature. Those line breaks are deviants and must be hunted down. Eradicated.

I love your position that Prettier is highly opinionated and therefore will not be adding more configuration options. I agree that a lot of options defeats the purpose of Prettier. However this one perplexes me to no end. Far more than had you forced everyone to use either tabs or spaces.

Not asking for a configuration option. Am asking that you guys consider enforcing a line break so the code is less Uglier and more Prettier

Just a reminder that it’s approaching late 2021, Prettier has released a new major version, and yet they still think this is readable:

export default class MyVeryLongClassA extends MyVeryLongClassB
  implements MyVeryLongClassC {
  constructor() {
    console.log('e');
  }
}

From the docs:

The approach that Prettier takes is to preserve empty lines the way they were in the original source code

vs.

Empty lines at the start and end of blocks (and whole files) are removed

Having opinions is arguably a good thing, but if you’re going to have strong opinions they need to be consistent. Might be harsh, but so is Prettier 😃

after going back and forth multiple times i ended up doing below… added a ‘//’ which tends to be grayed out depending on vscode theme and seems i can bear it for now.

love prettier but love my new lines too 😃

note: code copied in-part from top of post


export class SlackPeopleSync {
  //
  setting: Setting
  loader: SlackLoader

  constructor(setting: Setting) {
    this.setting = setting
    this.loader = new SlackLoader(this.setting)
  }
}

Does it cost to create a configuration and make many here happy?

This is the only thing that keeps me away from using prettier for my projects.

FYI I raised https://github.com/brodybits/prettier/pull/200 to show how we can respect the leading line break in each class body, as discussed in some of the comments above. (All tests pass in my work area.) I am raising this on my own prettier fork (not the one that I publish) pending interest from the Prettier team. I do hope that the Prettier team would be open to considering this in the future.

Not implemented yet ?

Yay, as @pleerock showed in their comment, adding a blank line after method declarations makes the code much more readable. A pity Prettier won’t adopt this rule cause the work you’re doing is great.

I’ll search for a configurable, not that highly opinionated, alternative that allows me to do so.

Since v2 is now released, would it maybe be possible to add this as an option? It’s kind of “the last missing thing” for me 🤓

Yes exactly, sometimes I think a blank line after a function defintion can improve legibility (ie. the first line of a block statement)

On Saturday, Aug 24, 2019 at 13:03, Hawken Rives <notifications@github.com (mailto:notifications@github.com)> wrote:

@ErikAGriffin (https://github.com/ErikAGriffin) Could you post an example of what you’d like? Prettier already collapses multiple blank lines to a single blank line. I’ve never had it completely remove the empty lines from my projects.

Except, I suppose, at the extreme start / end of a block (function, class, etc). Is that where you’re asking about?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub (https://github.com/prettier/prettier/issues/4870?email_source=notifications&email_token=ACPAZW3PTTMM7QGYYUITAKDQGGAWTA5CNFSM4FLHVWS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5CFXJY#issuecomment-524573607), or mute the thread (https://github.com/notifications/unsubscribe-auth/ACPAZW5FJ5UWDFQX3YH3LQ3QGGAWTANCNFSM4FLHVWSQ).

I too would be using prettier right now, but unfortunately was unable to recover from the visual assault at the start of each class.

This is a dealbreaker for me as well. Clearly more readable, as proved @pleerock

Thankfully I could deactivate prettier in my eslinc config (I’m using @react-native-community extension)

module.exports = {
  // ...
  extends: '@react-native-community',
  rules: {
    'prettier/prettier': 0,
  },
 // ...
};

credits: https://github.com/facebook/react-native/issues/25840#issuecomment-515561594

I don’t disagree but please let’s not have this thread become about overrides because the maintainers will likely ignore it if it does.

Also this thread is not about that.

It is about addressing the “elephant in the room”, which is the one exception to their rules about respecting whitespace.

The fact that prettier has this rule at all is just stupid, IMO.

Plus 1 for this feature. Here’s what my React components look like while using Prettier.

image

Here’s what they look like with a line break.

image

Any alternative to Prettier?

@SalahAdDin It depends on what you mean exactly by “alternative.” Sure, there are some alternatives, and I have tried some of them. I didn’t find any that let me configure what I want. However, I’d like to highlight dprint (https://dprint.dev/). It is not as opinionated as Prettier, and its AST-node-specific configuration is awesome (see https://dprint.dev/plugins/typescript/config/). Deno uses it under the hood for deno fmt (and switched from Prettier), and the TypeScript team uses it for formatting their code base (switched from formatting by ESLint). It has the same problem as stated in this issue, but it is the closest match to my needs. Just as a reference, my current config:

{
	"typescript": {
		"useTabs": true,
		"semiColons": "asi",
		"quoteStyle": "preferSingle",
		"quoteProps": "asNeeded",
		"bracePosition": "sameLine",
		"binaryExpression.linePerExpression": true,
		"conditionalType.preferSingleLine": true,
		"exportDeclaration.trailingCommas": "always",
		"importDeclaration.trailingCommas": "always",
		"arrowFunction.useParentheses": "preferNone",
		"exportDeclaration.forceMultiLine": true,
		"importDeclaration.forceMultiLine": true
	},
	"json": {
		"useTabs": true,
		"trailingCommas": "never"
	},
	"excludes": [
		"**/node_modules",
		"**/dist",
		"**/build",
		"**/coverage",
		"**/.ultra.cache.json",
		"**/*-lock.json",
		".vscode"
	],
	"plugins": [
		"https://plugins.dprint.dev/typescript-0.88.7.wasm",
		"https://plugins.dprint.dev/json-0.19.1.wasm"
	]
}

Now, I am working on a codebase where the previous team developed an ESLint rule to do exactly what is requested in this issue. Unfortunately, I do not have permission to share it.

I would actually favor another solution I gave in https://github.com/prettier/prettier/issues/10018#issuecomment-762611991:

I would actually favor applying “solution 2” (opening brace on its own line) for all ES classes, regardless of extends/implements/etc., which should improve readability in some other cases. For example:

class SimpleClass
{
  method1() {}
  method2() {}

  method3() {}
}

class HigherLevelClassWithLongNameAndExtendedFunctionality
  extends SuperMajorBaseClassWithHeavyFunctionality
  implements SuperLargeGenericInterface
{
  method1() {}
  method2() {}

  method3() {}
}

https://www.npmjs.com/package/@yikes2000/prettier-plugin-merge-preserve

Here’s my stab at the problem. It will preserve first blank line after open curly brace, bracket, and parenthesis. Additionally, double forward slash at the end of a line will preserve that line as a whole (including multi-line expression).

Enjoy!

I am new in TS world and this topic seems really interesting about a big detail.

From my experience in C#, PHP with Object-Oriented Programming, I always use the break line just after the declaration of a class and all its interface, parent etc, so classically :

export class MyClass implements AnInterface
{
  property: TypedClass

  constructor(setting: Setting) {
    this.setting = setting
  }
}

So it’s frustrating to me without that break line, and I think that’s also why it’s confusing in another way… our brains seem to be terribly suffering on pretty much without an empty line, or a blank breaking space, which world…

EDIT : it is call “the Allman style” : https://en.wikipedia.org/wiki/Indentation_style#Allman_style

“Pretty” annoying Did a regex replace on all my files to add a // after each class declaration

replace class(.|\n)*?\{\n with $0 //\n

Ok I understand. So, you are not against the idea but for technical reasons, it can’t be done right now. Hope it can be done some day 😃 Thanks for taking the time to explain. By the way, I think prettier philosophy is a good thing (well explained in the link you provided).

@Yikes2000 Fix #7884 also and you’ll make a lot of people happy!

After many years of not using Prettier because of the pain associated with it, I came back to see if something has changed. It seems not. Developers still hold the opinion that their decisions are correct and everyone else is wrong. Well, this is why Prettier is called opinionated. Not because it reflects the voice of its community.

I am not advocating for a configuration option. That would be way too much, way too far from becoming a reality. I am asking for just not touching the empty line if it’s there. I would love it if Prettier wouldn’t remove ANY of the empty lines except the redundant ones.

Any alternative to Prettier?

After many years of not using Prettier because of the pain associated with it, I came back to see if something has changed. It seems not. Developers still hold the opinion that their decisions are correct and everyone else is wrong. Well, this is why Prettier is called opinionated. Not because it reflects the voice of its community.

I am not advocating for a configuration option. That would be way too much, way too far from becoming a reality. I am asking for just not touching the empty line if it’s there. I would love it if Prettier wouldn’t remove ANY of the empty lines except the redundant ones.

Yes, I do think even if you are supposedly opinionated formatter, you can still give people option to override your opinionated defaults, I don’t really believe that having more options is confusing for people. Most people can ignore most of the options like we do in most of the libraries/functions/apis etc. and when they face an issue like this, they can search and use option that is useful for them. It isn’t necessarily an overload but more of a use it if you need it thing.

My comment has been marked “off-topic”. I must admit I don’t understand. Can someone explain why my comment is off-topic please?