]>
git.madduck.net Git - etc/vim.git/commitdiff
madduck's git repository
Every one of the projects in this repository is available at the canonical
URL git://git.madduck.net/madduck/pub/<projectpath> — see
each project's metadata for the exact URL.
All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@ git. madduck. net .
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
SSH access, as well as push access can be individually
arranged .
If you use my repositories frequently, consider adding the following
snippet to ~/.gitconfig and using the third clone URL listed for each
project:
[url "git://git.madduck.net/madduck/"]
insteadOf = madduck:
summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
fa7f015 )
Fixes #2588
<!-- Changes that affect Black's preview style -->
<!-- Changes that affect Black's preview style -->
+- Code cell separators `#%%` are now standardised to `# %%` (#2919)
+
### _Blackd_
<!-- Changes to blackd -->
### _Blackd_
<!-- Changes to blackd -->
else:
versions = detect_target_versions(src_node, future_imports=future_imports)
else:
versions = detect_target_versions(src_node, future_imports=future_imports)
- normalize_fmt_off(src_node)
+ normalize_fmt_off(src_node, preview=mode.preview )
lines = LineGenerator(mode=mode)
elt = EmptyLineTracker(is_pyi=mode.is_pyi)
empty_line = Line(mode=mode)
lines = LineGenerator(mode=mode)
elt = EmptyLineTracker(is_pyi=mode.is_pyi)
empty_line = Line(mode=mode)
FMT_PASS: Final = {*FMT_OFF, *FMT_SKIP}
FMT_ON: Final = {"# fmt: on", "# fmt:on", "# yapf: enable"}
FMT_PASS: Final = {*FMT_OFF, *FMT_SKIP}
FMT_ON: Final = {"# fmt: on", "# fmt:on", "# yapf: enable"}
+COMMENT_EXCEPTIONS = {True: " !:#'", False: " !:#'%"}
+
@dataclass
class ProtoComment:
@dataclass
class ProtoComment:
consumed: int # how many characters of the original leaf's prefix did we consume
consumed: int # how many characters of the original leaf's prefix did we consume
-def generate_comments(leaf: LN) -> Iterator[Leaf]:
+def generate_comments(leaf: LN, *, preview: bool ) -> Iterator[Leaf]:
"""Clean the prefix of the `leaf` and generate comments from it, if any.
Comments in lib2to3 are shoved into the whitespace prefix. This happens
"""Clean the prefix of the `leaf` and generate comments from it, if any.
Comments in lib2to3 are shoved into the whitespace prefix. This happens
Inline comments are emitted as regular token.COMMENT leaves. Standalone
are emitted with a fake STANDALONE_COMMENT token identifier.
"""
Inline comments are emitted as regular token.COMMENT leaves. Standalone
are emitted with a fake STANDALONE_COMMENT token identifier.
"""
- for pc in list_comments(leaf.prefix, is_endmarker=leaf.type == token.ENDMARKER):
+ for pc in list_comments(
+ leaf.prefix, is_endmarker=leaf.type == token.ENDMARKER, preview=preview
+ ):
yield Leaf(pc.type, pc.value, prefix="\n" * pc.newlines)
@lru_cache(maxsize=4096)
yield Leaf(pc.type, pc.value, prefix="\n" * pc.newlines)
@lru_cache(maxsize=4096)
-def list_comments(prefix: str, *, is_endmarker: bool) -> List[ProtoComment]:
+def list_comments(
+ prefix: str, *, is_endmarker: bool, preview: bool
+) -> List[ProtoComment]:
"""Return a list of :class:`ProtoComment` objects parsed from the given `prefix`."""
result: List[ProtoComment] = []
if not prefix or "#" not in prefix:
"""Return a list of :class:`ProtoComment` objects parsed from the given `prefix`."""
result: List[ProtoComment] = []
if not prefix or "#" not in prefix:
comment_type = token.COMMENT # simple trailing comment
else:
comment_type = STANDALONE_COMMENT
comment_type = token.COMMENT # simple trailing comment
else:
comment_type = STANDALONE_COMMENT
- comment = make_comment(line)
+ comment = make_comment(line, preview=preview )
result.append(
ProtoComment(
type=comment_type, value=comment, newlines=nlines, consumed=consumed
result.append(
ProtoComment(
type=comment_type, value=comment, newlines=nlines, consumed=consumed
-def make_comment(content: str) -> str:
+def make_comment(content: str, *, preview: bool ) -> str:
"""Return a consistently formatted comment from the given `content` string.
"""Return a consistently formatted comment from the given `content` string.
- All comments (except for "##", "#!", "#:", '#'", "#%%" ) should have a single
+ All comments (except for "##", "#!", "#:", '#'") should have a single
space between the hash sign and the content.
If `content` didn't start with a hash sign, one is provided.
space between the hash sign and the content.
If `content` didn't start with a hash sign, one is provided.
and not content.lstrip().startswith("type:")
):
content = " " + content[1:] # Replace NBSP by a simple space
and not content.lstrip().startswith("type:")
):
content = " " + content[1:] # Replace NBSP by a simple space
- if content and content[0] not in " !:#'%" :
+ if content and content[0] not in COMMENT_EXCEPTIONS[preview] :
content = " " + content
return "#" + content
content = " " + content
return "#" + content
-def normalize_fmt_off(node: Node) -> None:
+def normalize_fmt_off(node: Node, *, preview: bool ) -> None:
"""Convert content between `# fmt: off`/`# fmt: on` into standalone comments."""
try_again = True
while try_again:
"""Convert content between `# fmt: off`/`# fmt: on` into standalone comments."""
try_again = True
while try_again:
- try_again = convert_one_fmt_off_pair(node)
+ try_again = convert_one_fmt_off_pair(node, preview=preview )
-def convert_one_fmt_off_pair(node: Node) -> bool:
+def convert_one_fmt_off_pair(node: Node, *, preview: bool ) -> bool:
"""Convert content of a single `# fmt: off`/`# fmt: on` into a standalone comment.
Returns True if a pair was converted.
"""
for leaf in node.leaves():
previous_consumed = 0
"""Convert content of a single `# fmt: off`/`# fmt: on` into a standalone comment.
Returns True if a pair was converted.
"""
for leaf in node.leaves():
previous_consumed = 0
- for comment in list_comments(leaf.prefix, is_endmarker=False):
+ for comment in list_comments(leaf.prefix, is_endmarker=False, preview=preview ):
if comment.value not in FMT_PASS:
previous_consumed = comment.consumed
continue
if comment.value not in FMT_PASS:
previous_consumed = comment.consumed
continue
if comment.value in FMT_SKIP and prev.type in WHITESPACE:
continue
if comment.value in FMT_SKIP and prev.type in WHITESPACE:
continue
- ignored_nodes = list(generate_ignored_nodes(leaf, comment))
+ ignored_nodes = list(generate_ignored_nodes(leaf, comment, preview=preview ))
if not ignored_nodes:
continue
if not ignored_nodes:
continue
-def generate_ignored_nodes(leaf: Leaf, comment: ProtoComment) -> Iterator[LN]:
+def generate_ignored_nodes(
+ leaf: Leaf, comment: ProtoComment, *, preview: bool
+) -> Iterator[LN]:
"""Starting from the container of `leaf`, generate all leaves until `# fmt: on`.
If comment is skip, returns leaf only.
"""Starting from the container of `leaf`, generate all leaves until `# fmt: on`.
If comment is skip, returns leaf only.
yield leaf.parent
return
while container is not None and container.type != token.ENDMARKER:
yield leaf.parent
return
while container is not None and container.type != token.ENDMARKER:
- if is_fmt_on(container):
+ if is_fmt_on(container, preview=preview ):
return
# fix for fmt: on in children
return
# fix for fmt: on in children
- if contains_fmt_on_at_column(container, leaf.column):
+ if contains_fmt_on_at_column(container, leaf.column, preview=preview ):
for child in container.children:
for child in container.children:
- if contains_fmt_on_at_column(child, leaf.column):
+ if contains_fmt_on_at_column(child, leaf.column, preview=preview ):
container = container.next_sibling
container = container.next_sibling
-def is_fmt_on(container: LN) -> bool:
+def is_fmt_on(container: LN, preview: bool ) -> bool:
"""Determine whether formatting is switched on within a container.
Determined by whether the last `# fmt:` comment is `on` or `off`.
"""
fmt_on = False
"""Determine whether formatting is switched on within a container.
Determined by whether the last `# fmt:` comment is `on` or `off`.
"""
fmt_on = False
- for comment in list_comments(container.prefix, is_endmarker=False):
+ for comment in list_comments(container.prefix, is_endmarker=False, preview=preview ):
if comment.value in FMT_ON:
fmt_on = True
elif comment.value in FMT_OFF:
if comment.value in FMT_ON:
fmt_on = True
elif comment.value in FMT_OFF:
-def contains_fmt_on_at_column(container: LN, column: int) -> bool:
+def contains_fmt_on_at_column(container: LN, column: int, *, preview: bool ) -> bool:
"""Determine if children at a given column have formatting switched on."""
for child in container.children:
if (
"""Determine if children at a given column have formatting switched on."""
for child in container.children:
if (
or isinstance(child, Leaf)
and child.column == column
):
or isinstance(child, Leaf)
and child.column == column
):
+ if is_fmt_on(child, preview=preview ):
"""Default `visit_*()` implementation. Recurses to children of `node`."""
if isinstance(node, Leaf):
any_open_brackets = self.current_line.bracket_tracker.any_open_brackets()
"""Default `visit_*()` implementation. Recurses to children of `node`."""
if isinstance(node, Leaf):
any_open_brackets = self.current_line.bracket_tracker.any_open_brackets()
- for comment in generate_comments(node):
+ for comment in generate_comments(node, preview=self.mode.preview ):
if any_open_brackets:
# any comment within brackets is subject to splitting
self.current_line.append(comment)
if any_open_brackets:
# any comment within brackets is subject to splitting
self.current_line.append(comment)
`parens` holds a set of string leaf values immediately after which
invisible parens should be put.
"""
`parens` holds a set of string leaf values immediately after which
invisible parens should be put.
"""
- normalize_invisible_parens(node, parens_after=parens)
+ normalize_invisible_parens(node, parens_after=parens, preview=self.mode.preview )
for child in node.children:
if is_name_token(child) and child.value in keywords:
yield from self.line()
for child in node.children:
if is_name_token(child) and child.value in keywords:
yield from self.line()
def visit_match_case(self, node: Node) -> Iterator[Line]:
"""Visit either a match or case statement."""
def visit_match_case(self, node: Node) -> Iterator[Line]:
"""Visit either a match or case statement."""
- normalize_invisible_parens(node, parens_after=set())
+ normalize_invisible_parens(node, parens_after=set(), preview=self.mode.preview )
yield from self.line()
for child in node.children:
yield from self.line()
for child in node.children:
-def normalize_invisible_parens(node: Node, parens_after: Set[str]) -> None:
+def normalize_invisible_parens(
+ node: Node, parens_after: Set[str], *, preview: bool
+) -> None:
"""Make existing optional parentheses invisible or create new ones.
`parens_after` is a set of string leaf values immediately after which parens
"""Make existing optional parentheses invisible or create new ones.
`parens_after` is a set of string leaf values immediately after which parens
Standardizes on visible parentheses for single-element tuples, and keeps
existing visible parentheses for other tuples and generator expressions.
"""
Standardizes on visible parentheses for single-element tuples, and keeps
existing visible parentheses for other tuples and generator expressions.
"""
- for pc in list_comments(node.prefix, is_endmarker=False):
+ for pc in list_comments(node.prefix, is_endmarker=False, preview=preview ):
if pc.value in FMT_OFF:
# This `node` has a prefix with `# fmt: off`, don't mess with parens.
return
if pc.value in FMT_OFF:
# This `node` has a prefix with `# fmt: off`, don't mess with parens.
return
# Fixes a bug where invisible parens are not properly stripped from
# assignment statements that contain type annotations.
if isinstance(child, Node) and child.type == syms.annassign:
# Fixes a bug where invisible parens are not properly stripped from
# assignment statements that contain type annotations.
if isinstance(child, Node) and child.type == syms.annassign:
- normalize_invisible_parens(child, parens_after=parens_after)
+ normalize_invisible_parens(
+ child, parens_after=parens_after, preview=preview
+ )
# Add parentheses around long tuple unpacking in assignments.
if (
# Add parentheses around long tuple unpacking in assignments.
if (
--- /dev/null
+# The percent-percent comments are Spyder IDE cells.
+# Both `#%%`` and `# %%` are accepted, so `black` standardises
+# to the latter.
+
+#%%
+# %%
+
+# output
+
+# The percent-percent comments are Spyder IDE cells.
+# Both `#%%`` and `# %%` are accepted, so `black` standardises
+# to the latter.
+
+# %%
+# %%
# string processing
"cantfit",
"comments7",
# string processing
"cantfit",
"comments7",
"long_strings",
"long_strings__edge_case",
"long_strings__regression",
"long_strings",
"long_strings__edge_case",
"long_strings__regression",