detectImageProtocol function

ImageProtocol detectImageProtocol()

Auto-detect the best available terminal image protocol.

Comparisons are case-insensitive: terminals disagree on TERM_PROGRAM casing (Ghostty vs ghostty), and missing markers mean ImageProtocol.none.

Implementation

ImageProtocol detectImageProtocol() {
  final termProgram = platform.environmentValue('TERM_PROGRAM').toLowerCase();
  final term = platform.environmentValue('TERM').toLowerCase();
  final termEmulator = platform
      .environmentValue('TERMINAL_EMULATOR')
      .toLowerCase();
  final kittyWindowId = platform.environmentValue('KITTY_WINDOW_ID');

  if (kittyWindowId.isNotEmpty || termProgram == 'kitty') {
    return ImageProtocol.kitty;
  }
  if (termProgram == 'ghostty' || term.contains('ghostty')) {
    // Ghostty natively supports the Kitty graphics protocol (AOT,
    // PNG-compressed). Sixel support is limited/experimental.
    return ImageProtocol.kitty;
  }
  if (termProgram == 'iterm.app' || termProgram == 'iterm2') {
    return ImageProtocol.iterm2;
  }
  if (term.contains('sixel') ||
      term.contains('foot') ||
      term.contains('mlterm')) {
    return ImageProtocol.sixel;
  }
  if (termProgram == 'wezterm') {
    return ImageProtocol.sixel;
  }
  if (termProgram == 'vscode' || termEmulator == 'vscode') {
    return ImageProtocol.sixel;
  }
  if (termProgram == 'windows terminal' ||
      platform.hasEnvironmentValue('WT_SESSION')) {
    return ImageProtocol.sixel;
  }
  // Fall back to none — _renderTerminalImage will try Kitty anyway.
  return ImageProtocol.none;
}