Files
dotfiles/config/scripts/.local/scripts/graphics-query
2026-02-13 12:12:40 +01:00

98 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Description:
# Query terminal capabilities for graphics support using escape sequences,
# without relying on environment variables or external tools.
#
# Usage:
# This script will print one or more of the following strings to stdout, each on a new line,
# depending on the detected capabilities:
# - "kitty" if Kitty's terminal Graphics Protocol is supported
# - "iterm" if iTerm2's inline image support is detected
# - "sixels" if Sixel graphics support is detected
#
# See also:
# For separate queries for specific protocols, see the related scripts in the same directory:
# - kgp-query: specifically checks for Kitty's terminal Graphics Protocol support
# - iterm2-query: specifically checks for iTerm2 inline image support
# - sixel-query: specifically checks for Sixel graphics support
set -euo pipefail
# Ensure in a interactive terminal
[ ! -t 0 ] && exit 1
# Increase timeout for SSH sessions
TIMEOUT=0.3
[[ -n "${SSH_CONNECTION:-}" ]] && TIMEOUT=1.0
# Construct query
KGP_QUERY_ID=$RANDOM
KGP_QUERY_CODE=$(printf "\033_Gi=%d,s=1,v=1,a=q,t=d,f=24;AAAA\033\\" "$KGP_QUERY_ID")
ITERM2_QUERY_CODE=$(printf "\033]1337;ReportCellSize\a")
KGP_EXPECTED_RESPONSE=$(printf "\033_Gi=%d;OK\033\\" "$KGP_QUERY_ID")
ITERM2_EXPECTED_RESPONSE=$(printf "\033]1337;") # followed by "ReportCellSize=...", but only the prefix is enough
FENCE_CODE=$(printf "\033[c")
# Set terminal to raw mode with timeout
stty_orig=$(stty -g)
trap 'stty "$stty_orig"' EXIT INT TERM HUP
stty -echo -icanon min 1 time 0
printf "%s%s%s" "$ITERM2_QUERY_CODE" "$KGP_QUERY_CODE" "$FENCE_CODE" > /dev/tty
support_kgp=0
support_iterm2=0
support_sixel=0
response=""
while true; do
IFS= read -r -N 1 -t "$TIMEOUT" char || {
[ -z "$char" ] && break
}
response+="$char"
if [[ "$response" == *"$KGP_EXPECTED_RESPONSE"* ]]; then
support_kgp=1
fi
if [[ "$response" == *"$ITERM2_EXPECTED_RESPONSE"* ]]; then
support_iterm2=1
fi
if [[ "$response" == *$'\033['*'c' ]]; then
break
fi
if [ ${#response} -gt 1024 ]; then
break
fi
done
if [[ "$response" =~ $'\x1b'\[\?([0-9;]*)c ]]; then
params="${BASH_REMATCH[1]}"
IFS=';' read -ra codes <<< "$params"
for code in "${codes[@]}"; do
if [[ "$code" == "4" ]]; then
support_sixel=1
break
fi
done
fi
if [ "$support_kgp" -eq 1 ]; then
echo "kitty"
fi
if [ "$support_iterm2" -eq 1 ]; then
echo "iterm"
fi
if [ "$support_sixel" -eq 1 ]; then
echo "sixels"
fi