@@ -76,6 +76,15 @@ public final class TermCaps {
7676 /** Whether the terminal supports overline text. */
7777 private final boolean overline ;
7878
79+ /** Whether the terminal supports sixel bitmap graphics (DCS sequences). */
80+ private final boolean sixel ;
81+
82+ /** Whether the terminal supports the Kitty terminal graphics protocol (APC-based). */
83+ private final boolean kittyGraphics ;
84+
85+ /** Whether the terminal supports the iTerm2 inline image protocol (OSC 1337). */
86+ private final boolean iterm2Images ;
87+
7988 private TermCaps (Builder b ) {
8089 this .colors = b .colors ;
8190 this .altScreen = b .altScreen ;
@@ -89,6 +98,9 @@ private TermCaps(Builder b) {
8998 this .italic = b .italic ;
9099 this .strikethrough = b .strikethrough ;
91100 this .overline = b .overline ;
101+ this .sixel = b .sixel ;
102+ this .kittyGraphics = b .kittyGraphics ;
103+ this .iterm2Images = b .iterm2Images ;
92104 }
93105
94106 // ── Capability getters ────────────────────────────────────────────────
@@ -153,6 +165,21 @@ public boolean overline() {
153165 return overline ;
154166 }
155167
168+ /** Whether the terminal supports sixel bitmap graphics (DCS sequences). */
169+ public boolean sixel () {
170+ return sixel ;
171+ }
172+
173+ /** Whether the terminal supports the Kitty terminal graphics protocol (APC-based). */
174+ public boolean kittyGraphics () {
175+ return kittyGraphics ;
176+ }
177+
178+ /** Whether the terminal supports the iTerm2 inline image protocol (OSC 1337). */
179+ public boolean iterm2Images () {
180+ return iterm2Images ;
181+ }
182+
156183 // ── Terminal control helpers ──────────────────────────────────────────
157184
158185 private static final String CSI = "\033 [" ;
@@ -365,12 +392,51 @@ static void applyTerm(Builder b, String term) {
365392 b .colors (8 ).altScreen (true );
366393 } else if (term .startsWith ("rxvt" )) {
367394 b .colors (8 ).altScreen (true ).mouse (true ).unicode (true );
395+ } else if ("xterm-kitty" .equals (term )) {
396+ // Ghostty and other terminals that set TERM=xterm-kitty support the Kitty graphics
397+ // protocol
398+ b .colors (16_777_216 )
399+ .altScreen (true )
400+ .mouse (true )
401+ .settableTitle (true )
402+ .unicode (true )
403+ .kittyGraphics (true );
368404 } else if (term .startsWith ("xterm" ) || term .startsWith ("vte" )) {
369405 b .colors (8 ).altScreen (true ).mouse (true ).settableTitle (true ).unicode (true );
370406 } else if (term .startsWith ("linux" )) {
371407 b .colors (8 ).altScreen (true ).unicode (true );
372408 } else if (term .startsWith ("konsole" )) {
373409 b .colors (8 ).altScreen (true ).mouse (true ).settableTitle (true ).unicode (true );
410+ } else if (term .startsWith ("foot" )) {
411+ // foot (Wayland) 1.2.0+ supports sixel
412+ b .colors (256 )
413+ .altScreen (true )
414+ .mouse (true )
415+ .bracketedPaste (true )
416+ .focusTracking (true )
417+ .unicode (true )
418+ .sixel (true );
419+ } else if (term .startsWith ("mlterm" )) {
420+ // mlterm 3.1.9+ supports sixel
421+ b .colors (256 ).altScreen (true ).mouse (true ).unicode (true ).sixel (true );
422+ } else if (term .startsWith ("mintty" )) {
423+ // mintty 2.6.0+ supports sixel and the iTerm2 inline image protocol
424+ b .colors (256 )
425+ .altScreen (true )
426+ .mouse (true )
427+ .bracketedPaste (true )
428+ .unicode (true )
429+ .sixel (true )
430+ .iterm2Images (true );
431+ } else if (term .startsWith ("contour" )) {
432+ // Contour supports sixel natively
433+ b .colors (16_777_216 )
434+ .altScreen (true )
435+ .mouse (true )
436+ .bracketedPaste (true )
437+ .focusTracking (true )
438+ .unicode (true )
439+ .sixel (true );
374440 } else {
375441 // Unknown terminal — assume at least 8 colours
376442 b .colors (8 );
@@ -419,7 +485,8 @@ static void applyEnvVars(Builder b, EnvSource env) {
419485 .unicode (true )
420486 .italic (true )
421487 .strikethrough (true )
422- .overline (true );
488+ .overline (true )
489+ .sixel (true ); // Windows Terminal 1.22+ (August 2024)
423490 return ;
424491 }
425492
@@ -450,7 +517,10 @@ static void applyEnvVars(Builder b, EnvSource env) {
450517 .unicode (true )
451518 .italic (true )
452519 .strikethrough (true )
453- .overline (true );
520+ .overline (true )
521+ .sixel (true ) // iTerm2 3.3.0+
522+ .kittyGraphics (true ) // iTerm2 added Kitty graphics in 2024
523+ .iterm2Images (true );
454524 break ;
455525 case "WezTerm" :
456526 b .colors (16_777_216 )
@@ -464,7 +534,10 @@ static void applyEnvVars(Builder b, EnvSource env) {
464534 .unicode (true )
465535 .italic (true )
466536 .strikethrough (true )
467- .overline (true );
537+ .overline (true )
538+ .sixel (true )
539+ .kittyGraphics (true )
540+ .iterm2Images (true );
468541 break ;
469542 case "kitty" :
470543 b .colors (16_777_216 )
@@ -477,12 +550,29 @@ static void applyEnvVars(Builder b, EnvSource env) {
477550 .unicode (true )
478551 .italic (true )
479552 .strikethrough (true )
480- .overline (true );
553+ .overline (true )
554+ .kittyGraphics (true ); // kitty does not support sixel by design
481555 break ;
482556 case "Apple_Terminal" :
483557 if (b .colors < 256 ) b .colors (256 );
484558 b .settableTitle (true ).unicode (true );
485559 break ;
560+ case "Ghostty" :
561+ case "ghostty" :
562+ b .colors (16_777_216 )
563+ .altScreen (true )
564+ .mouse (true )
565+ .bracketedPaste (true )
566+ .focusTracking (true )
567+ .synchronizedOutput (true )
568+ .hyperlinks (true )
569+ .settableTitle (true )
570+ .unicode (true )
571+ .italic (true )
572+ .strikethrough (true )
573+ .overline (true )
574+ .kittyGraphics (true );
575+ break ;
486576 default :
487577 break ;
488578 }
@@ -495,6 +585,17 @@ static void applyEnvVars(Builder b, EnvSource env) {
495585 b .mouse (true );
496586 }
497587
588+ // KONSOLE_VERSION — KDE Konsole 22.04+ supports sixel and the Kitty graphics protocol.
589+ if (env .get ("KONSOLE_VERSION" ) != null ) {
590+ if (b .colors < 256 ) b .colors (256 );
591+ b .sixel (true ).kittyGraphics (true );
592+ }
593+
594+ // ZELLIJ — Zellij multiplexer 0.31.0+ passes sixel through to the underlying terminal.
595+ if (env .get ("ZELLIJ" ) != null ) {
596+ b .sixel (true );
597+ }
598+
498599 // Windows fallback: if no special env var fired but we are on Windows,
499600 // assume a VT-capable console host (Win10 1511+) with conservative caps.
500601 String os = System .getProperty ("os.name" , "" ).toLowerCase ();
@@ -532,6 +633,9 @@ public static final class Builder {
532633 private boolean italic ;
533634 private boolean strikethrough ;
534635 private boolean overline ;
636+ private boolean sixel ;
637+ private boolean kittyGraphics ;
638+ private boolean iterm2Images ;
535639
536640 private Builder () {}
537641
@@ -548,6 +652,9 @@ private Builder(TermCaps base) {
548652 this .italic = base .italic ;
549653 this .strikethrough = base .strikethrough ;
550654 this .overline = base .overline ;
655+ this .sixel = base .sixel ;
656+ this .kittyGraphics = base .kittyGraphics ;
657+ this .iterm2Images = base .iterm2Images ;
551658 }
552659
553660 /** Returns the currently set colors value. */
@@ -615,6 +722,21 @@ public Builder overline(boolean v) {
615722 return this ;
616723 }
617724
725+ public Builder sixel (boolean v ) {
726+ this .sixel = v ;
727+ return this ;
728+ }
729+
730+ public Builder kittyGraphics (boolean v ) {
731+ this .kittyGraphics = v ;
732+ return this ;
733+ }
734+
735+ public Builder iterm2Images (boolean v ) {
736+ this .iterm2Images = v ;
737+ return this ;
738+ }
739+
618740 public TermCaps build () {
619741 return new TermCaps (this );
620742 }
0 commit comments