Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from os import OsError 

2from os import env 

3 

4c"""source-before-namespace 

5#include <sys/ioctl.h> 

6""" 

7 

8enum GraphicsProtocol: 

9 Kitty 

10 ITerm 

11 Sixel 

12 Text 

13 

14class Dimensions: 

15 width: i64 

16 height: i64 

17 

18class Size: 

19 cells: Dimensions 

20 pixels: Dimensions? 

21 cell_pixels: Dimensions? 

22 

23enum KittyTransmissionMedium: 

24 Direct 

25 SimpleFile 

26 TemporaryFile 

27 SharedMemory 

28 

29class KittyGraphicsInfo: 

30 is_supported: bool 

31 transmission_mediums: [KittyTransmissionMedium] 

32 

33class SixelGraphicsInfo: 

34 is_supported: bool 

35 

36class ITermGraphicsInfo: 

37 is_supported: bool 

38 

39class GraphicsInfo: 

40 has_true_color: bool 

41 sixel: SixelGraphicsInfo 

42 kitty: KittyGraphicsInfo 

43 iterm: ITermGraphicsInfo 

44 

45class Info: 

46 size: Size 

47 graphics: GraphicsInfo 

48 

49func get_size() -> Size: 

50 """Get terminal size. 

51 

52 """ 

53 

54 rows = 0 

55 columns = 0 

56 width = 0 

57 height = 0 

58 ok = False 

59 

60 c""" 

61 struct winsize sz; 

62 if (ioctl(0, TIOCGWINSZ, &sz) == 0) { 

63 rows = sz.ws_row; 

64 columns = sz.ws_col; 

65 width = sz.ws_xpixel; 

66 height = sz.ws_ypixel; 

67 ok = true; 

68 } 

69 """ 

70 

71 if not ok: 

72 raise OsError("Failed to get terminal window size.") 

73 

74 size = Size(Dimensions(columns, rows), None, None) 

75 

76 if width > 0 and height > 0: 

77 size.pixels = Dimensions(width, height) 

78 size.cell_pixels = Dimensions(width / columns, height / rows) 

79 

80 return size 

81 

82func get_graphics_info() -> GraphicsInfo: 

83 """Get graphics info. 

84 

85 """ 

86 

87 return GraphicsInfo(env().get("COLORTERM", None) == "truecolor", 

88 get_sixel_graphics_info(), 

89 get_kitty_graphics_info(), 

90 get_iterm_graphics_info()) 

91 

92func get_sixel_graphics_info() -> SixelGraphicsInfo: 

93 """Get Sixel graphics info. 

94 

95 """ 

96 

97 return SixelGraphicsInfo(False) 

98 

99func get_kitty_graphics_info() -> KittyGraphicsInfo: 

100 """Get Kitty graphics info. 

101 

102 """ 

103 

104 term = env().get("TERM", None) 

105 is_supported = term is not None and "kitty" in term 

106 transmission_mediums: [KittyTransmissionMedium] = [] 

107 

108 if is_supported: 

109 transmission_mediums.append(KittyTransmissionMedium.Direct) 

110 

111 return KittyGraphicsInfo(is_supported, transmission_mediums) 

112 

113func get_iterm_graphics_info() -> ITermGraphicsInfo: 

114 """Get iTerm graphics info. 

115 

116 """ 

117 

118 program = env().get("TERM_PROGRAM", None) 

119 is_supported = False 

120 

121 if program is not None: 

122 for pattern in ["iTerm", "WezTerm", "mintty"]: 

123 if pattern in program: 

124 is_supported = True 

125 

126 return ITermGraphicsInfo(is_supported) 

127 

128func get_info() -> Info: 

129 """Get terminal info. 

130 

131 """ 

132 

133 return Info(get_size(), get_graphics_info()) 

134 

135func get_preferred_graphics_protocol() -> GraphicsProtocol: 

136 """Get preferred graphics protocol. 

137 

138 """ 

139 

140 graphics_info = get_graphics_info() 

141 

142 if graphics_info.kitty.is_supported: 

143 return GraphicsProtocol.Kitty 

144 elif graphics_info.iterm.is_supported: 

145 return GraphicsProtocol.ITerm 

146 elif graphics_info.sixel.is_supported: 

147 return GraphicsProtocol.Sixel 

148 else: 

149 return GraphicsProtocol.Text 

150 

151test get_info(): 

152 try: 

153 get_info() 

154 except OsError: 

155 pass 

156 

157test get_preferred_graphics_protocol(): 

158 protocol = get_preferred_graphics_protocol() 

159 assert protocol in [ 

160 GraphicsProtocol.Kitty, 

161 GraphicsProtocol.ITerm, 

162 GraphicsProtocol.Sixel, 

163 GraphicsProtocol.Text 

164 ]