domluna / JuliaFormatter.jl

An opinionated code formatter for Julia. Plot twist - the opinion is your own.

Home Page:https://domluna.github.io/JuliaFormatter.jl/dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Format `Dict` definitions like `Vector` definitions

efaulhaber opened this issue · comments

We're using the SciML style guide since we found that it's very consistent with our "in-house" style.
However, we would like to format Dict definitions similar to Vector definitions like this:

x = [
    "some arbitrary string bla bla bla bla bla bla bla bla bla",
    "another longer arbitrary string bla bla bla bla bla bla bla bla",
]

SomeLongerTypeThanJustString = String
y = Dict{Int, SomeLongerTypeThanJustString}(
    1 => "some arbitrary string bla bla bla bla bla bla bla bla bla",
    2 => "another longer arbitrary string bla bla bla bla bla bla bla bla"
)

After auto-formatting, however, it looks like this:

y = Dict{Int, SomeLongerTypeThanJustString}(1 => "some arbitrary string bla bla bla bla bla bla bla bla bla",
                                            2 => "another longer arbitrary string bla bla bla bla bla bla bla bla")

This also goes way beyond the 92-character limit.
Is there a way to redefine this behavior without changing the rest of the formatting rules?

currently there's no way to mix and match like that without creating your own style and overloading some calls. For the array calls you would need to overload p_vect and maybe something else as well to handle the typed case x = A[1, 2].

For the Dict definition it would be p_call and then you would check if the caller is Dict.

In both of these cases you would dispatch to DefaultStyle otherwise SciMLStyle

Thanks! The array call is already formatted the way I want it to. I just want to format Dict calls according to DefaultStyle.

From my understanding, before I even try to figure out how to check if the caller is a Dict, just redefining

function JuliaFormatter.p_call(style::SciMLStyle, cst::CSTParser.EXPR, s::JuliaFormatter.State)
    JuliaFormatter.p_call(DefaultStyle(style), cst, s)
end

should already format the Dict definition the way I want to, right? But it would then also change the formatting of function calls, which I don't want to do.

However, after this redefinition, I now end up with this:

y = Dict{Int, SomeLongerTypeThanJustString}(
                                            1 => "some arbitrary string bla bla bla bla bla bla bla bla bla",
                                            2 => "another longer arbitrary string bla bla bla bla bla bla bla bla"
                                            )

So, one additional line break after the opening parenthesis, but still with the indent that I don't want.

yes that should work!

oh sorry you'll also have to update the nesting function as well since that determines how it's indented, etc. n_call! - here's an example https://github.com/domluna/JuliaFormatter.jl/blob/master/src/styles/yas/nest.jl#L1

but that will work for all function calls not just ones with Dict, maybe that's what you want but if not you would need to verify the caller is Dict.

Thanks, now that part works.
How can I verify that the caller is Dict?

cst[1] will be that node. It seems either it's a curly node or a leaf node

JuliaFormatter.is_leaf(cst[1])

will check this

so you can do

is_dict_call = false
if JuliaFormatter.is_leaf(cst[1]) && cst[1].val == "Dict"
  is_dict_call = true
elseif !JuliaFormatter.is_leaf(cst[1]) && JuliaFormatter.is_leaf(cst[1][1]) && cst[1][1].val == "Dict"
  is_dict_call = true
end
   

then dispatch based on is_dict_call

and then do something similar for n_call!

it should actually work the exact same for an FST node

Thank you very much! Everything works as expected. Only forwarding all functions to SciMLStyle was a bit of a hassle.

Now, is there any way to use my custom style in VS Code? It seems like the config only allows the predefined styles:

if (style = get(config_dict, "style", nothing)) !== nothing
@assert (
style == "default" ||
style == "yas" ||
style == "blue" ||
style == "sciml" ||
style == "minimal"
) "currently $(CONFIG_FILE_NAME) accepts only \"default\" or \"yas\", \"blue\", \"sciml\", or \"minimal\" for the style configuration"

Alright, I decided not to create a completely new style that only really changes this one thing, but to instead add this as an option to SciMLStyle.
I created a PR, which is now ready for review: #676