Kitty Graphics Protocol in OCaml
terminal graphics ocaml
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** Tmux Passthrough Support 7 8 Support for passing graphics protocol escape sequences through tmux to the 9 underlying terminal emulator. 10 11 {2 Background} 12 13 When running inside tmux, graphics protocol escape sequences need to be 14 wrapped in a DCS (Device Control String) passthrough sequence so that tmux 15 forwards them to the actual terminal (kitty, wezterm, ghostty, etc.) rather 16 than interpreting them itself. 17 18 The passthrough format is: 19 - Prefix: [ESC P tmux ;] 20 - Content with all ESC characters doubled 21 - Suffix: [ESC] 22 23 {2 Requirements} 24 25 For tmux passthrough to work: 26 {ul 27 {- tmux version 3.3 or later } 28 {- [allow-passthrough] must be enabled in tmux.conf: 29 {v set -g allow-passthrough on v} 30 } 31 } 32 33 {2 Usage} 34 35 {[ 36 if Kgp.Tmux.is_active () then 37 let wrapped = Kgp.Tmux.wrap graphics_command in 38 print_string wrapped 39 else print_string graphics_command 40 ]} *) 41 42val is_active : unit -> bool 43(** Detect if we are running inside tmux. 44 45 Returns [true] if the [TMUX] environment variable is set, indicating the 46 process is running inside a tmux session. *) 47 48val wrap : string -> string 49(** Wrap an escape sequence for tmux passthrough. 50 51 Takes a graphics protocol escape sequence and wraps it in the tmux DCS 52 passthrough format: 53 - Adds [ESC P tmux ;] prefix 54 - Doubles all ESC characters in the content 55 - Adds [ESC] suffix 56 57 If not running inside tmux, returns the input unchanged. *) 58 59val wrap_always : string -> string 60(** Wrap an escape sequence for tmux passthrough unconditionally. 61 62 Like {!wrap} but always applies the wrapping, regardless of whether we are 63 inside tmux. Useful when you want to pre-generate tmux-compatible output. *) 64 65val write_wrapped : Buffer.t -> string -> unit 66(** Write a wrapped escape sequence directly to a buffer. 67 68 More efficient than {!wrap_always} when building output in a buffer, as it 69 avoids allocating an intermediate string. *)