diff --git a/src/textual/content.py b/src/textual/content.py index 3d3c370b78..f8c6f34d7a 100644 --- a/src/textual/content.py +++ b/src/textual/content.py @@ -523,12 +523,15 @@ def add_spans(self, spans: Sequence[Span]) -> Content: ) return self - def draws_like(self, other: Content) -> bool: + def draws_like(self, other: Visual) -> bool: """Whether both draw the same: the same text with the same styled spans. Equality compares text only, for sorting; a changed style or link is a change on screen. """ - return self.plain == other.plain and list(self._spans) == list(other._spans) + return other.draws_text(self.plain, self._spans) + + def draws_text(self, plain: str, spans: Sequence[object]) -> bool: + return self.plain == plain and list(self._spans) == list(spans) def __eq__(self, other: object) -> bool: """Compares text only, so that markup doesn't effect sorting.""" diff --git a/src/textual/visual.py b/src/textual/visual.py index 086f51cfc8..5621c12a48 100644 --- a/src/textual/visual.py +++ b/src/textual/visual.py @@ -1,6 +1,7 @@ from __future__ import annotations from abc import ABC, abstractmethod +from collections.abc import Sequence from dataclasses import dataclass from itertools import islice from typing import TYPE_CHECKING, Callable, Protocol @@ -138,6 +139,14 @@ def selected_text(visual, selection): return selection.extract(str(visual)), "\n" return None + def draws_like(self, other: Visual) -> bool: + """Whether both draw the same. A visual that cannot tell answers no, so it redraws.""" + return False + + def draws_text(self, plain: str, spans: Sequence[object]) -> bool: + """Whether this draws exactly this text with these styled spans; only content can.""" + return False + @abstractmethod def render_strips( self, width: int, height: int | None, style: Style, options: RenderOptions