| 145 | |
| 146 | |
| 147 | def _fmt_text_diff(old_text: object, new_text: object, indent: str) -> str | None: |
| 148 | old_lines = str(old_text).splitlines(keepends=True) |
| 149 | new_lines = str(new_text).splitlines(keepends=True) |
| 150 | diff = list(difflib.unified_diff(old_lines, new_lines, n=1)) |
| 151 | if not diff: |
| 152 | return None |
| 153 | out: list[str] = [] |
| 154 | for line in diff[2:]: |
| 155 | if line.startswith("@@"): |
| 156 | continue |
| 157 | text = line[1:].rstrip("\n") |
| 158 | if line.startswith("-"): |
| 159 | out.append(f"{_RED}{indent}- {text}{_RESET}") |
| 160 | elif line.startswith("+"): |
| 161 | out.append(f"{_GREEN}{indent}+ {text}{_RESET}") |
| 162 | else: |
| 163 | out.append(f"{_DIM}{indent} {text}{_RESET}") |
| 164 | blank = f"{_DIM}{indent} {_RESET}" |
| 165 | while out and out[0] == blank: |
| 166 | out.pop(0) |
| 167 | while out and out[-1] == blank: |
| 168 | out.pop() |
| 169 | return "\n".join(out) |
| 170 | |
| 171 | |
| 172 | def _option_detail_lines(opt: object, prefix: str = "", color: str = "") -> list[str]: |