Introduce line breaking in format command#486
Conversation
|
Thanks @sorenhartmann! You probably want to rebase on top of the most recent |
fdeb705 to
8ffc483
Compare
|
Alright so this is a (perhaps crude) implementation of a line wrapping algorithm for Fortran. In large part, this is inspired by how black / ruff seems to go about deciding when and where to break different language nodes. In particular, being as consistent as possible and breaking outer scopes before inner scopes. The basic approach is as follows
I noticed that this approach is quite close to what Some notes
Finally, as an initial implementation I have the following pipeline set up
|
ZedThree
left a comment
There was a problem hiding this comment.
Thanks @sorenhartmann! This looks great, it's really appreciated!
I have some high level comments:
- it would be good to get some unit tests on some of the individual functions -- I'm happy to lend a hand with this
- after fixing writing the output, I notice there are some test failures: it looks like a line break is being forced in cases where one isn't necessary? For example, this snippet:
- function real_not(a)
+ function real_not( &
+ a)Ahh, this is because the line length is currently hardcoded to 20, with an indent of 2; changing this to 80 and all the tests pass -- ok, so this is just a matter of needing to handle user options. Again, something I'm happy to help with
- we'll have to handle the different newline styles --
\n/\r\n/\r, but we can put this off for now - this "black-esque" style, with the vertical wrapping, is not going to be to everyone's tastes -- we've had a fair bit of discussion about this. I do like it, because it basically requires no options, and so there can be no arguments about tuning it really. However, we'll likely end up having this as one of two options, with the other being a flatter wrapping style -- just something to bear in mind
Also, a couple of points to help with developing rust:
- it's good to run
cargo clippyfairly frequently (or even better, set up LSP or something in your editor to run it automatically). This is the rust linter, and it's fantastic, it's really helpful for learning rust. README.dev.mddescribes how to run the tests
| ) | ||
| } | ||
|
|
||
| if strings.last().unwrap().ends_with('&') { |
There was a problem hiding this comment.
This doesn't handle comments after a &, but maybe that's correct. Presumably if we see something like:
foo = bar & ! comment
+ zagwe only want to indent + zag correctly, but leave the line break and comment alone, otherwise we have to work out where to put the comment.
There was a problem hiding this comment.
I'll admit, I did not consider this edge case, but it seems to me it is handled somewhat reasonably
As far as I can tell, indentation should in general be handled by the topiary query, since indentation is stripped prior to formatting, with no way to preserve it.
Currently the line breaking logic does not allow the breaking of any nodes spanning more than on line, so introducing a comment, would effectively disable line breaking across the entire math expression, i.e.
foo = abc + bar & ! comment
+ zag + defwould break to
foo = abc + bar & ! comment
+ zag + defand not
foo = abc &
+ bar & ! comment
+ zag &
+ defThese fit into the `Configuration` framework. Some work still needs to be done, namely that `Settings` is currently living in the linter crate, when it should be in the workspace crate.
|
I've wired up the settings to this, and added two tests for your new example: one with the default line length (100), and one with a shorter one (20) |
|
I think the Clippy issue can be fixed by rebasing on the latest main |
Courtesy of ChatGPT
|
@ZedThree @LiamPattinson Thank you for the feedback, it is really appreciated! First of all, I apologize for the late reply.
|
|
Thanks @sorenhartmann! Seems like the clippy issue is resolved, so no need to rebase. We've got a session at a workshop next week, so I might see if we can get some people to try out this branch and get some real world feedback.
That's probably wise, I would really very much hate to waste your time! One thing about using ruff's solution would be that we can take advantage of any improvements they make very easily, but it's possible that it's a lot of work to use it in the first place. I'm also not sure how flexible their solution is. If it's a bunch of work to achieve the same results you've got here, then it is probably not worth it. |
WIP