immapp_code_utils.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from imgui_bundle import immapp
  2. import inspect
  3. import json
  4. from typing import Any
  5. SnippetData = immapp.snippets.SnippetData
  6. def show_python_code(
  7. python_object: object, # can be a class, function, module, etc.
  8. read_only: bool = True,
  9. height_in_lines: int | None = None,
  10. max_height_in_lines: int | None = None,
  11. show_cursor_position: bool | None = None,
  12. de_indent_code: bool | None = None,
  13. show_copy_button: bool | None = None,
  14. palette: immapp.snippets.SnippetTheme | None = immapp.snippets.SnippetTheme.dark,
  15. border: bool | None = None,
  16. ) -> None:
  17. """Render the code of an object as a markdown code block"""
  18. statics = show_python_code
  19. if not hasattr(statics, "_ALL_PYTHON_SNIPPETS"):
  20. statics._ALL_PYTHON_SNIPPETS: dict[object, SnippetData] = {} # type: ignore
  21. if python_object not in statics._ALL_PYTHON_SNIPPETS:
  22. snippet_data = SnippetData()
  23. snippet_data.displayed_filename = str(python_object)
  24. snippet_data.code = inspect.getsource(python_object) # type: ignore
  25. snippet_data.language = immapp.snippets.SnippetLanguage.python
  26. if read_only is not None:
  27. snippet_data.read_only = read_only
  28. if height_in_lines is not None:
  29. snippet_data.height_in_lines = height_in_lines
  30. if max_height_in_lines is not None:
  31. snippet_data.max_height_in_lines = max_height_in_lines
  32. if show_cursor_position is not None:
  33. snippet_data.show_cursor_position = show_cursor_position
  34. if de_indent_code is not None:
  35. snippet_data.de_indent_code = de_indent_code
  36. if show_copy_button is not None:
  37. snippet_data.show_copy_button = show_copy_button
  38. if palette is not None:
  39. snippet_data.palette = palette
  40. if border is not None:
  41. snippet_data.border = border
  42. statics._ALL_PYTHON_SNIPPETS[python_object] = snippet_data
  43. cached_snippet_data = statics._ALL_PYTHON_SNIPPETS[python_object]
  44. immapp.snippets.show_code_snippet(cached_snippet_data)
  45. def _compact_json(data: Any, indent: int = 4) -> str:
  46. def _compact_list(lst: Any, indent_level: int) -> str:
  47. compacted = json.dumps(lst)
  48. if len(compacted) <= 80:
  49. return compacted
  50. return json.dumps(lst, indent=indent, separators=(',', ': '))
  51. def _compact_dict(dct: Any, indent_level: int) -> str:
  52. items = []
  53. for key, value in dct.items():
  54. key_str = json.dumps(key) + ': '
  55. value_str = (
  56. _compact_list(value, indent_level + 1)
  57. if isinstance(value, list)
  58. else json.dumps(value, indent=indent, separators=(',', ': '))
  59. )
  60. items.append('\n' + ' ' * indent_level * indent + key_str + value_str)
  61. return '{' + ','.join(items) + '\n' + ' ' * (indent_level - 1) * indent + '}'
  62. return _compact_dict(data, 1)
  63. def show_json_dict(json_dict: dict[str, Any]) -> None:
  64. from imgui_bundle import imgui_md
  65. """Render a json dict as a markdown code block"""
  66. md_string = "```\n" + _compact_json(json_dict, indent=4) + "\n```"
  67. imgui_md.render(md_string)