X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/44d5da00b520a05cd56e58b3998660f64ea59ebd..a2821815af5f5a706c673279d6405e286d6e95b8:/src/black/linegen.py diff --git a/src/black/linegen.py b/src/black/linegen.py index a2e41bf..644824a 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -2,10 +2,16 @@ Generating lines of code. """ import sys +from enum import Enum, auto from functools import partial, wraps from typing import Collection, Iterator, List, Optional, Set, Union, cast -from black.brackets import COMMA_PRIORITY, DOT_PRIORITY, max_delimiter_priority_in_atom +from black.brackets import ( + COMMA_PRIORITY, + DOT_PRIORITY, + get_leaves_inside_matching_brackets, + max_delimiter_priority_in_atom, +) from black.comments import FMT_OFF, generate_comments, list_comments from black.lines import ( Line, @@ -383,19 +389,18 @@ class LineGenerator(Visitor[Line]): # We need to find the length of the last line of the docstring # to find if we can add the closing quotes to the line without # exceeding the maximum line length. - # If docstring is one line, then we need to add the length - # of the indent, prefix, and starting quotes. Ending quotes are - # handled later. + # If docstring is one line, we don't put the closing quotes on a + # separate line because it looks ugly (#3320). lines = docstring.splitlines() last_line_length = len(lines[-1]) if docstring else 0 - if len(lines) == 1: - last_line_length += len(indent) + len(prefix) + quote_len - # If adding closing quotes would cause the last line to exceed # the maximum line length then put a line break before the # closing quotes - if last_line_length + quote_len > self.mode.line_length: + if ( + len(lines) > 1 + and last_line_length + quote_len > self.mode.line_length + ): leaf.value = prefix + quote + docstring + "\n" + indent + quote else: leaf.value = prefix + quote + docstring + quote @@ -561,6 +566,12 @@ def transform_line( yield line +class _BracketSplitComponent(Enum): + head = auto() + body = auto() + tail = auto() + + def left_hand_split(line: Line, _features: Collection[Feature] = ()) -> Iterator[Line]: """Split line into many lines, starting with the first matching bracket pair. @@ -591,9 +602,15 @@ def left_hand_split(line: Line, _features: Collection[Feature] = ()) -> Iterator if not matching_bracket: raise CannotSplit("No brackets found") - head = bracket_split_build_line(head_leaves, line, matching_bracket) - body = bracket_split_build_line(body_leaves, line, matching_bracket, is_body=True) - tail = bracket_split_build_line(tail_leaves, line, matching_bracket) + head = bracket_split_build_line( + head_leaves, line, matching_bracket, component=_BracketSplitComponent.head + ) + body = bracket_split_build_line( + body_leaves, line, matching_bracket, component=_BracketSplitComponent.body + ) + tail = bracket_split_build_line( + tail_leaves, line, matching_bracket, component=_BracketSplitComponent.tail + ) bracket_split_succeeded_or_raise(head, body, tail) for result in (head, body, tail): if result: @@ -639,9 +656,15 @@ def right_hand_split( tail_leaves.reverse() body_leaves.reverse() head_leaves.reverse() - head = bracket_split_build_line(head_leaves, line, opening_bracket) - body = bracket_split_build_line(body_leaves, line, opening_bracket, is_body=True) - tail = bracket_split_build_line(tail_leaves, line, opening_bracket) + head = bracket_split_build_line( + head_leaves, line, opening_bracket, component=_BracketSplitComponent.head + ) + body = bracket_split_build_line( + body_leaves, line, opening_bracket, component=_BracketSplitComponent.body + ) + tail = bracket_split_build_line( + tail_leaves, line, opening_bracket, component=_BracketSplitComponent.tail + ) bracket_split_succeeded_or_raise(head, body, tail) if ( Feature.FORCE_OPTIONAL_PARENTHESES not in features @@ -715,15 +738,23 @@ def bracket_split_succeeded_or_raise(head: Line, body: Line, tail: Line) -> None def bracket_split_build_line( - leaves: List[Leaf], original: Line, opening_bracket: Leaf, *, is_body: bool = False + leaves: List[Leaf], + original: Line, + opening_bracket: Leaf, + *, + component: _BracketSplitComponent, ) -> Line: """Return a new line with given `leaves` and respective comments from `original`. - If `is_body` is True, the result line is one-indented inside brackets and as such - has its first leaf's prefix normalized and a trailing comma added when expected. + If it's the head component, brackets will be tracked so trailing commas are + respected. + + If it's the body component, the result line is one-indented inside brackets and as + such has its first leaf's prefix normalized and a trailing comma added when + expected. """ result = Line(mode=original.mode, depth=original.depth) - if is_body: + if component is _BracketSplitComponent.body: result.inside_brackets = True result.depth += 1 if leaves: @@ -761,12 +792,24 @@ def bracket_split_build_line( leaves.insert(i + 1, new_comma) break + leaves_to_track: Set[LeafID] = set() + if ( + Preview.handle_trailing_commas_in_head in original.mode + and component is _BracketSplitComponent.head + ): + leaves_to_track = get_leaves_inside_matching_brackets(leaves) # Populate the line for leaf in leaves: - result.append(leaf, preformatted=True) + result.append( + leaf, + preformatted=True, + track_bracket=id(leaf) in leaves_to_track, + ) for comment_after in original.comments_after(leaf): result.append(comment_after, preformatted=True) - if is_body and should_split_line(result, opening_bracket): + if component is _BracketSplitComponent.body and should_split_line( + result, opening_bracket + ): result.should_split_rhs = True return result