-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Add option to omit semicolons in output #12
Comments
@jlongster If you are both accepting PRs and want this feature, I would be more than happy to help with a PR for this one. |
I'm open to it, but it gets problematic fast. When you don't use semicolons, you run into things like this where you are forced to put a semicolon: var x = 5
;[1, 2, 3].forEach(...) The first time this would be parsed correctly, but we would output: var x = 5
[1, 2, 3].forEach(...) which is invalid JS. (at least, not what you want.) This means that in order to support semicolon-less JS we need to code in all the ASI rules so we can see where semicolons are important. I'm not sure I'm willing to take on that complexity just yet. Feel free to play around with it. Code is powerful and you might convince me. My preference for evolving projects is to take it slowly though, and it's hard to remove things later than to add them, so let's play with it over time and see what we can do. I'd like to keep the number of options low, but this is such a divisive issue that it could be worthwhile. |
Have two suggestions:
|
I use standard.js, which is a popular no-configuration style guide & linter. They insist on a semicolon-free style, and the only rule needed to make this work is to never start a line with I would love to see standard.js and prettier be compatible one day. |
I would love seeing this integrated - is currently the only show stopper for me. // Edit: Standard Packe had 200k+ Downloads last Month - i think it's something that matters for a lot of people in the JS Community |
It's worth mentioning that "the only rule needed to make this work" will get progressively more complex as the language evolves. For example, under the popular public fields proposals these two classes differ: class A {
set
foo(x){} // setter for 'foo'
}
class B {
set; // uninitialized field named 'set'
foo(x){} // method named 'foo'
} (Note that babylon currently gets these edge cases wrong in a number of exciting ways.) Presumably a no-semi style would have you writing class B {
set
;foo(x){}
} So, keep in mind that the complexity cost comes not just now but also in the future. (I don't think this is well understood by people using this style.) |
Huh. I found cool thing. Because I'm moving to Atom and just using ESLint instead of Standard, i just love the combo of Linter, Linter-ESLint + eslintrc, and atom prettier :D It is just a whole show, because I had There has a bit of delay between them and it can be seen what does what. Cool. I'm moving back to semicolons because the AtomLinter. edit: So in short. I also wanted that option, but it seems AtomLinter comes to the rescue and can be easily fixed if you use ESLint, not some "standards" or "semistandards" :) |
Just have a simple question. var x = "thing"
[1].forEach(...) how do you know the person wanted to write var x = "thing";
[1].forEach(...); and not var x = "thing"[1].forEach(...) My point is "how do we know?" because if we know, we can add or prepend a semicolon, so same thing right? |
I tried piping the result of // Before
var x = 5;
[1,2,3].forEach(console.log);
// After
var x = 5;
[ 1, 2, 3 ].forEach(console.log) // Before
var x = "thing"
[1].forEach(console.log)
// After
var x = 'thing'[1].forEach(console.log) If the user doesn’t include a semicolon in front, these two lines gets squashed into the same line, clearing any ambiguity. |
@MoOx There is only one way that your example will be parsed (so one canonical AST), and only two ways that prettier should output it: with semi:
without semi:
The rule is simply: remove semi at end of line, and insert semi at beginning of line, before array literal, parens block, or template string. |
I know that. My idea is "what if people write this by mistake". I guess the response is "pebkac". |
@bakkot Yes, indeed, in this case the semicolon injection needs to happen after the keywords |
Seems as simple as looking that there's a linebreak/whitespace there and assuming they intended to have those two tokens be separate. Basically: "thing" [1] // implicit semicolon
"thing"
[1] // implicit semicolon
"thing"[1] // no implicit semicolon |
However, that goes against the rules of JavaScript. A JavaScript engine will parse it as
The no-unexpected-multiline ESLint rule will warn people about this 😃. P.S. I think the implications of using a semicolon-free style has already been well studied and there are already linter rules to avoid making mistakes in both styles. I would suggest to focus the discussion more on the complexity incurred and implementation effort required. |
@wmertens Not just 'get' and 'set' but also 'static' - but not 'async'. Off the top of my head, there's also class A {
a = 0; // initialized class field
*b(){} // generator method
}
class B {
a = 0
*b(){} // SyntaxError
} And that's just with this one proposal. It's hard to predict how much more complex it'll be in the future. That's kind of my point: adding this option will add an unknown (but certainly nonzero) amount of future complexity. |
Why not just leave semicolons alone, rather than adding or removing? |
@TehShrike Because this tool doesn’t care about the existing formatting of the code.
It’s more complex to program the pretty-printer not to output a semicolon, than to make it always output one. |
Yes, and this is what I meant by "we'll have to start embedding ASI-style rules into the printer". |
Any chance we could start small with what @TehShrike suggested?
As an option. So: Actually, this would be enough for me, as |
@dtinth but semicolons are code, too. I would expect them to be represented in the AST. |
The AST has no notion of "semicolons" at all. And this formatter works by printing the AST, with a few exceptions where we look at the original text. Those few exceptions are very easy cases, while checking for semicolons would be far harder.
It'd require a ton of special-casing and isn't really trivial. This formatter discourages giving the programmer control because the goal is complete consistency. The one exception is blank lines -- we will keep blank lines because that's such an important part of the code (but we will still collapse multiple blank lines into a single one). |
If you don't want semicolons, use I think a fork is actually a viable option and helps relieve the tension between the different styles. I'm happy to work on whatever tooling/process is needed to help maintain a fork if people really want that style. Lastly, we can also make it easy to integrate
Although if you're really after just ditching semicolons, you probably just want If someone wants to explore a no-semicolons version of this, I'd love to see it. I'm happy to advocate a forked version of this that has that, or a post-processing step, or something like that. |
Since we won't be actively working on this, I'm closing this issue. But whoever reads this please know: the next step is to implement it yourself and show me the code. We can see how much complexity it adds and talk about if a fork is the right option or not. |
Here’s my take for It basically takes the output from An Atom package is available. |
@tunnckoCore, thanks for the tip! I'd added it to my
Because this: So instead, I can disable The other underlying idea behind something like
If you don't want to use it, be my guest 😄 |
Hm. I'm new to Atom. Yea I did notice that flash and it wasn't cool, and kinda feel slower that it should. I did follow the linked issue. So yea, maybe make sense and I'll try your plugin. In anyway, that specific gif seems more like a |
I'm pretty sure that Note again that the plugin's got some issues that need PRs :) |
Yea, yea, I'm agree. |
(We don't disallow comments on the same line, inline comments are just plain buggy right now) |
Has anyone here already made a fork with a configuration option to remove semicolons? If anyone did it or will do it, I'll try to merge it in my fork. Or if someone sends a PR, even better! 😃 |
Omg. "with tabs". I can't understand why complexing the tools (not talking only specifically for prettier) when there always are workarounds with other tools and existing workflow? But yea, our different styles in that community kills us. |
For a few reasons:
I know I can't change what the majority of the community uses, but I cannot and will not adapt into it simply because it is what the majority uses, but only if someone manages to convince me it is a technically better option. |
I'm pasting the link to my package I've created specifically to fix this issue, as this thread is the first on google when you search for "prettier semicolons": https://github.com/sheerun/prettier-standard I hope prettier will support no-semi rule soon enough, though! |
For anyone finding this via Google, note that prettier supports this option now, per this PR: |
eslint.autoFixOnSave is a great option to autofix your code |
@vjeux Should this be unlocked? The option has been added. |
This has been added in #1129. |
E.g.
semicolons: true
to use semicolons at the end of statements (default), andsemicolons: false
to not use semicolons.The text was updated successfully, but these errors were encountered: