yapf icon indicating copy to clipboard operation
yapf copied to clipboard

Adding support for balanced line breaks?

Open danijar opened this issue 2 years ago • 4 comments

YAPF sometime breaks lines in spots that look a bit odd because they result in a very short and a very long line, whereas breaking the long expression at a different (rather than the first) opportunity would look more natural. Would it be feasible to support this in YAPF or if there already a config that could achieve something similar? Thanks a lot!

Example 1

Actual:

donated = {
    k: v
    for k, v in very_long_dict_name.items() if k not in self.copy_keys}

Desired:

donated = {
    k: v for k, v in very_long_dict_name.items()
    if k not in self.copy_keys}

Example 2

Actual:

return str(
    src.source_info_util.summarize(src.source_info_util.current(), 30))

Desired:

return str(src.source_info_util.summarize(
    src.source_info_util.current(), 30))

Configuration

pyproject.toml

[tool.yapf]
based_on_style = "pep8"
indent_width = 2
allow_multiline_lambdas = true
continuation_align_style = "FIXED"
continuation_indent_width = 4
dedent_closing_brackets = false
each_dict_entry_on_separate_line = false
spaces_around_power_operator = true
split_before_closing_bracket = false
split_before_expression_after_opening_paren = true
split_before_first_argument = true
split_before_logical_operator = false

danijar avatar Oct 11 '23 23:10 danijar

For the first one, see if SPLIT_COMPLEX_COMPREHENSION might help. (I think it will still split after the k: v part though.) As for the second example, you might try adjusting SPLIT_PENALTY_AFTER_OPENING_BRACKET. However, it may have other side effects.

bwendling avatar Oct 13 '23 19:10 bwendling

Thanks for the suggestions!

Example 1

With split_complex_comprehension = true, it generates:

donated = {
    k: v
    for k, v in very_long_dict_name.items()
    if k not in self.copy_keys}

I think this looks better. Not ideal, but I assume having a line balancing heuristic (i.e. avoiding very short lines) might be too tricky to consider?

Example 2

I tried different values of split_penalty_after_opening_bracket (default is 300, I tried 1, 100, 1000, 10000). None of those changed the generated output. I think it's probably because both breakpoints (the first one YAPF chooses and the second one that would be desired) are after an opening brackets, so the penalty would be the same either way?

Perhaps the current penalty system would already make it feasible to achieve the desired balancing behavior by adding a small penalty for based on line shortness (i.e. 79 minus line length, summed over all lines in the formatted expression)?

danijar avatar Oct 13 '23 19:10 danijar

@bwendling @Spitfire1900 Is this something you might be able to look into?

danijar avatar May 07 '24 21:05 danijar