Kitty Graphics Protocol in OCaml
terminal graphics ocaml
at main 2.0 kB view raw
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 || 16 match Sys.getenv_opt "TERM_PROGRAM" with 17 | Some prog -> String.lowercase_ascii prog = "kitty" 18 | None -> false 19 20let is_wezterm () = 21 Option.is_some (Sys.getenv_opt "WEZTERM_PANE") 22 || 23 match Sys.getenv_opt "TERM_PROGRAM" with 24 | Some prog -> String.lowercase_ascii prog = "wezterm" 25 | None -> false 26 27let is_ghostty () = 28 Option.is_some (Sys.getenv_opt "GHOSTTY_RESOURCES_DIR") 29 || 30 match Sys.getenv_opt "TERM_PROGRAM" with 31 | Some prog -> String.lowercase_ascii prog = "ghostty" 32 | None -> false 33 34let is_graphics_terminal () = is_kitty () || is_wezterm () || is_ghostty () 35let is_tmux () = Kgp_tmux.is_active () 36let is_interactive () = Unix.isatty Unix.stdout 37 38let is_pager () = 39 (* Not interactive = likely piped to pager *) 40 (not (is_interactive ())) 41 || 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 `Placeholder 51 else if is_tmux () then 52 (* Inside tmux - use passthrough if underlying terminal supports graphics *) 53 if is_graphics_terminal () then `Tmux else `Placeholder 54 else if is_graphics_terminal () then `Graphics 55 else `Placeholder 56 57let supports_graphics mode = 58 match resolve_mode mode with 59 | `Graphics | `Tmux -> true 60 | `Placeholder -> false