codeformatter icon indicating copy to clipboard operation
codeformatter copied to clipboard

$DefaultBreakLinesMethod = None

Open hifismith opened this issue 3 years ago • 14 comments

I would like CodeFormatter to help me with spacing and indentation but not line breaks. I'd like it to

  1. Preserve all line breaks I enter
  2. Prevent the formatter from adding line breaks

So if I write:

a[x_]:=Block[{b},
b=2;x^2+b
]

I would like it to return

a[x_] := Block[{b},
  b = 2; x^2 + b
]

i.e. add spacing and indentation, but do not add or remove line breaks

Is there a way to do this? I tried $DefaultBreakLinesMethod=None, but it appears that symbol has to be set to a string. And I would like to apply these settings in VS Code so I can use "Format Document" or "Format Selection".

hifismith avatar Oct 28 '22 14:10 hifismith

At 25:26 of your 2020 WTC video, you say the formatter tries to preserve line breaks added by the user. It doesn't seem to right now. Being able to set Airiness -> -1 in VS Code's settings.json and preserving user-entered line breaks is pretty close to what I'm looking for.

hifismith avatar Oct 28 '22 15:10 hifismith

After that presentation, there have been several updates to CodeFormatter and one was to canonicalize the output by always first stripping out whitespace and newlines.

(specifically https://github.com/WolframResearch/codeformatter/commit/47a3386156d6b6e277070d26dca70d4cc32d2dc1)

This fixes a problem of "history dependence" on input and Airiness settings, i.e., you want to be able to interactively change Airiness and you want to always get the same output for each Airiness setting. If the newlines are preserved, then there is an undesirable "hysteresis" effect.

Now, what you want of not changing newlines at all (not removing existing newlines and not adding new ones) and only modifying whitespace is a good idea and other people have also asked for this sort of thing.

It would not be formatting per se, and I would call this something new like "Fix indentation" or "Fix whitespace" or "Redo whitespace" (suggestions please!)

And could be provided as a different menu item in editors that we support like VSCode and Sublime.

bostick avatar Oct 28 '22 17:10 bostick

Makes perfect sense why you would want to get rid of history dependence.

Until "CodeSpacer" comes out (or whatever you call it), is there a way to specify Airiness in VS Code? We have $DefaultLineWidth=Infinity, do we need $DefaultAiriness?

The functionality I describe in my original post is what IntelliJ does when using "Reformat Code" image

hifismith avatar Oct 28 '22 17:10 hifismith

Unfortunately, there is no $DefaultAiriness (I can work to add that) and we will now have to switch to using SetOptions.

I believe specifying:

SetOptions[CodeFormatter`CodeFormatCST, CodeFormatter`Airiness -> Automatic, "BreakLinesMethod" :> $DefaultBreakLinesMethod, "LineWidth" :> $DefaultLineWidth]

in your VSCode command will get you want (with appropriate values specified and making sure to properly escape the strings, and possibly removing spaces because I am paranoid about running commands with spaces in them).

bostick avatar Oct 28 '22 18:10 bostick

Nice! Set options on CodeFormatCST. Got it; thanks for that. These settings are close to my preference: Airiness -> -0.5, "LineWidth" -> 90, "BreakLinesMethod" -> "LinkeBreakerV2" (Testing with CodeFormat in a notebook)

It'd be nice if there was an Airiness level that put the commas on the same line as the code. It goes from this at Airness -> -0.84

solanTemperaturePlot[opts : OptionsPattern[]] := Block[{data},
    data = {tsw @ p3TS[kOutT], Thread[{outputs[[ ;; , 1]], outputs[[ ;; , 2, 3]]}]};
    afsPlot[
        data
        ,
        scaleXDate[]
        ,
        Joined -> {True, False}
        ,
        afsPlotFrameQ -> False
        ,
        Flatten[{opts}]
        ,
        PlotStyle -> {{Thickness[0.006], afsColors[[1]]}, {PointSize[0.012], afsColors[[3]]}}
        ,
        AspectRatio -> 1 / 3
        ,
        PlotLabel -> "P3 Wing Valve Temperature Comparison"
        ,
        FrameLabel -> {None, Style["Temperature [°C]", Black]}
        ,
        PlotLegends -> Placed[{"Field Data", "Model Predictions"}, {Scaled[{0.99, 0.31}], {1, 0}}]
    ]
];

to this at -0.85 (notice LineWidth is not respected)

solanTemperaturePlot[opts : OptionsPattern[]] := Block[{data}, data = {tsw @ p3TS[kOutT], Thread[{outputs[[ ;; , 1]], outputs[[ ;; , 2, 3]]}]}; afsPlot[data, scaleXDate[], Joined -> {True, False}, afsPlotFrameQ -> False, Flatten[{opts}], PlotStyle -> {{Thickness[0.006], afsColors[[1]]}, {PointSize[0.012], afsColors[[3]]}}, AspectRatio -> 1 / 3, PlotLabel -> "P3 Wing Valve Temperature Comparison", FrameLabel -> {None, Style["Temperature [°C]", Black]}, PlotLegends -> Placed[{"Field Data", "Model Predictions"}, {Scaled[{0.99, 0.31}], {1, 0}}]]];

hifismith avatar Oct 28 '22 19:10 hifismith

EDIT: I had Wolfram.command edited in the wrong settings file. I copy-pasted into both (.vscode/settings, and user settings). It's working now

ORIGINAL: Is there not a 1-to-1 mapping between CodeFormatCST in VS Code and CodeFormat in a notebook? This is the result of using SetOptions in VS code (Format Selection or Format Document), which looks different from what I pasted in my last post

solanTemperaturePlot[opts : OptionsPattern[]] :=
  Block[{data},
    data = {tsw @ p3TS[kOutT], Thread[{outputs[[ ;; , 1]], outputs[[ ;; , 2, 3]]}]};
    afsPlot[data, scaleXDate[], Joined -> {True, False}, afsPlotFrameQ -> False, Flatten[{opts}], PlotStyle -> {{Thickness[0.006], afsColors[[1]]}, {PointSize[0.012], afsColors[[3]]}}, AspectRatio -> 1 / 3, PlotLabel -> "P3 Wing Valve Temperature Comparison", FrameLabel -> {None, Style["Temperature [\[Degree]C]", Black]}, PlotLegends -> Placed[{"Field Data", "Model Predictions"}, {Scaled[{0.99, 0.31}], {1, 0}}]]
  ];

hifismith avatar Oct 28 '22 19:10 hifismith

I'm having trouble reproducing example in your question about going from Airiness -> -0.84 to Airiness -> -0.85.

Can you show all the steps that you used starting with a fresh kernel?

bostick avatar Oct 31 '22 13:10 bostick

I can't seem to reproduce either. Was there a new Paclet pushed? Looks like I'm now on 1.7

It's still working the same in VS Code, but I can't reproduce it in a notebook. Here's my VSCode expression:

"Needs[\"LSPServer`\"];SetOptions[CodeFormatter`CodeFormatCST, CodeFormatter`Airiness -> -0.5, \"BreakLinesMethod\" :> \"LineBreakerV2\", \"LineWidth\" :> 120];LSPServer`StartServer[]"

In a notebook (notebook adding line wrapping): image

Using VS Code (Format Document): image

Example string: " mOpts = {Splice@Flatten[{opts}], Joined -> {True, False}, afsPlotFrameQ -> False, PlotStyle -> {{Thickness[0.006], afsColors[[1]]}, {PointSize[ 0.012], afsColors[[3]]}} , AspectRatio -> 1 / 3 , PlotLabel -> "P3 Wing Valve Temperature Comparison" , FrameLabel -> {None, Style["Temperature [°C]", Black ]} , PlotLegends -> Placed[{"Field Data", "Model Predictions"}, {Scaled[{0.99, 0.31}], {1, 0}}]};"

hifismith avatar Oct 31 '22 13:10 hifismith

Your example above has "LinkeBreakerV2" (typo extra e).

I can also work to warn about unrecognized values for options.

bostick avatar Oct 31 '22 14:10 bostick

Thanks! That was it 🤦🏼‍♂️

Are you able to reproduce the same results now? image

hifismith avatar Oct 31 '22 14:10 hifismith

Here's a notebook if it helps: Google Drive Link

hifismith avatar Oct 31 '22 14:10 hifismith

Yes, I see the same thing.

I'm sorry, can you give an example of what you are seeing vs. what you are requesting?

bostick avatar Oct 31 '22 15:10 bostick

Maybe at Airness -> -0.75, the commas stay on the previous line like this:

mOpts = {
  Splice @ Flatten[{opts}],
  Joined -> {True, (*True*)False},
  PlotRange -> {165, 185},
  afsPlotFrameQ -> False,
  ImageSize -> 600,
  PlotStyle -> {{Thickness[0.006], afsColors[[1]]}, {PointSize[0.012], afsColors[[3]]}},
  AspectRatio -> 1 / 3,
  PlotLabel -> "P3 ESP Discharge Pressure Comparison",
  FrameLabel -> {None, Style["Pressure [barg]", Black]},
  PlotLegends -> Placed[{"Field Data", "Model Predictions"}, {Scaled[{0.99, 0.71}], {1, 0}}]
};

Reason being, I can then use a plugin to help align the code further to make it more readable and more compact: image

Here's another example using multi-column alignment: image

I use "Smart Column Indenter," which doesn't work as well with the comma breaking the pattern between each line. What do you think?

hifismith avatar Oct 31 '22 17:10 hifismith

It's a good idea and there is already some cases where commas are kept on the same line if the structure is known.

e.g. LibraryFunction is hard-coded to format like this:

In[7]:= CodeFormat[code]
Out[7]= LibraryFunction["sqlite3_bind_int64"][
    statement,
    Cast[i, "Integer32", "ReinterpretCast"],
    Cast[v, "Integer64"]
]

but it's not a general solution and I have to make some changes to allow it to work in general.

bostick avatar Oct 31 '22 20:10 bostick