diff options
| author | cashmere <cashmere@autistici.org> | 2026-03-29 07:06:09 +0200 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-03-29 07:06:09 +0200 |
| commit | c6e4967b52eacb13360e649cddbaf9afcd6213dc (patch) | |
| tree | da25101832ecafe8caf624c44329ab12c222b230 /kitty-graphics.el | |
| parent | e5ee5bb0e498c66b473e7eecc8c31e29f503d85c (diff) | |
| download | kitty-graphics-c6e4967b52eacb13360e649cddbaf9afcd6213dc.tar.gz | |
feat: nuke-and-repaint for fold/unfold heading cleanup
Add heading-aware org-cycle handling:
- kitty-gfx--nuke-headings: erases ALL heading multicell blocks
in the current buffer, clearing their cached positions. This
is the "nuke" phase — a clean slate for the terminal.
- kitty-gfx--on-org-cycle: now handles both image and heading
overlays. Images get their placements deleted (existing logic),
headings get their multicell blocks erased (nuke phase).
The subsequent scheduled refresh is the "repaint" phase:
kitty-gfx--overlay-screen-pos checks in-folded-region-p, so
folded headings return nil and won't be re-emitted, while
visible headings get fresh OSC 66 emission at correct positions.
The nuke-and-repaint strategy avoids incremental erase complexity
(which failed in two prior prototypes) by simply erasing everything
and letting the refresh cycle figure out what's still visible.
Diffstat (limited to 'kitty-graphics.el')
| -rw-r--r-- | kitty-graphics.el | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/kitty-graphics.el b/kitty-graphics.el index 4d26d04..5195238 100644 --- a/kitty-graphics.el +++ b/kitty-graphics.el @@ -1896,23 +1896,52 @@ the terminal supports text sizing." (not (display-graphic-p))) (kitty-gfx--org-apply-heading-sizes))) +(defun kitty-gfx--nuke-headings () + "Erase all heading multicell blocks in the current buffer. +The `nuke' phase of nuke-and-repaint: erases every heading overlay's +multicell block at its cached terminal position, then clears the +cache. The subsequent refresh cycle handles the `repaint' phase, +re-emitting OSC 66 only for headings that are still visible +\(not inside a fold)." + (let ((count 0)) + (dolist (ov kitty-gfx--overlays) + (when (and (overlay-get ov 'kitty-gfx-heading) + (overlay-buffer ov) + (overlay-get ov 'kitty-gfx-last-row)) + (kitty-gfx--erase-heading ov) + (overlay-put ov 'kitty-gfx-last-row nil) + (overlay-put ov 'kitty-gfx-last-col nil) + (cl-incf count))) + (when (> count 0) + (kitty-gfx--log "nuke-headings: erased %d heading blocks" count)) + count)) + (defun kitty-gfx--on-org-cycle (&rest _args) "Handle org visibility cycling. -Deletes image placements from the terminal, clears position caches, -then schedules a refresh that re-places only the overlays that are -still visible (not inside a fold)." +Deletes image placements and erases heading multicell blocks from +the terminal, clears position caches, then schedules a refresh +that re-places only the overlays that are still visible (not +inside a fold). Heading overlays use nuke-and-repaint: erase all, +then let the refresh cycle re-emit the visible ones." (kitty-gfx--log "on-org-cycle: overlays=%d" (length kitty-gfx--overlays)) - (when (and kitty-graphics-mode kitty-gfx--overlays kitty-gfx--active-backend) + (when (and kitty-graphics-mode kitty-gfx--overlays) (kitty-gfx--sync-begin) (unwind-protect (dolist (ov kitty-gfx--overlays) (when (overlay-buffer ov) - (let ((id (overlay-get ov 'kitty-gfx-id)) - (pid (overlay-get ov 'kitty-gfx-pid))) - (when (and id pid) - (funcall (kitty-gfx--backend-fn 'delete) ov id pid))) - (overlay-put ov 'kitty-gfx-last-row nil) - (overlay-put ov 'kitty-gfx-last-col nil))) + (if (overlay-get ov 'kitty-gfx-heading) + ;; Heading overlay — erase multicell block (nuke phase) + (when (overlay-get ov 'kitty-gfx-last-row) + (kitty-gfx--erase-heading ov) + (overlay-put ov 'kitty-gfx-last-row nil) + (overlay-put ov 'kitty-gfx-last-col nil)) + ;; Image overlay — delete terminal placement + (let ((id (overlay-get ov 'kitty-gfx-id)) + (pid (overlay-get ov 'kitty-gfx-pid))) + (when (and id pid kitty-gfx--active-backend) + (funcall (kitty-gfx--backend-fn 'delete) ov id pid))) + (overlay-put ov 'kitty-gfx-last-row nil) + (overlay-put ov 'kitty-gfx-last-col nil)))) (kitty-gfx--sync-end)) (kitty-gfx--schedule-refresh))) |
