Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for OTP 27 Sigils & Triple Quoted Strings #358

Merged
merged 2 commits into from
Sep 2, 2024
Merged

Support for OTP 27 Sigils & Triple Quoted Strings #358

merged 2 commits into from
Sep 2, 2024

Conversation

maennchen
Copy link
Contributor

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 24, 2024
@maennchen maennchen marked this pull request as draft August 24, 2024 16:31
@maennchen maennchen marked this pull request as ready for review August 24, 2024 16:54
@eproxus
Copy link

eproxus commented Aug 27, 2024

Lovely! I had just started on a similar PR myself 😄

Does it support triple quoted strings in documentation attributes? I didn't see a specific test case about that:

-module(foo).
-moduledoc """
The module.
""".

-doc """
The function.

Long description.
""".
f() -> ok.

Also, does it re-indent triple quoted strings. E.g. from:

f() ->
    """
the
  long
     string
""".

to

f() -> 
    """
    the
      long
         string
    """.

I used the following test module test/erlfmt_SUITE_data/triple_quoted_strings.erl:

-module(triple_quoted_strings).
-moduledoc """
abc
""".

-doc "foobar".
-type my_type :: integer().

-doc """
     baz
         extra
     """.
-opaque otype :: integer().

-doc "qux"
foo() ->
    """
    foo
    """.

bar() ->
"""
the
  long
     string
""".

Together with the desired result test/erlfmt_SUITE_data/triple_quoted_string.erl.formatted:

-module(triple_quoted_strings).
-moduledoc """
abc
""".

-doc "foobar".
-type my_type :: integer().

-doc """
     baz
         extra
     """.
-opaque otype :: integer().

-doc "qux"
foo() ->
    """
    foo
    """.

bar() ->
    """
    the 
      long
         string
    """.

as a test driver, though I'm not 100% sure about if the result will be correct since I never finished implementing the indentation logic.

@maennchen
Copy link
Contributor Author

Does it support triple quoted strings in documentation attributes? I didn't see a specific test case about that:

Yes.

https://github.com/WhatsApp/erlfmt/pull/358/files#diff-ca49d93bca04b364c997af828c3aaf95beff334a9307b97fb1317b1721812ae4R4271

Also, does it re-indent triple quoted strings. E.g. from:

No, I haven't looked at indentation. But that would be a good feature to have.

I don't have the time right now to also get into this myself, but I would be very happy to collaborate to create a shared PR combined with your indentation logic. Do you want to send a PR to my PR branch? :D

@eproxus
Copy link

eproxus commented Aug 27, 2024

Does it support triple quoted strings in documentation attributes? I didn't see a specific test case about that:

Yes.

Ah, missed that. My bad!

#358 (files)

Also, does it re-indent triple quoted strings. E.g. from:

No, I haven't looked at indentation. But that would be a good feature to have.

I don't have the time right now to also get into this myself, but I would be very happy to collaborate to create a shared PR combined with your indentation logic. Do you want to send a PR to my PR branch? :D

Yeah, I can do that. I have the test and some "attempt" at getting indentation working. So far I added this hack but I have no clue if it is the right way to proceed or not:

diff --git a/src/erlfmt_algebra.erl b/src/erlfmt_algebra.erl
index 0f0994c..29ea433 100644
--- a/src/erlfmt_algebra.erl
+++ b/src/erlfmt_algebra.erl
@@ -522,6 +522,9 @@ format(Width, _, [{Indent, _, #doc_line{count = Count}} | T]) ->
     [NewLines, indent(Indent) | format(Width, Indent, T)];
 format(Width, Column, [{Indent, M, #doc_cons{left = X, right = Y}} | T]) ->
     format(Width, Column, [{Indent, M, X}, {Indent, M, Y} | T]);
+format(Width, Column, [{Indent, _, #doc_string{string = [$",$",$"|_] = S, length = L}} | T]) ->
+    [First|Rest] = string:split(S, <<"\n">>, all),
+    [First, [[indent(Column - string:length(First) - 1), R] || R <- Rest] | format(Width, Column, T)];
 format(Width, Column, [{_, _, #doc_string{string = S, length = L}} | T]) ->
     [S | format(Width, Column + L, T)];
 format(Width, Column, [{_, _, S} | T]) when is_binary(S) ->

Some feedback on that direction from you or the maintainers would be nice 😅

@michalmuskala
Copy link
Member

Thank you for the PR, this is great!

I agree we do need to handle indentation of the tripple-quote strings before merging. The test example that @eproxus gave is a good one to include, however I see an inconsistency with:

-moduledoc """
abc
""".

-doc """
     baz
         extra
     """.

I believe both should end up indented like the -moduledoc to end up with:

-moduledoc """
abc
""".

-doc """
baz
    extra
""".

As to the particular approach, I'm generally fine with a hacky solution - the formatter has many of those already 😅

@eproxus
Copy link

eproxus commented Aug 27, 2024

@michalmuskala I added the second in the sense of that the tool should try to keep the existing desire of the user if possible (as is done with line breaks somewhat). But perhaps for indentation that rule is not really applied now that I think about it...

src/erlfmt_parse.yrl Outdated Show resolved Hide resolved
src/erlfmt_scan.erl Outdated Show resolved Hide resolved
test/erlfmt_format_SUITE.erl Outdated Show resolved Hide resolved
@michalmuskala
Copy link
Member

@eproxus in general we retain line breaks introduced by the user, but we do re-indent everything according to the rules

@eproxus
Copy link

eproxus commented Aug 27, 2024

@michalmuskala Makes sense!

@maennchen Do you want a PR with my stuff right now to your branch, or would you rather fix the comments first?

@maennchen
Copy link
Contributor Author

@eproxus Fixes are done. Go ahead :)

@michalmuskala
Copy link
Member

Is this ready to merge? Or should I wait for the work on indentation?

@eproxus
Copy link

eproxus commented Sep 2, 2024

I think the PR is good enough to add compatibility for OTP 27. I got stuck in the rabbit whole of actually implementing indentation and didn't succeed yet. @maennchen Do you want my half-working code there?

@maennchen
Copy link
Contributor Author

@michalmuskala We can merge this without indentation support. 👍

@eproxus I don't plan on working on the indentation. But if anyone else wants to, it might be good to push the code somewhere so that they can look at the work you already did.

@michalmuskala michalmuskala merged commit 13b0510 into WhatsApp:main Sep 2, 2024
9 checks passed
@michalmuskala
Copy link
Member

I'll look into properly handling indentation myself

Thank you both for working on this! ❤️

@maennchen maennchen deleted the otp27 branch September 2, 2024 15:11
@michalmuskala
Copy link
Member

@maennchen I noticed you implemented conversion of single-line tripple-quoted strings into a regular string. I'm not sure we should actually do that - in general we try to preserve the "style" of an expression the user wrote. I'm leaning towards removing this conversion

@michalmuskala
Copy link
Member

Support for indentation was implemented in #362 and I cut a 1.5.0 release with support for the new OTP 27 features

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OPT 27's -moduledoc """ makes erlfmt fail
4 participants