I’m excited to announce elmfmt, as I’ve always wanted a configurable formatter for Elm.
While it’s a laudable goal to have one true formatting style for the Elm ecosystem, the reality is that I spend most of my time in my code which might be written in Elm, Haskell, Rust, TypeScript, … and I care more about having consistent code formatting among my projects, than conforming to some random Elm code on the internet.
It’s still rough around the edges but I already used it to re-format all my Elm code, so it’s definitely usable! There are not many configuration options yet, but I’d be happy to hear your wishes. So feel free to open issues! The default formatting style is mostly like elm-format, but with 2 spaces indentation instead of 4 and less spacing between several let expression and case … of branches.
This was also a good opportunity to try out Topiary, which is written in Rust and uses the tree-sitter ecosystem for parsing etc. Unfortunately it didn’t quite fulfill my expectations:
It was quite some work to handle all edge cases
It’s a little slower than elm-format
The Topiary playground code wasn’t updated in quite some time and so I can’t build a webapp to showcase the formatting features
But the biggest advantage of Topiary is its large community, so those problems will hopefully be addressed in future versions.
I can see this formatter being great for when you’re playing with the repl and don’t want the ‘correct’ spacey format yet.
What I’d love is an option to only emit blank lines between top level functions.
eg. you’re working on this (really contrived) function and send to repl to test.
doSomething a =
case a of
1 →
“one”
2 →
“two”
_ →
“nfi”
You then change it to this and send to repl, which works.
doSomething a =
case a of
1 →
“one”
2 →
“two”
3 →
"oh yeah, three's a number as well"
_ →
“nfi”
You think you’re happy and save the code and end up with this…
doSomething a =
case a of
1 →
“one”
2 →
“two”
3 →
"oh yeah, I forgot three"
_ →
“nfi”
Now, adding 4 is gonna be a pita because you need to go back and delete the blanks before making any changes and resending to repl.
Another nice thing would be a ‘keep-cases-simple’ option so if the result is ‘simple’ it doesn’t get dropped to a new line.
doSomething a =
case a of
1 → “one”
2 → “two”
_ → “nfi”
Again, I wouldn’t use the formatter for the final code/project, just while playing around, so I don’t have to keep deleting blank lines every. time. I. save.
EDIT: and yes I know I can import ScratchPad.elm exposing (..) but that falls over when you’re writing code to fix a problem (and the compiler is complaining).
This is a very rich and powerful way to provide an alternate formatter! I will keep an eye out.
Some time ago, I decided on a middle ground
I appreciate that elm-formatter is the unofficial standard for Elm and I appreciate the unity of this ecosystem for core concerns.
However, all the line feeds elm-formatter produces are truly disquieting for me. It is minor but perceptible. I recognize that I am probably more sensitive to visual representation than 90% of people and probably only n% of all people dislike the space.
Therefore, I decided that a compromise would be nice: just remove the, in my mind, excessive line feeds (and a few other minor changes). I thought “well I don’t need to re-implement the formatter for that”. So I wrote it tiny little post-processing script with the idea that one could use a run-on-save task runner in the IDE (like Run on Save for VSCode) to first run elm-format and then this script.
I just wanted to post it here in case anyone else here could benefit from this poor-man’s hack
I’m thinking a customizable formatter may be useful for docs, where sometimes compactness for read experience is more valuable than clean updates. Though, as pointed out by others, I prefer the “no-config” approach for all code that goes into the code base.