| 252 | ## cached metadata to speed up screen refreshes |
| 253 | @dataclass |
| 254 | class RefreshCache: |
| 255 | in_bracketed_paste: bool = False |
| 256 | screen: list[str] = field(default_factory=list) |
| 257 | screeninfo: list[tuple[int, list[int]]] = field(init=False) |
| 258 | line_end_offsets: list[int] = field(default_factory=list) |
| 259 | pos: int = field(init=False) |
| 260 | cxy: tuple[int, int] = field(init=False) |
| 261 | dimensions: tuple[int, int] = field(init=False) |
| 262 | invalidated: bool = False |
| 263 | |
| 264 | def update_cache(self, |
| 265 | reader: Reader, |
| 266 | screen: list[str], |
| 267 | screeninfo: list[tuple[int, list[int]]], |
| 268 | ) -> None: |
| 269 | self.in_bracketed_paste = reader.in_bracketed_paste |
| 270 | self.screen = screen.copy() |
| 271 | self.screeninfo = screeninfo.copy() |
| 272 | self.pos = reader.pos |
| 273 | self.cxy = reader.cxy |
| 274 | self.dimensions = reader.console.width, reader.console.height |
| 275 | self.invalidated = False |
| 276 | |
| 277 | def valid(self, reader: Reader) -> bool: |
| 278 | if self.invalidated: |
| 279 | return False |
| 280 | dimensions = reader.console.width, reader.console.height |
| 281 | dimensions_changed = dimensions != self.dimensions |
| 282 | paste_changed = reader.in_bracketed_paste != self.in_bracketed_paste |
| 283 | return not (dimensions_changed or paste_changed) |
| 284 | |
| 285 | def get_cached_location(self, reader: Reader) -> tuple[int, int]: |
| 286 | if self.invalidated: |
| 287 | raise ValueError("Cache is invalidated") |
| 288 | offset = 0 |
| 289 | earliest_common_pos = min(reader.pos, self.pos) |
| 290 | num_common_lines = len(self.line_end_offsets) |
| 291 | while num_common_lines > 0: |
| 292 | offset = self.line_end_offsets[num_common_lines - 1] |
| 293 | if earliest_common_pos > offset: |
| 294 | break |
| 295 | num_common_lines -= 1 |
| 296 | else: |
| 297 | offset = 0 |
| 298 | return offset, num_common_lines |
| 299 | |
| 300 | last_refresh_cache: RefreshCache = field(default_factory=RefreshCache) |
| 301 | |