|
10 | 10 | from pathlib import Path
|
11 | 11 | from typing import Collection, Generator, List, Tuple
|
12 | 12 |
|
| 13 | +from black.comments import FMT_SKIP |
| 14 | + |
13 | 15 | from darker.black_diff import (
|
14 | 16 | BlackConfig,
|
15 | 17 | filter_python_files,
|
@@ -191,15 +193,63 @@ def _blacken_single_file( # pylint: disable=too-many-arguments,too-many-locals
|
191 | 193 | """
|
192 | 194 | absolute_path_in_rev2 = root / relative_path_in_rev2
|
193 | 195 |
|
| 196 | + # find the fmt_skip comment that won't conflict with the code |
| 197 | + fmt_skip = None |
| 198 | + for comment in FMT_SKIP: |
| 199 | + if comment not in rev2_isorted.string: |
| 200 | + fmt_skip = comment |
| 201 | + if fmt_skip is None: |
| 202 | + logger.warning( |
| 203 | + "Detected the mixed styles of `# fmt: skip` comments in " |
| 204 | + f"{absolute_path_in_rev2}, " |
| 205 | + "please use one style to get the best result" |
| 206 | + ) |
| 207 | + # decorate lines with fmt_skip |
| 208 | + lines = [] |
| 209 | + modified_line_nums = edited_linenums_differ.revision_vs_lines( |
| 210 | + relative_path_in_repo, rev2_isorted, 0 |
| 211 | + ) |
| 212 | + for i, line in enumerate(rev2_isorted.lines): |
| 213 | + line_num = i + 1 |
| 214 | + if ( |
| 215 | + fmt_skip is not None |
| 216 | + and line_num not in modified_line_nums |
| 217 | + and not any(f in line for f in FMT_SKIP) |
| 218 | + ): |
| 219 | + line = f"{line} {fmt_skip}" |
| 220 | + lines.append(line) |
| 221 | + rev2_isorted_decorated = TextDocument.from_lines( |
| 222 | + lines, |
| 223 | + encoding=rev2_isorted.encoding, |
| 224 | + newline=rev2_isorted.newline, |
| 225 | + mtime=rev2_isorted.mtime, |
| 226 | + ) |
| 227 | + |
194 | 228 | # 4. run black
|
195 |
| - formatted = run_black(rev2_isorted, black_config) |
| 229 | + formatted = run_black(rev2_isorted_decorated, black_config) |
196 | 230 | logger.debug(
|
197 | 231 | "Read %s lines from edited file %s",
|
198 |
| - len(rev2_isorted.lines), |
| 232 | + len(rev2_isorted_decorated.lines), |
199 | 233 | absolute_path_in_rev2,
|
200 | 234 | )
|
201 | 235 | logger.debug("Black reformat resulted in %s lines", len(formatted.lines))
|
202 | 236 |
|
| 237 | + # redecorate lines without fmt_skip |
| 238 | + lines = [] |
| 239 | + for line in formatted.lines: |
| 240 | + if fmt_skip is not None: |
| 241 | + if line.endswith(f" {fmt_skip}"): |
| 242 | + line = line[: -len(f" {fmt_skip}")] |
| 243 | + elif line == fmt_skip: |
| 244 | + line = "" |
| 245 | + lines.append(line) |
| 246 | + formatted = TextDocument.from_lines( |
| 247 | + lines, |
| 248 | + encoding=formatted.encoding, |
| 249 | + newline=formatted.newline, |
| 250 | + mtime=formatted.mtime, |
| 251 | + ) |
| 252 | + |
203 | 253 | # 5. get the diff between the edited and reformatted file
|
204 | 254 | # 6. convert the diff into chunks
|
205 | 255 | black_chunks = diff_chunks(rev2_isorted, formatted)
|
|
0 commit comments