StyLua icon indicating copy to clipboard operation
StyLua copied to clipboard

Several calls needed to get final formatting of array

Open echasnovski opened this issue 3 years ago • 3 comments

I am not sure if this behavior is intended, so decided to create an issue here.

Steps (using stylua 0.13.1):

  • Create file (for example, 'tmp.lua') with following contents:
local arr = {{"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}}
  • Apply stylua tmp.lua with default settings. I get this diff:
-local arr = {{"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}, {"a"}}
+local arr =
+       { { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, {
+               "a",
+       }, {
+               "a",
+       } }
  • Now apply again the same command stylua tmp.lua. It changes formatting according to this diff:
-local arr =
-       { { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, { "a" }, {
+local arr = {
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       { "a" },
+       {
                "a",
-       }, {
+       },
+       {
                "a",
-       } }
+       },
+}

I would expect it to go after the first call directly to this:

local arr = {
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
	{ "a" },
}

echasnovski avatar Jul 01 '22 07:07 echasnovski

This class of bug is quite difficult to fix.

The way we check to determine if a table should hang or not is currently very naive - it relies on the input formatting, in particular the distance between the start and the end brace (+0-2 if spaces are necessary after the outermost braces).

I've tried formatting deeper before but it led to a severe performance regression as it caused exponential blowup for deeply nested tables (https://github.com/JohnnyMorganz/StyLua/pull/208)

The main thing that I need to develop is some way to perform a simpler formatting for checking, which has bounded complexity

JohnnyMorganz avatar Jul 05 '22 19:07 JohnnyMorganz

Very off topic, but may be helpful.

Some random idea about approach to formatting
I once toyed with the idea of implementing general formatting engine based on treesitter-like grammar. As often the case, general algorithmic approach seemed somewhat interesting, but actually implementing it required a lot of effort to learn and do stuff.

So approach was something like this:

  • Each parsed language node has exactly two formatting rules: basic and expanded. For function calls it is something like "fit on single line" and "put all arguments on separate lines".
  • First, all nodes, even nested, are formatted with basic rules. So this will usually result into everything fit in one big single line.
  • Check nodes from top to bottom hierarchically. If formatting of expression doesn't satisfy some predicate (like "fit every line width to 120 characters") format it with expanded rule and don't touch it later.
  • Repeat for every node from top to bottom formatted with "basic" rule until all predicates are satisfied.

I know this doesn't generalize very well (e.g. Python can't really be done this way), but idea came when I thought about how I would format Lua code.

And also I know that this won't apply fully to StyLua. Just felt the urge to share this with someone experienced with code formatting. Maybe it will spark something.

echasnovski avatar Jul 06 '22 06:07 echasnovski

Interesting, this is very similar to how stylua works, expect one key difference being we do the single/expanded predicate check nested inside of each node.

Admittedly, this is problematic. We do a lot of unnecessary work which will ultimately be discarded. In particular, for heavily nested tables/other expressions, the branching blows up.

It's been a year and a half now since I started this (wow, time flies), but there is probably a lot I would change. Your approach sounds interesting, something else which look interesting was prettiers algorithmic approach with "commands". I want to maybe one day starting again with a fresh slate, but that's a major undertaking unfortunately. (Atleast we have a very large test suite to verify changes 😅)

As an aside, you might be interested in this blog post: https://journal.stuffwithstuff.com/2015/09/08/the-hardest-program-ive-ever-written/. It's not how stylua works, but I think they approached this problem well

JohnnyMorganz avatar Jul 06 '22 07:07 JohnnyMorganz