google / yamlfmt

An extensible command line tool or library to format yaml files.
Apache License 2.0
1.2k stars 48 forks source link

Feat Request: Option to set and enforce a specific number of line breaks #210

Open badrobit opened 2 months ago

badrobit commented 2 months ago

The current formatter will allow you to keep as many or as few line breaks if they already exist between entries. I was hoping by setting retain_line_breaks_single: true it would also add line breaks if they didn't exist already.

The output of the tool would be more uniform (but cause bigger diffs) if it were to set the number of line breaks and add/remove them until at the user defined (or default) setting.

e.g.

formatter:
  type: basic
  line_breaks: 1 # <-- New Suggested setting

it could default to zero which would remove them all which is the current behavior then when a value is set it would add/trim the found line breaks to align with the user defined value.

Example:

Input:

a: 
    b_a: value
    b_b: value2
    a-b: 
      - x
      - y
      - z
    a-c: 
      - x
      - y
      - z
      -

output:

a:  # I am unsure if a newline after this but before (b_a) makes sense 

    b_a: value
    b_b: value2 # I am unsure if a newline after this but before (a_b) makes sense 

    a_b: 
      - x
      - y
      - z

    a_c: 
      - x
      - y
      - z
braydonk commented 2 months ago

Hi @badrobit thanks for the feature request.

I have had requests for similar features before, but your version sounds a bit different and if I'm understanding correctly is the first I've ever heard of anyone having a use case like this. Do you mean you'd like a feature Like this?
Before:

a: 1
b: 2
c: 3

After:

a: 1

b: 2

c: 3

If so, I suppose I could add something like that but it's definitely the first I've heard of someone wanting something like this.

I have had requests for a feature like retain_max_line_breaks such that with a setting like retain_max_line_breaks: 2 this:

a: 1

b: 2

Would become:

a: 1

b: 2

That feature would be relatively easy to implement, but it sounds different than what you're asking for so I want to make sure.

badrobit commented 2 months ago

I think it is a weird mix (I know why can it not just be simple). I think it would be based on parent grouping so if say you had the following:

a: 
    b_a: value
    b_b: value2
    a-b: 
      - x
      - y
      - z
    a-c: 
      - x
      - y
      - z

you would get the following out (assuming line separation is set to 1:

a:  # I am unsure if a newline after this but before (b_a) makes sense 
    b_a: value
    b_b: value2 # I am unsure if a newline after this but before (a_b) makes sense 
    a_b: 
      - x
      - y
      - z

    a_c: 
      - x
      - y
      - z

Adding in the option with the newlines just to see how it looks (I think I like it more)

a:  # I am unsure if a newline after this but before (b_a) makes sense 

    b_a: value
    b_b: value2 # I am unsure if a newline after this but before (a_b) makes sense 

    a_b: 
      - x
      - y
      - z

    a_c: 
      - x
      - y
      - z

I think what I am asking for is if at each level (with children) it is separated. I think the key part is the children as it would be a bit weird and less readable if you put a line between every entry. The most common example I can think of that I tend to do this with is the .pre-commit-config.yaml where I will add a new line between each repo listed.

Seeing the second option I can see my background from python is clearly having an impact here. I did try to find justification in the YAML spec and this setup would flow with their guide for indentation being a strong indicator of grouping but I couldn't find anything on recommendations for newline spacing.