summaryrefslogtreecommitdiff
path: root/kitty-graphics.el
Commit message (Collapse)AuthorAgeFilesLines
* Revert "Merge pull request #16 from timfel/master"HEADmastercashmere2026-04-301-430/+95
| | | | | This reverts commit 308fc78775058d583449b6ffcdc227cf7f1280af, reversing changes made to 632b33b6ecbc3e2a7c8277effcac9b2de0fff5a9.
* Merge pull request #16 from timfel/mastercashmeredev2026-04-301-95/+430
|\ | | | | Fix multiple issues with Sixel
| * Track image placements per windowTim Felgentreff2026-04-291-43/+122
| | | | | | | | | | | | A buffer can be visible in more than one window. With one last-row/last-col and one placement ID per overlay, refreshing the second window overwrites the placement state for the first. After C-x 0, the closed pane's terminal image can no longer be addressed and remains as an artifact. Record image placement geometry and placement IDs per live window. Refresh and cleanup now delete the placement for the specific window, while existing last-row/last-col properties mirror the window currently being refreshed for backend compatibility.
| * Delete image placements before window rerendersTim Felgentreff2026-04-291-27/+53
| | | | | | | | | | | | Window layout changes move image overlays before kitty-graphics recalculates terminal positions. Clearing last-row/last-col first loses the only geometry the backends can use to delete the old terminal placement, which leaves stale pixels over new split separators. Delete the current recorded image placement during window-change handling before clearing the cached position. Also make image-mode placement reuse explicit: zoom commands still reuse a PID to avoid flicker, while split/resize rerenders delete first.
| * Render doc-view pages without mutating PDF buffersTim Felgentreff2026-04-291-9/+26
| | | | | | | | | | | | | | | | | | | | | | Terminal doc-view rendering used to erase and insert padding/newlines into the doc-view buffer before placing the page image. doc-view buffers visit the original PDF, so changing buffer text marks the document modified and can corrupt it if saved. Create the Kitty/Sixel page overlay over the existing buffer contents instead. Compute the page image dimensions, prepare/cache the page image, and schedule a refresh without changing the visited PDF bytes.
| * Handle doc-view image navigation in terminalsTim Felgentreff2026-04-291-1/+193
| | | | | | | | | | | | When kitty-graphics renders doc-view pages in a terminal, doc-view still calls image-mode navigation helpers for scrolling and edge movement. Those helpers expect an Emacs image display and can error or do nothing in the terminal renderer. Add terminal-only doc-view advice for the image navigation functions so they update window hscroll/vscroll and schedule a graphics refresh instead.
| * Fix overlay position mapping in split windowsTim Felgentreff2026-04-291-26/+46
| | | | | | | | | | | | | | | | | | | | | | Compute overlay screen positions in the window currently being refreshed instead of choosing an arbitrary window that shows the same buffer. This keeps placements correct when a buffer is visible in more than one pane. Also derive the terminal column from the overlay's buffer column rather than posn-col-row. In terminal Emacs, posn-col-row can describe the right edge of display-property text instead of the logical overlay start, which makes Sixel placements appear to the right of their reserved cells.
| * Guard Sixel cleanup against nil filesTim Felgentreff2026-04-291-7/+8
| | | | | | | | | | | | | | | | kitty-gfx--sixel-cleanup can be called without a file when cleanup is routed through generic backend code. In that case the old implementation passed nil to md5 while pruning cached Sixel temp files. Make the cleanup a no-op when FILE is nil.
* | fix(detect): read terminal env from frame for emacs --daemon (#15)unship2026-04-301-17/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `kitty-gfx--kitty-detect' and `kitty-gfx--sixel-detect' read TERM, TERM_PROGRAM, TMUX, KITTY_PID, and the WT_* markers via `(getenv VAR)' -- the process-level lookup. Under `emacs --daemon' / `emacsclient -t', the daemon process inherits the launcher's env (often `TERM=dumb' from a systemd unit, no TMUX, no TERM_PROGRAM); the *attached client* env lives on the new frame's `environment' parameter. As a result, every detect call sees daemon env and reports "terminal not supported" even when the client is attached from a fully sixel-/kitty-capable terminal inside tmux. Note `(getenv VAR FRAME)' only consults the frame env (no process fallback), and `(getenv VAR)' only consults the process env first (then the *selected* frame's env). Neither alone gives the desired prefer-frame-then-process semantics. Add a small helper `kitty-gfx--frame-getenv' that does, and route both detect functions plus `kitty-gfx--tmux-sixel-supported-p' through it. For TERM specifically also consult the frame's `tty-type' parameter, which is set by `server-create-tty-frame' and is the canonical TERM emacs uses for this frame -- preferred over the env value when the latter is missing or `dumb'. Repro before this patch (Linux, ghostty + tmux, emacs daemon): *kitty-gfx-debug*: kitty-detect: nil (KITTY_PID=nil TERM_PROGRAM=tmux) sixel-detect: nil (TERM=dumb TERM_PROGRAM=tmux TMUX=yes tmux-ver=3.6 tmux-ok=yes WT=no) mode: terminal not supported, aborting enable After the patch the detectors read the frame env, so TERM resolves to the actual `tmux-256color' / `xterm-kitty' / etc. and the matching backend is picked. Behaviour unchanged for non-daemon emacs: when the frame has no `environment' parameter, `kitty-gfx--frame-getenv' falls back to the process env directly.
* | fix(sixel): accept tmux/screen TERM when tmux forwards Sixel (#14)unship2026-04-301-0/+6
|/ | | | | | | | | | | | | | | | | | | | | `kitty-gfx--sixel-detect' currently gates on the outer TERM matching `xterm|vt[0-9]|foot|contour'. Once `tmux-ok' has confirmed tmux >= 3.4, tmux itself owns the Sixel rendering -- the DCS payload never reaches the outer terminal. At that point the outer TERM regex is irrelevant, but the canonical tmux assignment `tmux-256color' (and the legacy `screen-256color') still trip the check, and detection returns nil even when Sixel works fine. Accept `tmux*' and `screen*' TERMs when `tmux-ok' is true. Outside tmux the existing regex still rules, so no behavioural change for non-tmux setups. Repro before this patch: TERM=tmux-256color emacs -nw -Q -l kitty-graphics.el \ --eval '(setq kitty-gfx-debug t)' \ --eval '(kitty-graphics-mode 1)' => "Kitty graphics: terminal not supported" *kitty-gfx-debug*: sixel-detect: nil (TERM=tmux-256color ... tmux-ok=yes)
* chore: bump version to 0.5.0 + write 0.5.0 changelogcashmere2026-04-261-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | Bumps `;; Version:' header from 0.4.0 to 0.5.0 and AGENTS.md `Current version' to match (it was still 0.3.0; missed at the 0.4.0 bump). Per AGENTS.md versioning rules, minor (0.x.0) is the right step for new features, and 0.5.0 collects: - Typst inline equation preview (#5) - Configurable Sixel encoder + per-invocation timeout (refs #4) - Sixel inside tmux >= 3.4 (refs #2) - Windows Terminal detection + GIF routing (closes #6) - Inline mpv video playback on the Kitty backend - Loud warning when the Sixel backend cannot find an encoder on PATH Plus assorted fixes (ECH erase + pre-erase, heading folded-line skip, Sixel parity, text sizing column guard / CPU / preview-mode), the new `justfile' task runner, and documentation that hard-states img2sixel as the recommended Sixel encoder. CHANGELOG.org gets a new top-level section with the full feature write-ups, bench numbers for the encoder swap, credits to @timfel (encoder timeout pattern + Windows Terminal patch + ongoing Sixel collaboration), and a reworded "what comes next" paragraph that reflects the Sixel-in-tmux side as done while leaving Kitty APC passthrough on the roadmap.
* fix(sixel): detect Windows Terminal and route GIFs through image pipelinecashmere2026-04-261-5/+14
| | | | | | | | | | | | | | | | | | Windows Terminal does not expose a stable `TERM' value, so the previous sixel-detect check missed it. Accept the `WT_SESSION', `WT_PROFILE_ID' and `WT_WINDOWID' environment markers it injects into every session. Also add `gif' to `kitty-gfx--image-file-p' so GIF files are routed through the image pipeline. Animation is still not supported -- only the first frame is rendered -- but that is better than dropping them on the floor. AGENTS.md: list Windows Terminal under supported sixel terminals and soften the GIF wording from "not supported" to "first frame only". Closes #6. Co-authored-by: Tim Felgentreff <timfel@users.noreply.github.com>
* docs(sixel): hard-state img2sixel as the recommended encoder + warn loudly ↵cashmere2026-04-261-0/+13
| | | | | | | | | | | | | | | | | | | | | | | | | when none is on PATH Users hit a silent-failure mode where `kitty-gfx--sixel-detect' returned true (terminal supports Sixel) but no encoder was on `PATH', so every `sixel-place' logged `no encoder found' and produced no image. The echo-area `message' from `sixel-encode' was easy to miss inside tmux, which made the issue look like a refresh / tmux passthrough bug. - README.org: Requirements section now explicitly lists a Sixel encoder as required and recommends `img2sixel' (libsixel) over ImageMagick, with the concrete numbers from PR #10's bench (~2.2x smaller payload, ~10x faster) and a note that this matters most inside tmux because every refresh re-emits the full DCS payload. Known-Limitations reworded: missing encoder = silent failure surfaced via the debug log. - AGENTS.md: Dependencies block reorganised the same way; adds a pointer to `just sixel-encoder' as the first step when diagnosing Sixel rendering bugs. - kitty-graphics.el: when the active backend is Sixel and `kitty-gfx--sixel-resolve-encoder' returns nil at mode-enable time, fire a `display-warning' (`*Warnings*' buffer + visible message) pointing at img2sixel/ImageMagick, so the failure is no longer buried in /tmp/kitty-gfx.log.
* feat(tmux): unlock Sixel backend inside tmux >= 3.4cashmere2026-04-261-4/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Sixel detection used to hard-disable the moment `$TMUX' was set. That guard predates tmux 3.4 (released 2024-02-13), which ships native Sixel rendering, so we were rejecting a working configuration. Drop the hard guard, gate on a parsed `tmux -V' >= 3.4, and let users opt out via a new custom var. - `kitty-gfx-tmux-allow-sixel' (default t). Set to nil if your tmux build lacks `--enable-sixel' or if you want to avoid the upstream scroll artifact (tmux's cell buffer is not pixel-aware, so images may persist after scrolling). - `kitty-gfx--tmux-version' parses `tmux -V' once per session and caches the result in `kitty-gfx--tmux-version-cache' (with an `unset' sentinel so we can distinguish "not probed" from "no tmux"). - `kitty-gfx--tmux-sixel-supported-p' centralises the (in-tmux + opt-in + version >= 3.4) check. - `kitty-gfx--sixel-detect' now uses the helper instead of `(not in-tmux)'. Debug log gained `tmux-ver=' and `tmux-ok='. - AGENTS.md / README.org / CHANGELOG.org: limitation reworded from "no tmux support" to a partial entry that explains exactly what works and what the remaining caveats are (Kitty APC passthrough is still unimplemented; scroll artifacts are upstream). - justfile: new `test-sixel-tmux' recipe wraps `test-sixel-image' in `tmux new-session' for one-command interactive verification, and the sibling `test-sixel-image' recipe was switched from a fragile shell conditional to an elisp `when' so passing an encoder argument no longer breaks the parse. Refs #2.
* feat(sixel): configurable encoder + per-invocation timeoutcashmere2026-04-261-17/+123
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Sixel encoding was hard-coded to ImageMagick (`magick'/`convert') with no timeout, so a malformed image or hung encoder could freeze Emacs and users could not switch to libsixel's faster `img2sixel'. - New customs: `kitty-gfx-sixel-encoder-program' (nil = auto-detect: prefer img2sixel, then magick, then convert), `-encoder-args' (extra args list), `-encoder-timeout' (float seconds, default 5.0, nil = no timeout). - New helper `kitty-gfx--sixel-resolve-encoder' returns (KIND . ABS-PATH) where KIND is `img2sixel' or `imagemagick' so the encode pipeline can build the right argv (`-w/-h <px>' vs `-geometry WxH sixel:-'). - New helper `kitty-gfx--sixel-run-encoder' runs the encoder via `make-process' with a separate stderr buffer and a `run-at-time' watchdog that kills the process on timeout; failures and timeouts are logged and surface as nil from `kitty-gfx--sixel-encode' rather than freezing Emacs. - Existing magick/convert path preserved and still chosen automatically when img2sixel is absent. - AGENTS.md: dependency note updated to mention img2sixel and the new customs. Inspired by and co-authored with @timfel's sixel-graphics.el fork (https://github.com/timfel/sixel-graphics.el), which introduced the configurable encoder + timeout pattern. Refs #4. Co-authored-by: Tim Felgentreff <timfel@users.noreply.github.com>
* feat: add typst inline equation previewcashmere2026-04-261-0/+151
| | | | | | | | | | | | | | | | | | | | | Mirrors the existing LaTeX fragment integration but uses the `typst` CLI to compile `$...$' math fragments into PNGs that are then displayed inline through the existing kitty-graphics overlay pipeline. - New section in kitty-graphics.el: customs (typst-command, ppi, text-size, preamble), SHA-1 cached PNGs under /tmp/kitty-gfx-typst, Emacs face-foreground -> typst rgb() hex conversion. - Two autoloaded commands: `kitty-gfx-typst-preview' and `kitty-gfx-typst-clear-preview', region-aware. - Regex skips backslash-escaped dollars (\\$not math\\$). - justfile with recipes: compile/lint/load + per-feature test-* and headless typst-render / typst-show. - tests/test-typst.typ fixture with inline, display, mixed and edge-case fragments. - AGENTS.md updated: test instructions, dependency note, issue marked done. Closes #7. Parent #5.
* feat: add inline mpv video playback via Kitty graphics protocolcashmere2026-04-031-3/+253
| | | | | | | | | | | | | | Spawn mpv with --vo=kitty to paint video frames into a terminal region that Emacs controls. Emacs reserves overlay space and coordinates mpv's screen position via JSON IPC on scroll/resize. New public API: - kitty-gfx-play-video: play video file inline at point - kitty-gfx-stop-video: stop playback and cleanup - kitty-gfx-toggle-video: pause/resume Requires: mpv with --vo=kitty support, Kitty terminal. Gated behind kitty-gfx-enable-video defcustom (nil by default).
* fix: text sizing rendering — column guard, CPU optimization, preview modecashmere2026-04-021-52/+132
| | | | | | | | | | | | | | | | | | | | | | | | | Remove hardcoded column-1 guard that broke heading placement with display-line-numbers-mode and org-indent-mode. Headings were never placed (placed=0 hidden=37) because posn-at-point returns terminal columns offset by body-left, not buffer column 1. CPU optimizations reduce position queries by 86% and heading placements by 76%: - Early window-range exit skips posn-at-point for off-screen overlays - Emitted flag prevents redundant OSC 66 re-emission - Single fold-check instead of duplicate calls - Strip text properties to prevent org-modern payload corruption Add preview mode that temporarily disables conflicting minor modes (org-modern, org-appear, org-indent, visual-line, olivetti) and unfolds all headings for clean OSC 66 rendering. Modes are restored when heading sizes are toggled off. Add row-based collision detection to prevent overlapping multicell blocks when adjacent headings occupy the same terminal rows. Deferred display property shows heading text as fallback until first successful OSC 66 emission, preventing invisible headings.
* fix: Sixel backend parity improvementscashmere2026-03-291-5/+29
| | | | | | | | | | | | | | | | | | | 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)
* fix: skip heading rendering when folded to same visual linecashmere2026-03-291-2/+9
| | | | | | | | | | | | | | | | | | | | When org folds headings (S-TAB overview mode), the newline after each heading becomes invisible, causing multiple headings to appear on the same visual line. posn-at-point then reports col > 1 for headings that follow the fold ellipsis of a previous heading. Placing scaled text at col > 1 causes horizontal drift — headings rendered mid-line overlapping with fold ellipsis and each other. Fix: org headings always start at buffer column 0. If the computed terminal column is not 1, the heading is in a folded context where rendering at scale would be wrong. Skip it (treat as not visible), erase any previous placement, and let the refresh cycle re-place it when unfolded. Root cause identified via debug log analysis showing: Before fold: all headings at col=1 (correct) After S-TAB: headings at col=21/24 on same row (wrong)
* fix: use ECH erase + pre-erase pattern from mdfriedcashmere2026-03-291-13/+39
| | | | | | | | | | | | | | | | | Replace space-writing erase with ECH escape (\e[NX) which erases characters at the cursor without moving it — more efficient and cleaner terminal state. Changes: - kitty-gfx--erase-heading-at: new low-level function using ECH, disables DECAWM during erase to prevent wrapping artifacts, erases all rows of multicell blocks (not just topmost) - kitty-gfx--erase-heading: now delegates to erase-heading-at - kitty-gfx--place-heading: pre-erases target area before emitting OSC 66, preventing ghost artifacts from partial overwrites Adapted from mdfried's "erase-character dance" pattern which erases the full multicell area using ECH before every OSC 66 emission.
* chore: bump to 0.4.0, extend debug-state for headingscashmere2026-03-291-7/+16
| | | | | | | | - Version bump 0.3.0 → 0.4.0 (text sizing feature complete) - kitty-gfx-debug-state: show text-sizing-support status in header, distinguish heading vs image overlays, display heading-specific properties (text, scale, level, cell-s) instead of image properties (id, pid, file)
* feat: nuke-and-repaint for fold/unfold heading cleanupcashmere2026-03-291-10/+39
| | | | | | | | | | | | | | | | | | | 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.
* feat: heading-aware scroll and buffer-change handlingcashmere2026-03-291-10/+26
| | | | | | | | | | | | | | | | | | Fix scroll/buffer-switch behavior for heading overlays: - on-window-change: preserve heading overlay position caches (images clear theirs for re-placement, but headings need old→new comparison to erase multicell blocks properly) - on-buffer-change: erase heading multicell blocks when their buffer becomes hidden, preventing ghost artifacts if the new buffer's content doesn't fully overwrite the heading cells - on-buffer-change: preserve heading caches for visible buffers (same rationale as on-window-change) The existing two-phase refresh already handles scroll correctly: phase 1 detects position changes and erases moved headings, phase 2 re-emits all visible headings. These fixes ensure the cache state is correct for that comparison to work.
* feat: emit OSC 66 for heading overlayscashmere2026-03-291-5/+325
| | | | | | | | | | | | | | | | | | | | | | | Add the OSC 66 emission pipeline (Step 5 of incremental plan): - kitty-gfx--place-heading: emits \e]66;s=S:n=N:d=D;TEXT\a with SGR bold + 24-bit foreground color at cached terminal position - kitty-gfx--erase-heading: erases multicell blocks by writing spaces at the topmost row (overwrite Rules 2-3) - kitty-gfx--refresh-heading-overlay: phase 1 computes position, erases on move/hide, caches new position (no emission) - kitty-gfx--emit-heading-overlays: phase 2 walks all buffers, emits OSC 66 for visible heading overlays after all posn-at-point queries complete (prevents redraw-induced multicell destruction) Two-phase refresh in kitty-gfx--refresh: phase 1 (walk-windows) does position queries and image placements, phase 2 (after loop) emits all heading OSC 66 sequences. Both phases run inside synchronized output (BSU/ESU) to prevent flicker. Also adds org-mode integration hooks (heading-modified debounce, org-mode-hook for auto-apply, heading scan/remove commands) and self-tests for place-heading and erase-heading in dry-run mode.
* feat: add OSC 66 text sizing protocol detectioncashmere2026-03-291-5/+95
| | | | | | | | | | - Add kitty-gfx--query-text-sizing-support using CPR probing (3 cursor position reports interleaved with OSC 66 tests) - Detect scale, width-only, or no support - Wire detection into kitty-graphics-mode enable (Kitty backend only) - Reset detection cache on mode disable - Update modeline lighter: KittyGfx[K+T] when text sizing available - Update enable message to mention text sizing when detected
* feat: add dry-run mode, scale decomposition, and self-test infrastructurecashmere2026-03-291-26/+173
| | | | | | | | | | | | | - Add kitty-gfx--dry-run variable and kitty-gfx--terminal-send wrapper that routes all terminal escape output through a single function, logging sequences in dry-run mode for batch debugging - Replace 9 bare send-string-to-terminal call sites with wrapper - Add kitty-gfx--decompose-scale for OSC 66 parameter computation - Add kitty-gfx--validate-osc66 for protocol param validation - Add kitty-gfx--heading-sgr for org-level-N face color extraction - Add kitty-gfx-run-self-tests with 15+ assertions for batch testing - Add kitty-gfx-heading-scales and kitty-gfx-heading-sizes-auto defcustoms - Add kitty-gfx--text-sizing-support state variable
* fix: force redisplay before position queries to fix initial image placementcashmere2026-03-201-39/+163
| | | | | | | | | | | | | | After org-toggle-inline-images creates overlays with multi-line display properties, posn-at-point still sees pre-overlay layout because Emacs hasn't recomputed pixel positions yet. This caused images to appear ~4 rows too low on initial render (scrolling would fix it). Adding (redisplay t) at the start of kitty-gfx--refresh forces a full layout recomputation so position queries return correct values immediately. Also includes: simplified column calculation using window-body-edges, stderr suppression in call-process, debug state inspection commands, and ImageMagick binary preference fixes.
* chore: bump version to 0.3.0cashmere2026-03-201-1/+1
| | | | | Sixel backend support is a new minor feature (new protocol, new terminals supported, new defcustom). No breaking changes to public API.
* feat: add Sixel graphics backend with protocol auto-detectioncashmere2026-03-201-65/+329
| | | | | | | | | | | | | | | | | | | Introduce backend dispatch architecture so the package supports multiple terminal graphics protocols. Existing Kitty protocol code is extracted into a `kitty` backend; a new `sixel` backend enables ~20 additional terminals (foot, Konsole, xterm, mlterm, mintty, VS Code Terminal). Key changes: - Alist-based backend dispatch (`kitty-gfx--backends`, `kitty-gfx--backend-fn`) - Kitty backend: detect/prepare/place/delete/cleanup extracted from inline code - Sixel backend: ImageMagick-based encoding, temp-file cache, DCS emission - Auto-detection (`kitty-gfx--detect-protocol`): tries Kitty first, then Sixel - `kitty-gfx-preferred-protocol` defcustom for user override (auto/kitty/sixel) - Mode-line indicator shows active backend: [K], [S], or [?] - Fix obsolete `when-let` → `when-let*` (zero byte-compile warnings) All integration points (org, image-mode, shr, dired, doc-view) dispatch through the backend interface — no mode-specific changes needed.
* feat: support images in agent-shell sessionsLenbok2026-03-121-0/+46
|
* fix: reuse placement ID on zoom to avoid WezTerm visual glitchescashmere2026-03-101-34/+55
| | | | | | | | | | | When zooming in image-mode or doc-view, reuse the existing placement ID instead of deleting and re-placing. This lets the terminal atomically replace the old placement (same PID, new dimensions) without a delete step, working around WezTerm rendering artifacts (wezterm#5892). Kitty handles this perfectly. WezTerm still shows minor artifacts on zoom-in (larger replacement) but zoom-out is clean. This is a WezTerm-side bug.
* feat: robustness overhaul — LRU cache, better error handling, reduced flickerv0.2.1cashmere2026-02-271-202/+494
| | | | | | | | | | | | | | | | | - LRU image cache with configurable size and eviction (kitty-gfx-cache-size) - Cache stores only image IDs; dimensions computed fresh each time - Leading-edge debounce for faster initial refresh response - Targeted placement deletion on buffer/window change (no more delete-all flicker) - Cell pixel size re-queried on window resize - Image overflow check prevents visual corruption at window bottom - convert-to-png returns nil on failure instead of passing non-PNG data - unwind-protect for temp file cleanup in display-image paths - kill-buffer-hook checks cross-buffer image sharing before deleting - ignore-errors around all send-string-to-terminal calls - Millisecond-precision debug logging throughout - Dead overlay pruning in refresh cycle - GIF removed from supported formats (multi-frame issues) - Window-size-change hook in image-mode for split/unsplit re-render
* chore: update URL to GitHub repositorycashmere2026-02-271-1/+1
|
* fix: image-mode compatibility with evil-mode and centered image positioningcashmere2026-02-261-8/+42
| | | | | | | | | | | | - Use kitty-gfx-image-mode major-mode to avoid evil-collection overriding zoom keybindings with native image functions that fail in terminal - Add evil normal-state bindings for +/=/-/0/q when evil is loaded - Use special-mode-map as parent instead of image-mode-map to prevent image-mode-window-put and image--change-size errors - Fix centered image column calculation: detect when posn-col-row is inflated by overlay display properties and fall back to body-left - Clear buffer-modified-p after image-mode renders - Add debug logging to centered display and image-mode-render paths
* feat: add image-mode centering and zoom controlscashmere2026-02-261-6/+43
| | | | | | | | | | | | Images in image-mode now display centered in the window with +/-/0 keybindings for zoom in/out/reset. - Add kitty-gfx--image-scale buffer-local variable - Add kitty-gfx--image-mode-render for centered display at scale - Add kitty-gfx-image-increase-size (1.25x per press) - Add kitty-gfx-image-decrease-size (0.8x per press) - Add kitty-gfx-image-reset-size (back to 1.0) - Bind +/-/0 in the image-mode keymap
* feat: add doc-view integration for PDF viewing with zoomcashmere2026-02-261-0/+91
| | | | | | | | | | | | | PDFs now render via Kitty graphics in terminal doc-view-mode. Pages display centered in the window with n/p navigation and +/-/0 zoom controls. - Advise doc-view-mode-p to bypass display-graphic-p guard while preserving per-type tool availability checks - Advise doc-view-insert-image to render pages via Kitty using the centered display helper with zoom scale - Advise doc-view-enlarge and doc-view-scale-reset to update the buffer-local scale factor and re-render
* feat: add centered display helper, bump default sizes, relax refreshcashmere2026-02-261-6/+53
| | | | | | | | - Add kitty-gfx--display-image-centered: centers images in the window with optional zoom scale parameter for full-window modes - Bump kitty-gfx-max-width 80->120, kitty-gfx-max-height 24->40 - Relax refresh visibility check to only require overlay start on screen (allows images larger than window for zoom-in)
* feat: add LaTeX fragment preview in org-mode via Kitty graphicscashmere2026-02-261-1/+80
| | | | | | | | | | | | | C-c C-x C-l now renders LaTeX fragments as images in terminal Emacs. Bypasses org's display-graphic-p guard since the latex+dvipng pipeline works fine without a GUI. - Advise org-latex-preview to handle terminal color fallbacks (unspecified-fg -> Black) and suppress clear-image-cache - Advise org--make-preview-overlay to display generated PNGs via kitty-gfx-display-image instead of Emacs image specs - Add kitty-gfx--org-clear-latex-preview for C-u cleanup - Add LaTeX test fragments to test-kitty-gfx.org
* fix: hide images when org headings are collapsedcashmere2026-02-261-3/+53
| | | | | | | | | | | | Add fold-aware visibility detection so images disappear when their containing heading is folded and reappear when expanded. - Add kitty-gfx--in-folded-region-p: checks org-fold (9.6+) then falls back to overlay-based invisibility, ignoring cosmetic org-link bracket hiding - Update kitty-gfx--overlay-screen-pos to skip folded overlays - Add kitty-gfx--on-org-cycle hook: deletes terminal placements before clearing cache, then schedules refresh
* feat: Add README.org and kitty-graphics.elcashmere2026-02-241-1/+1
|
* Add cell size query, synchronized output, and dirvish integrationcashmere2026-02-241-67/+218
| | | | | | | | | | | | | - Query terminal cell size via CSI 16t (XTWINOPS) instead of hardcoded 8x16 fallback, giving accurate image aspect ratios - Wrap all placement output in synchronized output (DEC mode 2026) to eliminate flicker during scroll and redisplay - Add native dirvish preview dispatcher (kitty-image) that hooks into dirvish-preview-dispatchers for automatic image preview - Improve shr/eww advice to detect actual image type from spec - Extract kitty-gfx--refresh-overlay for cleaner refresh cycle - Reset position cache on buffer/window change so images re-place after d=a - Bump version to 0.2.0, update package metadata and README
* Add dired preview command and improve image-mode integrationcashmere2026-02-241-2/+44
| | | | | | - kitty-gfx-dired-preview: preview images in a side window from dired - image-mode: add q to quit, set buffer-read-only - Add dired-get-file-for-visit forward declaration
* Initial commit: kitty-graphics.elcashmere2026-02-241-0/+722
Display images in terminal Emacs via Kitty graphics protocol with direct placements. Integrates with org-mode (including org-link-preview for org 10.0+), image-mode, and shr/eww.