Pizzaandy / Gobo

Gobo is an opinionated code formatter for GameMaker Language.
https://pizzaandy.github.io/Gobo/
MIT License
20 stars 1 forks source link

Verticality vs Horizontality #13

Open adam-coster opened 4 months ago

adam-coster commented 4 months ago

As stated in the docs, the current formatter output is similar to what Prettier produces for JavaScript. Most of my dev work is in JavaScript, so this is both preferable and really familiar to me, personally.

However, GameMaker has historically required a lot of horizontality because its IDE lost (still loses?) context when moving to a new line. In particular, the IDE did not provide function argument support if you wanted to put an argument on a new line.

This means that our main programmer and our existing code strongly prefer more horizontality, and unless the context issue has been resolved in recent GameMaker IDE versions it also needs to be that way.

I know the whole point of an auto-formatter like this is to minimize formatting options, but at least for our use case the current options don't fit with the practicalities of GML. In particular:

Because of the historical functionality of GameMaker, we'd probably want a formatter that wasn't print-width-based at all, but rather just had a set of consistent semantics rules. The rules would be similar to what happens with GOBO when the print width is exceeded, with some exceptions:

Would it make sense to have this sort of GameMaker-friendly option, or is that out of scope for what you intend with Gobo?

Pizzaandy commented 4 months ago

Each node has a PrintNode method that outputs to an intermediate format called a Doc, which contains the information about where line breaks can occur. You could make a fork and modify the PrintNode method for ArgumentList so that it never breaks.

https://github.com/Pizzaandy/Gobo/blob/fcffa74ce8c057924f2012aae40efcfe5a05d032/Gobo/SyntaxNodes/Gml/ArgumentList.cs#L17

e.g.

public override Doc PrintNode(PrintContext ctx)
{
    // Won't break!
    return Doc.Concat("(", Doc.Join(", ", PrintChildren(ctx)), ")");
}

Side note: this would result in double-printed comments on argument lists due to the way expression chains are handled. But as long as you don't have comments like `call /huh?/ ()` it should be ok.

You can also modify undefined arguments to not print as "undefined":

https://github.com/Pizzaandy/Gobo/blob/fcffa74ce8c057924f2012aae40efcfe5a05d032/Gobo/SyntaxNodes/Gml/UndefinedArgument.cs#L11

Whether this should be included as an option is a tricky question. I'm not a frequent GM IDE user so I'd have to ask around to see if these issues are prevalent enough to justify more options.

adam-coster commented 4 months ago

Rad, good to know, thanks!

Pizzaandy commented 4 months ago

Just talked with some discord folks and it seems like empty arguments like doSomething("hello",,,true,,[10]) are common enough to justify changing the behavior. Thanks for bringing up the issue!