Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/IPython/core/kitty.py: 36%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

39 statements  

1# Implements https://sw.kovidgoyal.net/kitty/graphics-protocol/ 

2 

3from base64 import b64encode, b64decode 

4import sys 

5from typing import Union 

6 

7def _supports_kitty_graphics() -> bool: 

8 import platform 

9 

10 if platform.system() not in ("Darwin", "Linux"): 

11 return False 

12 

13 isatty = getattr(sys.stdout, "isatty", None) 

14 if not callable(isatty) or not isatty(): 

15 return False 

16 # Hardcoding process names instead of using 

17 # https://sw.kovidgoyal.net/kitty/graphics-protocol/#querying-support-and-available-transmission-mediums 

18 # to avoid startup slowdown 

19 supported_terminals = { 

20 "ghostty", 

21 "iTerm2", 

22 "kitty", 

23 "konsole", 

24 "warp", 

25 "wayst", 

26 "wezterm-gui", 

27 } 

28 import psutil 

29 

30 process = psutil.Process() 

31 while process := process.parent(): 

32 if process.name() in supported_terminals: 

33 return True 

34 return False 

35 

36 

37supports_kitty_graphics = _supports_kitty_graphics() 

38 

39 

40def png_to_kitty_ansi(png: bytes) -> str: 

41 if not png.startswith(b"\x89PNG\r\n\x1a\n"): 

42 raise ValueError 

43 # This simplicity resembles 

44 # https://sw.kovidgoyal.net/kitty/graphics-protocol/#a-minimal-example 

45 # but if we need tmux support, we can switch to Unicode like 

46 # https://github.com/hzeller/timg/blob/main/src/kitty-canvas.cc 

47 result = ["\033_Ga=T,f=100,", "m=1;"] 

48 encoded = b64encode(png) 

49 for i in range(0, len(encoded), 4096): 

50 result.append(encoded[i : i + 4096].decode("ascii")) 

51 result.append("\033\\") 

52 result.append("\033_G") 

53 result.append("m=1;") 

54 del result[-2:] 

55 result[-3] = "m=0;" 

56 return "".join(result) 

57 

58 

59def kitty_png_render(png: Union[bytes, str], _md_dict: object) -> None: 

60 if isinstance(png, str): 

61 png = png_to_kitty_ansi(b64decode(png)) 

62 else: 

63 png = png_to_kitty_ansi(png) 

64 print(png) 

65 

66 

67display_formatter_default_active_types = [ 

68 "text/plain", 

69 *(["image/png"] if supports_kitty_graphics else []), 

70] 

71 

72terminal_default_mime_renderers = { 

73 "image/png": kitty_png_render, 

74}