@@ -23,7 +23,7 @@ require (
github.com/charmbracelet/colorprofile v0.4.1
github.com/charmbracelet/fang v0.4.4
github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560
- github.com/charmbracelet/x/ansi v0.11.3
+ github.com/charmbracelet/x/ansi v0.11.4
github.com/charmbracelet/x/editor v0.2.0
github.com/charmbracelet/x/etag v0.2.0
github.com/charmbracelet/x/exp/charmtone v0.0.0-20260109001716-2fbdffcb221f
@@ -104,7 +104,7 @@ require (
github.com/charmbracelet/x/json v0.2.0 // indirect
github.com/charmbracelet/x/termios v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.2.2 // indirect
- github.com/clipperhouse/displaywidth v0.6.2 // indirect
+ github.com/clipperhouse/displaywidth v0.7.0 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -104,8 +104,8 @@ github.com/charmbracelet/fang v0.4.4 h1:G4qKxF6or/eTPgmAolwPuRNyuci3hTUGGX1rj1Yk
github.com/charmbracelet/fang v0.4.4/go.mod h1:P5/DNb9DddQ0Z0dbc0P3ol4/ix5Po7Ofr2KMBfAqoCo=
github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560 h1:j3PW2hypGoPKBy3ooKzW0TFxaxhyHK3NbkLLn4KeRFc=
github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560/go.mod h1:VWATWLRwYP06VYCEur7FsNR2B1xAo7Y+xl1PTbd1ePc=
-github.com/charmbracelet/x/ansi v0.11.3 h1:6DcVaqWI82BBVM/atTyq6yBoRLZFBsnoDoX9GCu2YOI=
-github.com/charmbracelet/x/ansi v0.11.3/go.mod h1:yI7Zslym9tCJcedxz5+WBq+eUGMJT0bM06Fqy1/Y4dI=
+github.com/charmbracelet/x/ansi v0.11.4 h1:6G65PLu6HjmE858CnTUQY1LXT3ZUWwfvqEROLF8vqHI=
+github.com/charmbracelet/x/ansi v0.11.4/go.mod h1:/5AZ+UfWExW3int5H5ugnsG/PWjNcSQcwYsHBlPFQN4=
github.com/charmbracelet/x/editor v0.2.0 h1:7XLUKtaRaB8jN7bWU2p2UChiySyaAuIfYiIRg8gGWwk=
github.com/charmbracelet/x/editor v0.2.0/go.mod h1:p3oQ28TSL3YPd+GKJ1fHWcp+7bVGpedHpXmo0D6t1dY=
github.com/charmbracelet/x/etag v0.2.0 h1:Euj1VkheoHfTYA9y+TCwkeXF/hN8Fb9l4LqZl79pt04=
@@ -130,8 +130,8 @@ github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8
github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo=
github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM=
github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k=
-github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
-github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
+github.com/clipperhouse/displaywidth v0.7.0 h1:QNv1GYsnLX9QBrcWUtMlogpTXuM5FVnBwKWp1O5NwmE=
+github.com/clipperhouse/displaywidth v0.7.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
@@ -2,7 +2,6 @@ package image
import (
"bytes"
- "errors"
"fmt"
"hash/fnv"
"image"
@@ -195,50 +194,12 @@ func (e Encoding) Transmit(id string, img image.Image, cs CellSize, cols, rows i
}
var buf bytes.Buffer
- rp, wp := io.Pipe()
- go func() {
- for {
- // Read single Kitty graphic chunks from the pipe and wrap them
- // for tmux if needed.
- var out bytes.Buffer
- seenEsc := false
- for {
- var p [1]byte
- n, err := rp.Read(p[:])
- if n > 0 {
- out.WriteByte(p[0])
- if p[0] == ansi.ESC {
- seenEsc = true
- } else if seenEsc && p[0] == '\\' {
- // End of Kitty graphics sequence
- break
- } else {
- seenEsc = false
- }
- }
- if err != nil {
- if !errors.Is(err, io.EOF) {
- slog.Error("error reading from pipe", "err", err)
- }
- return
- }
- }
-
- seq := out.String()
- if tmux {
- seq = ansi.TmuxPassthrough(seq)
- }
-
- buf.WriteString(seq)
- }
- }()
-
img := fitImage(id, img, cs, cols, rows)
bounds := img.Bounds()
imgWidth := bounds.Dx()
imgHeight := bounds.Dy()
imgID := int(key.Hash())
- if err := kitty.EncodeGraphics(wp, img, &kitty.Options{
+ if err := kitty.EncodeGraphics(&buf, img, &kitty.Options{
ID: imgID,
Action: kitty.TransmitAndPut,
Transmission: kitty.Direct,
@@ -250,9 +211,18 @@ func (e Encoding) Transmit(id string, img image.Image, cs CellSize, cols, rows i
VirtualPlacement: true,
Quite: 1,
Chunk: true,
+ ChunkFormatter: func(chunk string) string {
+ if tmux {
+ return ansi.TmuxPassthrough(chunk)
+ }
+ return chunk
+ },
}); err != nil {
slog.Error("failed to encode image for kitty graphics", "err", err)
- return uiutil.ReportError(fmt.Errorf("failed to encode image"))
+ return uiutil.InfoMsg{
+ Type: uiutil.InfoTypeError,
+ Msg: "failed to encode image",
+ }
}
return tea.RawMsg{Msg: buf.String()}