Our great sponsors
-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
-
biome
A toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.
-
InfluxDB
Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
For example, the latest Prettier makes XHTML files invalid by changing DOCTYPE to lowercase:
https://github.com/prettier/prettier/issues/15476
Prettier moves ts-ignore comments which can cause TypeScript errors:
https://github.com/prettier/prettier/issues/15876
Interpreting nested CSS functions' "-" as minus and inserting a space:
https://github.com/prettier/prettier/issues/15369
I picked up standard[1] a while back for this reason, I don't want to have to think about it. It works fine, I have no complaints (took me a while to get used to not using semi-colons but now I prefer it) Same reason I use `cargo fmt` as well.
[1] https://standardjs.com/
1.1k isn't bad for a project with ~33 million weekly downloads[1], imo. Yes, I know that's not necessarily a good metric, but it's ~10 million more than React[2] which also has a similar number of open issues[3].
[1]: https://www.npmjs.com/package/prettier
[2]: https://www.npmjs.com/package/react
[3]: https://github.com/facebook/react
I think I agree about the testing and labor of complicated translation rules.
But it doesn't appear that almost every pretty printer uses the Wadler pretty printing paper. It seems like MOST of them don't?
e.g. clang-format is one of the biggest and best, and it has a model that includes "unwrapped lines", a "layouter", a line break cost function, exhaustive search with memoization, and Dijikstra's algorithm:
https://llvm.org/devmtg/2013-04/jasper-slides.pdf
The YAPF Python formatter is based on this same algorithm - https://github.com/google/yapf
The Dart formatter used a model of "chunks, rules, and spans"
https://journal.stuffwithstuff.com/2015/09/08/the-hardest-pr...
It almost seems like there are 2 camps -- the functional algorithms for functional/expression-based languages, and other algorithms for more statement-based languages.
Though I guess Prettier/JavaScript falls on the functional side.
I just ran across this survey on lobste.rs and it seems to cover the functional pretty printing languages influenced by Wadler, but functional style, but not the other kind of formatter ("Google" formatters perhaps)
https://arxiv.org/pdf/2310.01530.pdf
> My only bad experience with prettier, besides the incredible slowness (orders of magnitude slower than ruff)
Ruff is based on the same foundations that Biome (https://biomejs.dev/). Although Biome doesn't support all languages that Prettier supports, you should give a try, it is fast.
You can mellow the squiggles for stylistic errors in VS Code.
Take a look at the “eslint.rules.customizations” key in this file:
https://github.com/antfu/eslint-config/blob/main/.vscode/set...
> Oh I'm curious why you're rewriting it?
The primary driver is that we're moving to a fairly different formatting style: https://github.com/dart-lang/dart_style/issues/1253
The formatter works sort of like a compiler in that it parses the code, translates it to an internal representation, does optimization on that IR, and then outputs final code. The main difference is that the "final code" is also source code, and the "optimization" is line splitting.
The old IR grew organically over time and got increasingly difficult to work with. It baked certain formatting choices directly into the IR (mainly indentation) which line splitting then had no control over. For example, given a function call like:
someLongFunctionName(some + long + argument + expression, [firstElement, anotherElement, aThirdElement]);