diff options
| author | cashmere <cashmere@autistici.org> | 2026-03-29 09:07:06 +0200 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-03-29 09:07:06 +0200 |
| commit | 7691a94d26190324d3f7b6ff22068fa4fc57c121 (patch) | |
| tree | f70d4d917b341116c964996ba66f64e4d7bc3190 | |
| parent | 97f0dbc31d9e7eed6ac3ae3300968a3d231270fe (diff) | |
| download | kitty-graphics-7691a94d26190324d3f7b6ff22068fa4fc57c121.tar.gz | |
fix: Sixel backend parity improvements
Close gaps identified in Sixel vs Kitty audit:
- image-mode: mode-name now shows Image[Sixel] or Image[Kitty]
based on active backend (was hardcoded to Image[Kitty])
- LaTeX preview: docstring updated to reference kitty-graphics
package name, not Kitty protocol specifically
- sixel-cleanup-all: now erases visible Sixel images from terminal
cells before cleaning disk/memory state (prevents pixel artifacts
on mode disable)
- sixel-place: LRU eviction for .six temp files, capped at
kitty-gfx-cache-size (default 64), oldest evicted on overflow
Remaining by-design differences (protocol limitations, not bugs):
- Sixel re-emits raw pixel data on scroll (no placement IDs)
- Sixel erases by overwriting with spaces (no protocol-level delete)
- Sixel detection is env-var based (no DA1 query yet)
| -rw-r--r-- | kitty-graphics.el | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/kitty-graphics.el b/kitty-graphics.el index 60a1e70..f5006fb 100644 --- a/kitty-graphics.el +++ b/kitty-graphics.el @@ -630,7 +630,16 @@ Encodes on-demand if not cached, then emits DCS sequence." (with-temp-file cache-path (set-buffer-multibyte nil) (insert sixel-data))) - (push cache-path kitty-gfx--sixel-temp-files))) + (push cache-path kitty-gfx--sixel-temp-files) + ;; LRU eviction: cap temp files at kitty-gfx-cache-size + (when (> (length kitty-gfx--sixel-temp-files) kitty-gfx-cache-size) + (let ((victim (car (last kitty-gfx--sixel-temp-files)))) + (kitty-gfx--log "sixel-cache-evict: %s (count=%d max=%d)" + victim (length kitty-gfx--sixel-temp-files) + kitty-gfx-cache-size) + (ignore-errors (delete-file victim)) + (setq kitty-gfx--sixel-temp-files + (butlast kitty-gfx--sixel-temp-files)))))) ;; Emit Sixel sequence if we have data (when sixel-data (let* ((cw (or kitty-gfx--cell-pixel-width 8)) @@ -669,9 +678,21 @@ Sixel has no placement IDs — erase by writing spaces over the region." (setq kitty-gfx--sixel-temp-files (delete temp-file kitty-gfx--sixel-temp-files))))) (defun kitty-gfx--sixel-cleanup-all () - "Cleanup all Sixel resources." + "Cleanup all Sixel resources. +Erases visible Sixel images from the terminal before cleaning +disk/memory state, preventing pixel artifacts on mode disable." (kitty-gfx--log "sixel-cleanup-all: deleting %d temp files" (length kitty-gfx--sixel-temp-files)) + ;; Erase visible images from terminal (Sixel has no protocol-level + ;; delete — must overwrite cells with spaces). + (dolist (buf (buffer-list)) + (with-current-buffer buf + (dolist (ov kitty-gfx--overlays) + (when (and (overlay-buffer ov) + (not (overlay-get ov 'kitty-gfx-heading)) + (overlay-get ov 'kitty-gfx-last-row)) + (funcall #'kitty-gfx--sixel-delete ov nil nil))))) + ;; Clean disk cache (dolist (temp-file kitty-gfx--sixel-temp-files) (ignore-errors (delete-file temp-file))) (setq kitty-gfx--sixel-temp-files nil) @@ -2097,8 +2118,9 @@ With prefix ARG \\[universal-argument], clear previews." (defun kitty-gfx--org-latex-preview-advice (orig-fn &optional arg beg end) "Around advice for `org-latex-preview'. Bypasses org's `display-graphic-p' guard so LaTeX fragments are -rendered to images via dvipng/dvisvgm and displayed via Kitty -graphics. The image generation pipeline does not require a GUI." +rendered to images via dvipng/dvisvgm and displayed via +kitty-graphics (works with both Kitty and Sixel backends). +The image generation pipeline does not require a GUI." (if (and kitty-graphics-mode (not (display-graphic-p))) (cond ;; C-u = clear previews in region/subtree @@ -2219,7 +2241,9 @@ Values > 1.0 zoom in, < 1.0 zoom out.") ;; image-mode bindings (which call native image functions ;; that fail in terminal) don't override our keymap. (setq major-mode 'kitty-gfx-image-mode - mode-name "Image[Kitty]") + mode-name (format "Image[%s]" + (pcase kitty-gfx--active-backend + ('kitty "Kitty") ('sixel "Sixel") (_ "GFX")))) (let ((map (make-sparse-keymap))) (set-keymap-parent map special-mode-map) (define-key map (kbd "q") #'kill-current-buffer) |
