summaryrefslogtreecommitdiff
path: root/kitty-graphics.el
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-03-29 07:06:09 +0200
committercashmere <cashmere@autistici.org>2026-03-29 07:06:09 +0200
commitc6e4967b52eacb13360e649cddbaf9afcd6213dc (patch)
treeda25101832ecafe8caf624c44329ab12c222b230 /kitty-graphics.el
parente5ee5bb0e498c66b473e7eecc8c31e29f503d85c (diff)
downloadkitty-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.el49
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)))