Inspecting klipper objects and printing contents

Yeah i dont know how much more there is to say about this.
allows you to lookup objects and look at them, automatically calls methods starting with ‘get_’ that only take self or eventtime… dunno if that will ever cause issues, if it does, feel free to remove it.

Its not typescript. i just choose typescript because every other highlighting was broken.

How to use?

INSPECT_OBJECT O=<your_object>
(toolhead for example)

[gcode_macro INSPECT_OBJECT]
description: "Usage: INSPECT_OBJECT O=<name> [F=<filter>] [DUNDER=1]"
variable_color_attr:            "rgb(150, 220, 255)"
variable_color_method:          "rgb(130, 255, 150)"
variable_color_private_method:  "rgb(180, 220, 180)"
variable_color_getter:          "rgb(255, 200, 100)"
variable_color_command:         "rgb(255, 160, 122)"
variable_color_val:             "rgb(240, 240, 240)"
variable_color_type:            "rgb(160, 160, 160)"
variable_color_doc:             "rgb(140, 160, 140)"
variable_color_klipper_obj:     "rgba(255, 130, 80, 0.6)"
variable_color_container:       "rgb(210, 180, 255)"
variable_color_arg_self:        "rgb(255, 110, 180)"
variable_color_arg_other:       "rgb(137, 207, 240)"
variable_val_cutoff:            200
variable_font_size:             "0.8em"
gcode:
    {%- set p = printer.printer -%}
    {%- set obj_name = params.O|default(params.OBJECT|default(None)) -%}
    {%- if obj_name is none -%} {action_raise_error("Usage: INSPECT_OBJECT O=<name>")} {%- endif -%}

    # find the closest match if it didnt exactly match
    {%- set obj = p.lookup_object(obj_name, None) -%}
    {%- if obj is none -%}
        {%- set ns = namespace(best_match_obj=None, best_match_name=None) -%}
        {%- set search_lower = obj_name|lower -%}
        {%- for candidate_name, candidate_obj in p.lookup_objects() if search_lower in candidate_name|lower -%}
            {%- if ns.best_match_name is none or candidate_name|length < ns.best_match_name|length -%}
                {%- set ns.best_match_obj = candidate_obj -%}
                {%- set ns.best_match_name = candidate_name -%}
            {%- endif -%}
        {%- endfor -%}
        {%- if ns.best_match_obj is not none -%}
            {action_respond_info("Object '" ~ obj_name|e ~ "' not found. Using best match: '" ~ ns.best_match_name|e ~ "'")}
            {%- set obj = ns.best_match_obj -%}
            {%- set obj_name = ns.best_match_name -%}
        {%- else -%}
            {action_respond_info("Object '" ~ obj_name|e ~ "' not found. No partial matches found either.")}
            {%- set obj = {} -%}
        {%- endif -%}
    {%- endif -%}

    #-------------------------------------------------------------------------------------------------------------------------------------
    # just small helpers
    {%- macro _span(color, txt) -%}
        {"<span style='color:" ~ color ~ "'>" ~ txt|e ~ "</span>"}
    {%- endmacro -%}
    {%- macro _details(summary, content, is_open=False) -%}
        {"<details" ~ (" open" if is_open else "") ~ "><summary style='cursor:pointer;'>" ~ summary ~ "</summary><div style='padding-left: 20px; border-left: 1px solid rgb(51, 51, 51);'>" ~ content ~ "</div></details>"}
    {%- endmacro -%}

    # render values
    {%- macro _render_value(val, as_string=False) -%}
        {%- set type_name = val.__class__.__name__ -%}
        {%- set val_str_raw = val|string -%}
        {%- if as_string -%}
            {%- if val is none -%}None
            {%- elif val is sameas True or val is sameas False -%}{val|string}
            {%- elif val is mapping -%}{"{...}"}
            {%- elif val is sequence and val is not string -%}{"[...]" }
            {%- elif '<' in val_str_raw and 'object at 0x' in val_str_raw -%}{"<" ~ type_name ~ ">"}
            {%- else -%}{ "'" ~ val_str_raw|truncate(30) ~ "'" }
            {%- endif -%}
        {%- else -%}
            {%- if val is none -%} {_span(color_val, 'None') ~ " " ~ _span(color_type, '(NoneType)')}
            {%- elif val is sameas True or val is sameas False -%} {_span(color_val, val|string) ~ " " ~ _span(color_type, '(bool)')}
            {%- elif val is mapping -%}
                {%- set summary = _span(color_container, "(dict, " ~ val|length ~ " items)") -%}
                {%- set items = [] -%}
                {%- for k, v in val.items() -%}{%- set _ = items.append("<div style='display: flex; align-items: baseline;'>" ~ _span(color_attr, k|string ~ ": ") ~ _render_value(v) ~ "</div>") -%}{%- endfor -%}
                {_details(summary, items|join(''))}
            {%- elif val is sequence and val is not string -%}
                {%- set summary = _span(color_container, "(list, " ~ val|length ~ " items)") -%}
                {%- set items = [] -%}
                {%- for item in val -%}{%- set _ = items.append("<div style='display: flex; align-items: baseline;'>" ~ _span(color_type, "[" ~ loop.index0 ~ "]: ") ~ _render_value(item) ~ "</div>") -%}{%- endfor -%}
                {_details(summary, items|join(''))}
            {%- elif '<' in val_str_raw and 'object at 0x' in val_str_raw -%}{ _span(color_klipper_obj, "<" ~ type_name ~ ">") }
            {%- else -%}
                {%- set val_str = val_str_raw -%}
                {%- if val_str|length > val_cutoff -%}{%- set val_str = val_str[:val_cutoff] ~ '…' -%}{%- endif -%}
                { _span(color_val, "'" ~ val_str ~ "'") ~ " " ~ _span(color_type, "(" ~ type_name ~ ")") }
            {%- endif -%}
        {%- endif -%}
    {%- endmacro -%}

    # render method/function + signature
    {%- macro _render_callable(callable_obj, name, color, override_doc=None) -%}
        {%- if callable_obj.__code__.co_varnames is defined -%}
            {%- set signature_html = [] -%}
            {%- set code = callable_obj.__code__ -%}
            {%- set defaults = callable_obj.__defaults__ or () -%}
            {%- set arg_names = code.co_varnames[:code.co_argcount] -%}
            {%- set first_default_idx = arg_names|length - defaults|length -%}
            {%- for i in range(arg_names|length) -%}
                {%- set arg_name = arg_names[i] -%}
                {%- set arg_color = color_arg_self if arg_name == 'self' else color_arg_other -%}
                {%- if i >= first_default_idx -%}
                    {%- set default_val_str = _render_value(defaults[i - first_default_idx], as_string=True) -%}
                    {%- set _ = signature_html.append(_span(arg_color, arg_name) ~ "=" ~ _span(color_val, default_val_str)) -%}
                {%- else -%}
                    {%- set _ = signature_html.append(_span(arg_color, arg_name)) -%}
                {%- endif -%}
            {%- endfor -%}
            {%- set doc = override_doc or callable_obj.__doc__|string|trim -%}
            {%- set full_signature = _span(color, name ~ "(") ~ signature_html|join(', ') ~ _span(color, ")") -%}
            {%- if doc and doc != 'None' -%}
                {%- set doc_html = _span(color_doc, " // " ~ doc|replace('\n', ' ')|truncate(100)) -%}
                {full_signature ~ doc_html}
            {%- else -%}
                {full_signature}
            {%- endif -%}
        {%- else -%}
            {%- set type_name = callable_obj.__class__.__name__ -%}
            {_span(color, name ~ "(i dunno)") ~ _span(color_type, "<" ~ type_name ~ ">")}
        {%- endif -%}
    {%- endmacro -%}

    #-------------------------------------------------------------------------------------------------------------------------------------
    {%- set attributes, public_methods, private_methods, getters, commands, output = [], [], [], [], [], [] -%}
    {%- set filt = params.F|default("")|lower -%}
    {%- set help_strings = {} -%}

    {%- if obj -%}
        # find _help to attatch later
        {%- for attr_name in obj.__dir__() -%}
            {%- if attr_name.startswith('cmd_') and attr_name.endswith('_help') -%}
                {%- set _ = help_strings.update({attr_name|replace('_help', ''): obj|attr(attr_name)}) -%}
            {%- endif -%}
        {%- endfor -%}
        
        # main loop
        {%- for attr_name in obj.__dir__()|sort -%}
            {%- if (not attr_name.startswith('__') or params.DUNDER) and (not filt or filt in attr_name|lower) and not attr_name.endswith('_help') -%}
                {%- set attr_val = obj|attr(attr_name) -%}
                {%- if attr_val.__code__ is defined and attr_val.__code__.co_varnames is defined -%}
                    {%- set doc = help_strings.get(attr_name, None) -%}
                    {%- if attr_name.startswith('get_') -%}
                        {%- set code = attr_val.__code__ -%}
                        {%- if code.co_argcount == 2 and code.co_varnames[1] == 'eventtime' or code.co_argcount == 1 -%}
                            {%- set return_val = attr_val(p.get_reactor().monotonic()) if code.co_argcount != 1 else attr_val() -%}
                            {%- set status_html = _render_callable(attr_val, attr_name, color_getter) ~ ': ' ~ _render_value(return_val) -%}
                            {%- set _ = getters.append( "<div style='display: flex; align-items: baseline;'>" ~ status_html ~ "</div>") -%}
                        {%- else -%}
                            {%- set _ = getters.append(_render_callable(attr_val, attr_name, color_getter, doc)) -%}
                        {%- endif -%}
                    {%- elif attr_name.startswith('cmd_') -%} {%- set _ = commands.append(       _render_callable(attr_val, attr_name, color_command,        doc)) -%}
                    {%- elif attr_name.startswith('_') -%}    {%- set _ = private_methods.append(_render_callable(attr_val, attr_name, color_private_method, doc)) -%}
                    {%- else -%}                              {%- set _ = public_methods.append( _render_callable(attr_val, attr_name, color_method,         doc)) -%}
                    {%- endif -%}
                {%- elif attr_val is callable -%}
                    {%- set type_name = attr_val.__class__.__name__ -%}
                    {%- set fallback_html = "<div>" ~ _span(color_private_method, attr_name ~ "(i dunno)") ~ _span(color_type, "<"|e ~ type_name) ~ ">"|e ~ "</div>" -%}
                    {%- set _ = private_methods.append(fallback_html) if attr_name.startswith('_') else public_methods.append(fallback_html) -%}
                {%- else -%}
                    {%- set attr_html = "<div style='display: flex; align-items: baseline;'>" ~ _span(color_attr, attr_name ~ ": ") ~ _render_value(attr_val) ~ "</div>" -%}
                    {%- set _ = attributes.append(attr_html) -%}
                {%- endif -%}
            {%- endif -%}
        {%- endfor -%}
    {%- endif -%}
    
    #--- Assemble and Print Report ---
    {%- set _ = output.append(_details(_span(color_attr,           "Attributes (" ~      attributes|length ~ ")"), attributes|sort|join(''))) if attributes else '' -%}
    {%- set _ = output.append(_details(_span(color_getter,         "Getters (" ~         getters|length ~ ")"), "<div>" ~ getters|sort|join('</div><div>') ~ "</div>")) if getters else '' -%}
    {%- set _ = output.append(_details(_span(color_command,        "Commands (" ~        commands|length ~ ")"), "<div>" ~ commands|sort|join('</div><div>') ~ "</div>")) if commands else '' -%}
    {%- set _ = output.append(_details(_span(color_method,         "Public Methods (" ~  public_methods|length ~ ")"), "<div>" ~ public_methods|sort|join('</div><div>') ~ "</div>")) if public_methods else '' -%}
    {%- set _ = output.append(_details(_span(color_private_method, "Private Methods (" ~ private_methods|length ~ ")"), "<div>" ~ private_methods|sort|join('</div><div>') ~ "</div>")) if private_methods else '' -%}

    {%- set title = "<b>Inspecting Object: '" ~ obj_name|e ~ "'</b>" -%}
    {%- set report = _details(title, output|join(''), is_open=True) -%}
    # may klipper forgive me for shitting literal megabytes to the console in one respond
    {action_respond_info("<div style='font-size: " ~ font_size ~ ";'>" ~ report ~ "</div>")} #font-family: monospace;