···66let use_graphics mode =
77 Kgp.Terminal.supports_graphics mode
8899-let next_image_id = ref 1
99+(* Generate image IDs suitable for unicode placeholders.
1010+ The ID must have non-zero bytes in positions for:
1111+ - High byte (bits 24-31) - encoded as third diacritic
1212+ - Middle bytes (bits 8-23) - encoded in foreground RGB color
1313+ See kitty icat transmit.go for reference. *)
1414+let next_unicode_image_id () =
1515+ (* Use Random to generate IDs with non-zero bytes in required positions *)
1616+ let rec gen () =
1717+ let id = Random.int32 Int32.max_int |> Int32.to_int in
1818+ (* Ensure high byte and middle bytes are non-zero *)
1919+ if id land 0xFF000000 = 0 || id land 0x00FFFF00 = 0 then gen ()
2020+ else id
2121+ in
2222+ gen ()
10231124let display_png_thumbnail path =
2525+ let image_id = next_unicode_image_id () in
1226 let png_data = Eio.Path.load path in
1327 let rows = 4 in
1428 let cols = 8 in
1515- (* Direct rendering - cursor stays in place after image *)
1616- let placement = Kgp.Placement.make ~rows ~columns:cols ~cursor:`Static () in
1717- let cmd = Kgp.transmit_and_display ~format:`Png ~placement ~quiet:`Silent () in
2929+ (* Unicode placeholder mode - transmit image virtually, display via placeholders *)
3030+ let placement = Kgp.Placement.make ~rows ~columns:cols ~unicode_placeholder:true () in
3131+ let cmd = Kgp.transmit_and_display ~image_id ~format:`Png ~placement ~quiet:`Silent () in
1832 let buf = Buffer.create 4096 in
3333+ (* Transmit image with tmux passthrough if needed *)
1934 Kgp.write_tmux buf cmd ~data:png_data;
3535+ (* Write unicode placeholders - these are just text characters *)
3636+ Kgp.Unicode_placeholder.write buf ~image_id ~rows ~cols ();
3737+ (* Move cursor back up to top of image area and to column 0 *)
3838+ Printf.bprintf buf "\x1b[%dA\r" (rows - 1);
2039 Buffer.contents buf
21402241let display_block_placeholder () =
···2544 let row2 = "▒░▒▓▒░" in
2645 let row3 = "░▒▓▒░▒" in
2746 let row4 = "▒▓▒░▒▓" in
2828- Printf.sprintf "%s\n%s\n%s\n%s\x1b[4A" row1 row2 row3 row4 (* print 4 rows, move up 4 *)
4747+ Printf.sprintf "%s\n%s\n%s\n%s\x1b[4A\r" row1 row2 row3 row4 (* print 4 rows, move up 4, return to col 0 *)
29483049let move_right n = Printf.sprintf "\x1b[%dC" n
3150let move_down_and_back () = Printf.sprintf "\n\x1b[%dC" image_columns
···34533554(* 1-row thumbnail for listings *)
3655let display_small_thumbnail path =
3737- let image_id = !next_image_id in
3838- incr next_image_id;
5656+ let image_id = next_unicode_image_id () in
3957 let png_data = Eio.Path.load path in
4058 let rows = 1 in
4159 let cols = 2 in