Adding custom code formatting

Hi,
I’m playing with Rescript for some time now, and I have to say I really don’t like how Rescript format a code by default.
The most common things are:

  • enforcing pipe operators chain in one line
  • enforcing component props in one line

Is it possible to apply a custom format style?

5 Likes

Rescript’s formatter is not configurable and currently there’s no plan for it afaik.
The reason behind this is to maintain a consistent codestyle in community and I think there are good reasons for this.
but your cases are valid IMO.
In order to solve this there’s an idea to format pipes (and maybe other parts) based on previous state
see Smart linebreak printer for pipe chains · Issue #257 · rescript-lang/syntax · GitHub .
Note that formatter currently does that in some cases.
For example check these two snippets and hit format : #1 #2

3 Likes

Do you have an example of how you want to format your code?

Example 1:
I would like to see:

    value
      -> Future.map(cb1)
      -> Future.get(cb2)

What I get:
value -> Future.map(cb1) -> Future.get(cb2)
Note:
Current formatting is awful for code readability. It’s exactly the same example as @amiralies posted in the first link.

Example 2:
I would like to see:

    <MyComp
      prop1
      prop2=value
      prop3=otherValue
    />
    <div>
        <p>{"hello" |> React.string}</p>
    </dif>

what I get:

    <MyComp prop1 prop2=value prop3=otherValue />
    <div><p>{"hello" |> React.string}</p></dif>

notice:
Again, harder to read, harder to quick change.

There might be a good reason and bad consequences. Rust has a unified formatter experience, and it’s marvelous (I think you can customize it these days anyway). Rescript has it too and, in my opinion, is… well, questionable.
It’s hit or miss approach, some may like it and some will hate, and won’t touch language anymore. But there is a bigger problem here, IMHO. When I started ReasonML, it was just fun to write code. It’s not anymore with Rescript. With more and more little gotchas like that, I have to think twice every time I approach a new project. ReasonML felt like 2 steps forward and Rescript like 1 step back (but still 1 step forward :wink: ).
I really like Elm, but unfortunately, it doesn’t support anything like React Native. Because of that, I think Rescript is currently the best alternative for Typescript, and also is pretty fresh yet, so I hope all these little gotchas will be improved some day :grinning_face_with_smiling_eyes:

1 Like

Your arguments are valid as I said. there are rooms for improvements in printer. i’m only a bit against having configurations.
This is a good read about this

1 Like

The only practical usage of Prettier is with integration with linters, so basically tons of configuration. For me, it seems like the article is irrelevant to its own tool.
Of course, it’s better to have auto-indent, but while thinking about code formatting I have rust-fmt in mind that format code heavily without any configuration or Prettier+eslint that has tons of configuration but can deal even with jsx.
I’m not saying that having a lot of configuration is good. I don’t even mean that Rescript needs configuration files.
We already agreed, that in some cases Rescript could handle it better.
The only thing that worries me is that the issue was reported 4 months ago. Seems like there is not a chance for quick progression for pipes, and it will be even harder for jsx.

1 Like

I agree. Still as of august 24 there’s no option to change these things. And it’s a shame, because even in other niche languages like f# this is greatly covered with fantomas.

I don’t know how difficult this is to implement, but if the end goal is to attract js users, and prettier is the standard, why not copy prettier output results?

I’m totally in for rescript though. It’s the most practical functional compile-to-js language in the market. Today I discovered that you can even make your own dsls with custom jsx. That’s awesome!

Yay, this is super annoying to the point it’s hindering reading. I don’t have a problem with no config formaters, Rust or Elm got it right. Very surprising especially even your own documentation got it right. This is such a big deal for me coming from a common-sense formater I’ll just stop using it.

Here is directly from rescript doc’s.

1 Like

Just getting in to ReScript and have found this a bit baffling.

I’ve been using the IntelliJ plugin by @hgiraud which has been great so far, but I agree the default formatter is a bit brutal.

I’m a big fan of newlines for readability, it’d be great to allow some user configuration for this :slight_smile:

There is no configuration, but there is “smart printing” for certain structures like pipe-chains or records.

Have a look: [ANN] Smart linebreaks for pipe chains

EDIT: Do you mean more than just one empty newline after another? Why? If you really want to space it out you can add a comment. I find it OTOH much more useful that I can put lots of newlines after another and they are all removed on save.

1 Like

Thanks Florian, the smart line breaks look good in that context.

Perhaps I’ve got any terminology wrong, but I think there’s a slight discrepancy in behavior when formatting ReScript code and JSX.

It appears that within a function one blank line is allowed between statements, whereas all blank lines are removed when the JSX is formatted.

In the example below I find it much easier to read when the switch statement has a blank newline before and after it (these are removed when formatting). I could explain this further, but ultimately it comes down to personal preference - I find it easier to see at a glance what’s happening in the code.

I don’t think adding comments would help necessarily, and even then I’d prefer a newline preceding the comment.

without spaces:
withoutSpaces

with spaces:
withSpaces

3 Likes

Ok now I understand it. Having consistency between the two syntaxes makes a lot of sense and I must have grown blind to it over the years. We also won’t need a config option for that IMO.

I created an issue for it.

4 Likes

Excellent thank you!

1 Like