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(* Terminal Environment Detection *) 7 8type graphics_mode = [ `Auto | `Enabled | `Disabled | `Tmux ] 9 10let is_kitty () = 11 Option.is_some (Sys.getenv_opt "KITTY_WINDOW_ID") || 12 (match Sys.getenv_opt "TERM" with 13 | Some term -> String.lowercase_ascii term = "xterm-kitty" 14 | None -> false) || 15 (match Sys.getenv_opt "TERM_PROGRAM" with 16 | Some prog -> String.lowercase_ascii prog = "kitty" 17 | None -> false) 18 19let is_wezterm () = 20 Option.is_some (Sys.getenv_opt "WEZTERM_PANE") || 21 (match Sys.getenv_opt "TERM_PROGRAM" with 22 | Some prog -> String.lowercase_ascii prog = "wezterm" 23 | None -> false) 24 25let is_ghostty () = 26 Option.is_some (Sys.getenv_opt "GHOSTTY_RESOURCES_DIR") || 27 (match Sys.getenv_opt "TERM_PROGRAM" with 28 | Some prog -> String.lowercase_ascii prog = "ghostty" 29 | None -> false) 30 31let is_graphics_terminal () = 32 is_kitty () || is_wezterm () || is_ghostty () 33 34let is_tmux () = Kgp_tmux.is_active () 35 36let is_interactive () = 37 Unix.isatty Unix.stdout 38 39let is_pager () = 40 (* Not interactive = likely piped to pager *) 41 not (is_interactive ()) || 42 (* PAGER set and not in a known graphics terminal *) 43 (Option.is_some (Sys.getenv_opt "PAGER") && not (is_graphics_terminal ())) 44 45let resolve_mode = function 46 | `Disabled -> `Placeholder 47 | `Enabled -> `Graphics 48 | `Tmux -> `Tmux 49 | `Auto -> 50 if is_pager () || not (is_interactive ()) then 51 `Placeholder 52 else if is_tmux () then 53 (* Inside tmux - use passthrough if underlying terminal supports graphics *) 54 if is_graphics_terminal () then `Tmux 55 else `Placeholder 56 else if is_graphics_terminal () then 57 `Graphics 58 else 59 `Placeholder 60 61let supports_graphics mode = 62 match resolve_mode mode with 63 | `Graphics | `Tmux -> true 64 | `Placeholder -> false