Skip to content

Kitty graphics: Implement remaining delete selectors and case-sensitive layer distinction #5710

@anthonykim1

Description

@anthonykim1

Context

The Kitty graphics protocol a=d (delete) action supports many selectors for targeting specific images. Currently only a/A (delete all) and i/I (delete by image ID) are implemented. All other selectors are silently ignored (see _handleDelete() default branch).

Additionally, the spec distinguishes lowercase selectors (delete placements only, keep stored data) from uppercase (delete placements AND free stored image data). The current implementation treats both the same — it always frees everything. There is a TODO at line 277 of KittyGraphicsHandler.ts noting this.

Note: The current d=a implementation also deletes ALL images including offscreen stored data. Per spec, d=a should only delete "all placements visible on screen" — offscreen/stored-but-not-placed images should be preserved. This needs to be fixed as part of this issue.

What needs to happen

  1. Fix d=a scope: d=a should only delete placements visible on screen, not all stored image data. Offscreen images (stored via a=t but never placed, or scrolled out of view) should be preserved. d=A should delete visible placements AND free their stored image data.

  2. Implement missing delete selectors in KittyGraphicsHandler._handleDelete():

    • c/C — delete image at cursor position
    • n/N — delete images with ID >= the specified ID
    • p/P — delete image by placement ID (requires p key + optionally i key)
    • q/Q — delete images whose placement intersects the cursor cell
    • r/R — delete images intersecting a row range (uses x/y keys for row bounds)
    • x/X — delete images intersecting a column range
    • y/Y — delete images at a specific cell position
    • z/Z — delete images at a specific z-index
    • f/F — delete animation frames (depends on animation support)
  3. Implement case distinction:

    • Lowercase selector → delete the on-screen placement only, keep the stored image data in _images map so a=p can re-place it later
    • Uppercase selector → delete placement AND free stored image data from _images
  4. Add positional query support to KittyImageStorage:

    • Currently only has deleteById() and deleteAll() — no way to query "which images intersect row 5?" or "which images are at cursor position?"
    • Needs methods like deleteAtCursorPosition(), deleteByRowRange(), deleteByColumnRange(), deleteByZIndex(), etc.

Spec reference

https://sw.kovidgoyal.net/kitty/graphics-protocol/#deleting-images

Key files

  • addons/addon-image/src/kitty/KittyGraphicsHandler.ts_handleDelete() (line ~270)
  • addons/addon-image/src/kitty/KittyImageStorage.ts — needs new positional delete methods
  • addons/addon-image/test/KittyGraphics.test.ts — integration tests

Acceptance criteria

  • d=a only deletes placements visible on screen, not all stored data
  • d=A deletes visible placements AND frees stored image data
  • Each selector (c, n, p, q, r, x, y, z) correctly deletes matching images
  • Lowercase selectors preserve stored image data; uppercase selectors free it
  • d=p,i=3,p=5 deletes only placement 5 of image 3
  • d=r,x=2,y=8 deletes images intersecting rows 2–8
  • Integration tests verify each selector

Discussion

See feature inventory §9.3–9.13 in #5683

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions