
A Prettier JavaScript Formatter - danabramov
http://jlongster.com/A-Prettier-Formatter
======
harpocrates
I really have to back up the recommendation for Wadler's "prettier printer"
paper. I'm working on a Haskell parser and pretty-printer for Rust and I had
pretty much given up on ever finding a lightweight pretty printer that would
be able to choose whether to put something on one line or to split it up into
multiple lines all by itself. For anyone needing this in Haskell, I strongly
urge you to consider the modern rewrite of the initial library [1].

[1] [https://hackage.haskell.org/package/wl-pprint-
annotated](https://hackage.haskell.org/package/wl-pprint-annotated)

~~~
bjz_
Yeah, I can second that recommendation on reading the paper [0]. It's one of
the nicest I've read. There is also a Rust crate for it[1] - though it's not
as... 'pretty'... as the Haskell EDSL, obviously.

[0]:
[http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettie...](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)

[1]: [https://crates.io/crates/pretty](https://crates.io/crates/pretty)

------
sharpercoder
> If computers are good at anything, they are good at parsing code and
> analyzing it. So I set out to make this work, and prettier was born. I
> didn't want to start from scratch, so it's a fork of recast's printer with
> the internals rewritten to use Wadler's algorithm from "A prettier printer".

Bob Nystrom (munificent) disagrees[0] after writing one himself:

> The search space we have to cover is exponentially large, and even ranking
> different solutions is a subtle problem.

[0]: [http://journal.stuffwithstuff.com/2015/09/08/the-hardest-
pro...](http://journal.stuffwithstuff.com/2015/09/08/the-hardest-program-ive-
ever-written/)

~~~
munificent
I will note that one _could_ design a pretty printer that reliably had better
performance if the formatting style they chose was simpler and more amenable
to it.

My (mostly self-imposed) task was more difficult because I was trying to
follow the existing style that humans were hand-applying to their Dart code,
and that had a lot of tricky non-local cases that look nice but are hard to
automate.

~~~
korm
I have to say Dartfmt is one of my favorite things about using Dart. It works
amazingly well and the fact that it's not configurable is a great decision
[0]. I'm never afraid to peek into unfamiliar code because of that. So thank
you.

[0] [https://github.com/dart-lang/dart_style/wiki/FAQ#why-
cant-i-...](https://github.com/dart-lang/dart_style/wiki/FAQ#why-cant-i-
configure-it)

~~~
munificent
You're welcome! That means a lot to me. I tried really really hard to make it
produce output I and others would like.

> I'm never afraid to peek into unfamiliar code because of that.

This is _exactly_ why dartfmt exists. It's not about making _your_ code more
readable to you, it's about making _strangers '_ code more readable, because
that lowers the bar to contribution between people in the ecosystem.

------
K0nserv
This looks really nice. One of my favourite things about Golang is the use of
gofmt and the resulting consistency of all Go programs. The idea of parsing
the code to AST representation and then printing it back as source is
brilliant, all though it can mess stuff up like the chaining of `.then` as
mentioned in the post.

~~~
pcwalton
gofmt doesn't solve the hard problem that this blog post (and Wadler's paper)
is about. From the article: "There's an extremely important piece missing from
existing styling tools: the maximum line length."

gofmt's decision to not bother to require a line length may work somewhat for
Go (which tends to encourage short lines by virtue of lacking expressiveness),
but it doesn't work for lots of other languages, including JavaScript.

~~~
Strom
The fact that gofmt doesn't enforce some arbitrary line length is a blessing.
I have a modern widescreen monitor and I use a maximized window text editor. I
have no problem with 200 char length lines. I'm more easily annoyed by 80 (or
60, like in this case) char limits, as if I was viewing this code on punch
cards.

~~~
pcwalton
> The fact that gofmt doesn't enforce some arbitrary line length is a
> blessing.

You don't have an infinitely long screen. You have some line length limit.

~~~
flukus
It's infinitely scrollable though. Scrolling horizontally sometimes isn't a
bad fallback.

~~~
pcwalton
Scrolling horizontally interrupts flow like nothing else!

99% of all software projects have a de facto or de jure line length limit for
a reason.

------
russellbeattie
My team recently ganged up on me to tell me my line spacing was f*cked. Upon
reflection, it seems that as I'm writing code I group lines into 'working well
- one line, 'not sure - two lines', 'probably will change - lots of space',
'hey look at me! - off by itself'. Apparently, this unconcious invisible
system drives others crazy. Developers are so picky! ;-)

We've actually got a bunch of automatic eslint rules, but it doesn't correct
for this. Looking at the various beautifiers, I couldn't find anything that
really cleaned up line spacing very well, and ended up running a bunch of sed
commands to remove lines and then spacing out things manually in a "sane" way
(so picky!!). Having a formatter that actually parsed the AST and rewrote the
code like gofmt will be very handy if it works - I'll have to try it out.

~~~
toefraz
There's a eslint rule for multiple blank lines

~~~
jbergens
That one actually crashes in my atom installation. I get a warning that it
cannot show me where the multiple empty lines are.

------
Dangeranger
After using Elm and the elm-format package in Emacs for the last few weeks I
can say that not having to format the source and just letting your editor do
it for you on save or via a command is so very nice.

This is a trend that I feel is going to catch on across any language that can
support it. It makes trivial decisions and arguments about formatting a thing
of the past.

~~~
overcast
It's almost crazy to think this already isn't just a thing. Why is this just
coming to a head now, after all these years of carrying on over code
formatting?

~~~
mrgoldenbrown
I'm not convinced it is just coming to a head now. I've seen automatic/forced
formatting on projects at least as far back as 2000, when I entered the
workforce.

~~~
djeikyb
The ones I've used for java have been consistently bad though. Autoformat as a
commit hook leads to ugly code. Granted, I mean "bad" as in "gets ya 75% of
the way".

------
amenghra
[https://github.com/facebook/pfff](https://github.com/facebook/pfff) is a tool
which support pretty printing a bunch of different languages (currently c,
c++, java, js, php, python, rust, and a bunch more).

The idea is to have a common AST (with parsers for each language) which keeps
track of whitespace/comments/etc and then share a ton of logic by writing
writing code at the AST layer.

You can use pfff to pretty print according to your style needs. Also supports
a bunch of other neat things such as search/replace.

~~~
bastih
I've looked at pfff and couldn't really figure out what's supposed to work and
what isn't. Would love to pretty print python with it. (I've been looking at
the many different pretty printers in the python world and haven't found
anything that I feel works well enough). Did you use it for pretty printing
python?

------
artursapek
This has been the single biggest missing tool in the JS ecosystem. I never
even realized until I experienced the magic of gofmt. It should honestly be a
standard tool for new languages going forward. Kudos to the creator. I'll try
it out later today - hopefully it works well for us.

------
balajics
How is it different from jsbeautifier[1] other than enforcing its own style
rules? [1] [https://github.com/beautify-web/js-
beautify](https://github.com/beautify-web/js-beautify)

~~~
Noseshine
Looking at both github repos, _jsbeautifier_ looks more complicated (as a
project), and I don't think it uses the AST or at least I did not see anything
that looked like it would create one. Looking at some of the code I saw
`string.replace(...)` so it seems to be string-manipulation. It also is for
HTML and CSS too it seems, while the project discussed here is just JS, so
more targeted, and the approach to go through the AST seems intriguing to me.

PS: This seems to be the code for the JS beautifier in _jsbeautifier_ :
[https://github.com/beautify-web/js-
beautify/blob/master/js/l...](https://github.com/beautify-web/js-
beautify/blob/master/js/lib/beautify.js)

------
BrandonM
If I personally prefer the second Promise chain:

    
    
        myPromise.then(() => {
          // ...
        }).then(() => {
          // ...
        }).catch(() => {
          // ..
        });
    

and if I also prefer the Lisp-like approach and hate putting:

    
    
        );
    

on its own line, am I part of the problem? What if my whole team uses that
style? For example, we would write:

    
    
        foo(
          reallyLongArg(),
          omgSoManyParameters(),
          IShouldRefactorThis(),
          isThereSeriouslyAnotherOne()
        );
    

as:

    
    
        foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(),
                isThereSeriouslyAnotherOne());
    

(100 characters wide, double indent on the continuation line. This is pretty
standard for Java formatting.)

Stated differently, is this meant to be very opinionated in hopes that all JS
would follow a uniform style? I think that can work for Go since it was like
that from Day 1. For JS, though, it has been out for so long that many teams
have developed their own preferred style. I suspect that most of them would
avoid an opinionated formatter that differs in a few small ways from their in-
house format, if only because it seems silly to break diffs and git blame for
a sweeping formatting change.

~~~
joshwcomeau
I think that this is definitely not a tool for everybody, and I think that's
alright.

Dan Abramov said it best, when he opened an issue urging to resist the urge to
add configuration:
[https://github.com/jlongster/prettier/issues/40](https://github.com/jlongster/prettier/issues/40)

Configuration has a cost, and the product will be better and more reliable if
it's limited. As it stands right now, the configuration isn't ideal for my
preferences, but I'm fine with that; either I'll

* use the tool and adopt new patterns (ones which, frankly, have very little impact on anything), * keep doing this stuff manually (it's gotten me this far!) * fork the project, and bear the cost of maintaining the updated configuration myself.

~~~
gsylvie
I find if I hate a formatting pattern that I'm forced to use, after a while I
prefer it and hate all others.

------
hackcrafter
I appreciate the emacs bindings [0]!

Between this and eslint+flycheck I will feel less envious of Visual Studio
Code's editor environment (if only there were a way to leverage some of its
fantastic IntelliSense from emacs...)

[0]
[https://github.com/jlongster/prettier/tree/master/editors/em...](https://github.com/jlongster/prettier/tree/master/editors/emacs)

~~~
Derander
If you're using typescript and emacs,
[https://github.com/ananthakumaran/tide](https://github.com/ananthakumaran/tide)
is a very good integration with the built-in language server for semantic
auto-completion and "jump-to" support. I use it every day on large projects.

I think that vscode uses the typescript language server behind-the-scenes for
plain javascript analysis.

------
SomeCallMeTim
Flow is cool, but TypeScript has way more traction. Would jump on this in an
instant if it had TypeScript support and a VS Code plugin.

~~~
chc
Typescript is another language. It kind of goes without saying that people
using a different language be more likely to use something if it were in the
language they use, doesn't it?

~~~
Touche
I mean, by any reasonable definitely of a language, Flow is another language
too.

------
IvanVergiliev
Eventually we should just store the AST in source control. Prevents
inconsistencies when style changes and/or 50k lines diffs to change the
indentation level.

~~~
chriswarbo
I certainly think that language definitions should include a standard parsed
format in addition to their human-friendly syntax. This can just be an
s-expression representation of the normal, concrete syntax, without any
transformations applied. This way, we don't have to build language-specific
rules for precedence, offside/significant-whitespace, fixity, etc. into every
tool for that language.

Implementations (compilers and interpreters) should include tools/modes for
converting between these two representations, and should support running
programs written in the parsed format in addition to those written in the
human-friendly syntax. This isn't asking much: the difficult part is parsing
the human-friendly syntax, which implementations must already do.

The benefit is that we don't end up with a mismatch between what the
compilers/interpreters accept, and what the other tooling accepts (linters,
formatters, doc generators, static analysers, search engines, syntax
highlighters, use-finders, go-to-definition, refactoring tools, etc.). This
_would_ , incidentally, allow people to read and write code as s-expressions,
but that's not the point; it's just about representing concrete syntax as
closely as possible (plus arbitrary annotations, e.g. for line numbers, etc.),
whilst exposing the structure in a machine-friendly way.

This would also make it much easier to make new tools, extend existing ones,
and improve practices, e.g. like syntax-aware diffing, standard code
formatting (i.e. tools like this one), version-control-friendly
representations, tree-based editors, more powerful navigation in editors and
IDEs, etc.

------
esbenp
I made a VS Code plugin for Prettier

[https://github.com/esbenp/prettier-
vscode](https://github.com/esbenp/prettier-vscode)

It is my first VS code extension so have no idea if it is correct way.
Feedback is welcome.

~~~
Paperweight
Cool! Don't worry about it being "correct" or not. :)

------
rhengles
Much better than "Standard JS" and its choice of no semicolons. I know about
"Semi Standard JS", but I refuse to accept such a little difference that could
be a configuration has to live in a entirely new project.

~~~
kasbah
But the linked formatter doesn't seem to have an option for no semicolons so I
wouldn't call it better in that regard.

EDIT: Looks like they may be open to it though.
[https://github.com/jlongster/prettier/issues/12](https://github.com/jlongster/prettier/issues/12)

~~~
russellbeattie
Semicolons are not optional in JavaScript: ASI ([http://www.ecma-
international.org/ecma-262/6.0/#sec-automati...](http://www.ecma-
international.org/ecma-262/6.0/#sec-automatic-semicolon-insertion)) is an
error correction scheme for novice programmers. The spec's parsing rules calls
out the statements following where a semicolon should be "offending tokens".
There is no leeway here for style or preference.

~~~
kasbah
The thing is, they made the "error correction scheme" work so well that they
are no longer required. Give it a go sometime; you might like it.

------
gravypod
" _There 's an extremely important piece missing from existing styling tools:
the maximum line length. Sure, you can tell eslint to warn you when you have a
line that's too long, but that's an after-thought (eslint never knows how to
fix it). The maximum line length is a critical piece the formatter needs for
laying out and wrapping code._"

I'd disagree. See [https://www.youtube.com/watch?v=wf-
BqAjZb8M](https://www.youtube.com/watch?v=wf-BqAjZb8M)

------
rhengles
How does this handle tabs vs spaces? I looked the post, the repo and the
issues page and I didn't find anything. I'm specially concerned about not
seeing this in the options of the API, since there are strong opinions on both
sides.

~~~
jlongster
It always prints spaces and you can configure the number of spaces with
`--tab-width`.

For tabs/spaces and semicolons I'm considering if we should support those
options. We need to figure out the goal of the project: is it to converge on
generally a single format, or is it to provide formatting options for a few
large groups of people that have different opinions. There are issues on the
project discussing this right now.

~~~
chriswarbo
Whilst it's easy to flame about tabs vs spaces and other bike-sheddy issues
online, I wonder how much people _really_ care about it? After all, many
people just get on with life when it comes to non-optional syntax, e.g. whilst
many people flame about Python's use of significant whitespace, I doubt that's
been a major reason for many people to actually use a different language, or
some semicolon-and-braces-to-indentation preprocessor.

Perhaps stick to just one, as seems to be the case right now (whichever it
is), and mention in the documentation that those wanting the other option are
free to e.g. write a patch/fork on GitHub/postprocessor/etc., with the
understanding that such support will eventually get merged in iff it's
actively maintained for some amount of time, its author/maintainer is active
in general development and maintenance for the project, and there's
significant community adoption of such a patch.

Whilst not perfect, this sort of approach might better determine who
_actually_ cares enough about this to offset the community-splitting effects
of allowing both; compared to a general accumulation of online grumbling.

------
geuis
Fantastic. One thing I've learned that's incredibly important is code style
has to be uniform across all engineers. Seems like an unimportant point to
devs that haven't worked with teams that enforce it, but it really is.

As was once told to me, my code should look like your code and yours like
mine.

~~~
kansface
> One thing I've learned that's incredibly important is code style has to be
> uniform across all engineers.

Honestly, why does this matter at all?

~~~
pitaj
So people can easily read each other's code.

------
pritambarhate
I have used ESFormatter
([https://github.com/millermedeiros/esformatter](https://github.com/millermedeiros/esformatter))
with decent amount of success. Does anybody know how Prettier compares to
ESFormatter?

~~~
jlongster
esformatter suffers from the same problems as eslint as described in the post.
It doesn't take maximum line width into account, which is a critical piece for
laying out code.

------
evmar
How does this compare to clang-format, which also formats JavaScript and also
(to use one of the features highlighted in the article) obeys line length?

~~~
jlongster
Not sure, didn't know it formatted JavaScript! This is written in JS at least
so if anything it's more approachable to the community.

~~~
evmar
Yes, that's a good point. If you ever get a chance to compare to clang-format
I'd be interested to read your results. My vague understanding is that clang-
format has some sophisticated-ish algorithms for intelligently wrapping
complex expressions. However, I also think its output is inferior on code like
your .then() chain example.

------
tomp
Nice attempt, but currently wrong. For example, it pretty-formats this code:

    
    
      function makeComponent() {
        return /*test*/ { a: 1
        };
      }
    

into

    
    
      function makeComponent() {
        return /*test*/
        { a: 1 };
      }
    

From my own experience writing a formatter, comments are very difficult (if
one wants to preserve them). I guess the author should reparse the generated
code to ensure the AST hasn't changed.

~~~
jlongster
We do. The entire Flow test suite passes when pretty-printing and re-parsing
and comparing ASTs.

There are a very few subtle bugs like the one you mentioned above. As noted in
the readme, this is a beta. It's certainly more than an attempt.

~~~
artursapek
Don't let HN negativity get you down. This is an awesome project and I'll
contribute bug fixes/test cases if we end up adopting it on our team (very
likely based on your blog post).

~~~
mi_lk
the parent gave an ill example and suggest a solution, how's that a
negativity?

~~~
dangoor
I believe it was the "Nice attempt, but currently wrong." at the start of the
comment. "Nice attempt" could imply that this should be thrown out in favor of
another attempt to solve the problem.

~~~
n42
The entire comment was patronizing. "Nice attempt" minimizes the effort
involved and implies the author is a novice. "but currently wrong" categorizes
the entire project as a failure because of a single bug. The followup "From my
own experience writing a formatter" really drives the whole thing home.

~~~
tomp
Wasn't meant that way.

~~~
softawre
"Nice attempt" used to actually mean the words it said. You know, like "nice
job".

------
hanniabu
It seems a pretty format can be subjective depending on personal preference
and code complexity. I'm surprised that there aren't and formatted that are
customizable in that you break down the format of a function into a few
sections and give the user options on how they would best prefer the format to
look. (At least there's not a formatter like that which I'm aware of)

------
Bahamut
This is awesome - this reminds me of Google's clang-format which they use to
format Angular automatically, but sounds like it's less sucky. The idea behind
it is that developers tend to be opinionated about code style, so having a
tool do it for you eliminates those arguments, which can be a hold up for PRs
getting merged into a codebase.

------
nailer
This is awesome, but one request: can you please extend it into a _real_ (ie,
AST based) diffing tool? Current diffing tools all compare the text (which is
basically an input format) rather than the AST, and hence end up focusing on
formatting rather than actual changes.

~~~
estebank
You could hack a diffing tool that reformats both the before and after and
shows the diff of the generated text.

This would _not_ catch changes like

    
    
        --val  x =  [1]
        ++var x = [
        ++  1,
        ++];
    

as expected, while it would give you a slightly more verbose diff if the
change was

    
    
        --val x = [short(), short()];
        ++val x = [
        ++  a_really_long_name_that_pushes_the_line_length(),
        ++  a_really_long_name_that_pushes_the_line_length(),
        ++];

------
overcast
Oh man, this really needs a vscode plugin, or sublime!

------
amelius
Is there a way to format code before committing it to git, without affecting
the working tree?

------
funkaster
> Many of you know that I usually don't use JSX when writing React code. Over
> a month ago I wanted to try it out, and I realized one of the things holding
> me back was poor JSX support in Emacs.

huh? I've been using emacs with WebMode + tide + FlyCheck and it supports jsx
just fine. Moreover, tide[1] provides great support for plain javascript (I've
used it extensively on a ES6 codebase with great results).

[1]:
[https://github.com/ananthakumaran/tide](https://github.com/ananthakumaran/tide)

------
ludwigvan
For emacs, recently released rjsx-mode solves the JSX problems.

See [https://github.com/felipeochoa/rjsx-
mode](https://github.com/felipeochoa/rjsx-mode)

------
berryg
I enjoy something similar for Elm code called Elm Format.
[https://github.com/avh4/elm-format](https://github.com/avh4/elm-format)

------
devwastaken
I was actually just looking for something like this the other day because I'm
forced to use actual JS like a json config, so it can use Require to import
XML data and sprite sheet location right into a config my application loads.
Problem with all the other formatters is they made everything on new lines,
which would take up a giant amount of space.

Would be cool to have this as a little website to try out, too.

------
ud0
I'm already using and it works really nice, also submitted a pull request too.
But one thing I've always looked for in formatters is still missing here, it's
the ability to format the JSX in React.

It would be nice if the JSX in React's render could be formatted nicely
because a lot of times the code get's so long that formatting and indenting
becomes inaccurate.

------
simplify
Awesome! Can't wait for a sublime plugin :)

------
robbrown451
Would it be reasonable to have an editor that ran this every time you resize
your editor window?

I like to have multiple windows on screen at once, and will often adjust them
to make best use of screen real estate. I tend let it soft-wrap the text, but
I'd love it if it would do soft-wrapping... prettier.

~~~
gcommer
That sounds like an awesome idea (given that display is totally separated from
the format-on-save anyways).

I got a quick feel for it with this in a terminal:

    
    
        watch -n 0.1 'prettier --print-width $COLUMNS index.js'
    

... and unfortunately didn't really like it. Maybe in a pinch, but it still
ends up feeling really cramped trying to read column in low-width terminals.
At the other extreme (having the terminal be the only window on a 21:9
ultrawide), some of the lines get so long that you'd want a max anyways.

~~~
robbrown451
I'm playing with this in CodeMirror (browser based code editor) which talks to
a local node.js server, and I think it looks really good, as long as you have
lower and upper limits as you suggest. Biggest concern is stuff like the undo
history. I think it just needs a "formatting" button or even background
process when you leave it idle for a bit. Might be better to run on the
browser but haven't bothered trying yet.

------
piyush_soni
In the section of 'respecting patterns', I was really expecting that it'd
maintain my style of curly braces if they're already there, which has same
indentation level (and on new line) for a function's opening and closing
braces.

e.g. :

function something()

{

}

------
Can_Not
I was hoping to see alignment of = and : when declaring variables and objects.

~~~
adregan
I'm personally not a fan on alignment because of its impact on the project's
commit history and diffs. Not saying it's not nice to look at, I just prefer
not changing many unrelated lines because a new variable name is one character
longer than the names that surround it.

------
tony-k
i guess i'm relatively new to javascript (can count years on one hand), but
like many devs, i'm OCD about formatting and i'm a huge fan of eslint. i have
found that curating a list of rules can require cycles (not to mention
differences in opinion). i recently came across this project which had some
allure, and i made note to try when i had a moment:
[https://github.com/sindresorhus/xo](https://github.com/sindresorhus/xo), how
does "prettier" compare to this?

------
wnevets
am I the only one who dislikes spaces after braces?

i.e foo({ num: 3 },

~~~
jlongster
That's actually one of the few config options. Pass `--bracket-spacing=false`
to turn off that spacing (or `bracketSpacing: false` in the API)

~~~
gknoy
This tool looks amazing! Would you consider adding a flag for whether to
terminate statements with a semicolon, or consider accepting a PR that added
such an option? (My team is all-in on `standard`, so I'd love to be able to
execute this in a way that would be an easy fixer for our linting rules.)

~~~
jlongster
Check out this issue, we are discussing it:
[https://github.com/jlongster/prettier/issues/12](https://github.com/jlongster/prettier/issues/12)

Honestly, we may never do it. But we're still figuring out if the ultimate
goal is to keep to a single style or not.

------
lobster_johnson
gofmt — the official formatter of the Go language — made a very wise choice
for its formatting strategy. I think it's something other tools can learn
from.

gofmt will fix indentation, spacing, and so on, but it will generally preserve
structure. For example, this:

    
    
      a:=Foo{value:42}
    

becomes, of course:

    
    
      a := Foo{value: 42}
    

But! This:

    
    
      a:=Foo{
      value:42,
      }
    

becomes:

    
    
      a := Foo{
        value: 42,
      }
    

That's because gofmt can't really pretend to know that it knows better than
the developer here. Sometimes code does need to be loose (like in a DSL or a
big declaration, or a test (which must be readable), or similar). Sometimes it
should be compact.

This means you _never have to fight gofmt_. Never once have I disagreed with
its decisions.

gofmt works this way because its ruleset isn't exhaustive; it says that, yes,
an indent must happen after a hanging "{", but the ruleset doesn't say that a
_line break_ must happen. If there's a line break, let's stick with it.

Prettier seems to have a strict normalization approach: AST goes in, canonical
form goes out. For example, I tried this fictional piece of code:

    
    
        performAction({
          type: "thing",
          value: 42,
          owner: user, 
          bucket: root,
          path: p
        });
    

It's turned into a much less readable blob because it happens to fit on a
single line:

    
    
        performAction({type: "thing", value: 42, owner: user, bucket: root, path: p});
    

Unfortunately, in every instance where I indent the code in this manner, it's
for a specific reason. I _wanted_ it on separate lines; the fact that it
happens to _fit_ on a single line doesn't matter at all. Prettier overruled my
carefully indented code.

I often format code in a specific way for _regularity_ : Every chunk in a
block should have the same format, because each chunk is an instance of the
same pattern. For example, I might have something like:

    
    
      const RULES = [
        {
          type: "boost",
          fn: node => increaseImportance(node),
          weight: 0.5,
          dependencies: ["priority", "rotation"]
        },
        {
          type: "eliminate",
          fn: node => nil
        },
        // ... lots of rules ...
      ]
    

Prettier's output generates inconsistency:

    
    
        const RULES = [
          {
            type: "boost",
            fn: node => increaseImportance(node),
            weight: 0.5,
            dependencies: ["priority", "rotation"]
          },
          {type: "eliminate", fn: node => nil}
        ];
    

To quote the immortal Trump: No way!

Maybe one could use some advanced heuristics to find an optimal balance
between width vs. indentation vs. compactness; for example, in the above
array, a clever formatter could see that it's an array of object literals,
which means that it should prioritize regularity over compactness. If it's an
array of something simple (like numbers, but not numbers with trailing
comments), it can go compact. Maybe.

I don't use Prettier at the moment, but I know the strictness would drive me
nuts. I predict that Prettier is going to cause a lot of frustration and
heated discussion as a result of the one-size-fits-all approach. I don't think
a canonical form for everything even makes sense; people need _regularity_
(and no surprises), but not at the cost of readability.

~~~
ocharles
> I often format code in a specific way for regularity:

I am trying to write my own formatter at the moment, and this is exactly the
property I want, also. I'm working in Haskell, and one example is case
statements. There are two ways I'd like to format them:

case foo of A -> ... B -> ...

or

case foo of A -> ...

    
    
      B ->
        ...
    

The first is when every case fits on one line, but the second is when at least
one case needs to span multiple lines. I don't want this:

case foo of A -> ...

    
    
      B -> ...
    

I haven't yet come up with a good way to do that heuristically and
efficiently, but maybe just looking at how the original code is formatted
would be enough! Thanks for providing some food for thought :)

------
err4nt
It breaks the moment you type in with()

