@@ -872,6 +872,68 @@ def _add_to_tree(node, top):
872872 )
873873
874874
875+ def _get_force_info (sym ):
876+ # Returns a string indicating what's forcing a symbol's value, or None
877+ # if the value is not being forced by select/imply.
878+ #
879+ # Example return values:
880+ # " [selected by FOO]"
881+ # " [implied by BAR, BAZ]"
882+
883+ if sym .orig_type not in (BOOL , TRISTATE ):
884+ return None
885+
886+ origin = sym .origin
887+ if not origin :
888+ return None
889+
890+ kind , sources = origin
891+ if kind not in ("select" , "imply" ) or not sources :
892+ return None
893+
894+ # Format the force info string
895+ prefix = "selected by" if kind == "select" else "implied by"
896+ sym_names = _extract_controlling_symbols (sources )
897+
898+ if not sym_names :
899+ return None
900+
901+ # Show up to 2 symbols to keep line length reasonable
902+ if len (sym_names ) <= 2 :
903+ return " [{} {}]" .format (prefix , ", " .join (sym_names ))
904+
905+ return " [{} {}, +{}]" .format (prefix , ", " .join (sym_names [:2 ]), len (sym_names ) - 2 )
906+
907+
908+ def _extract_controlling_symbols (expr_list ):
909+ # Extracts the primary controlling symbol from each expression string
910+ # Returns a list of unique symbol names
911+ #
912+ # For "A && B", extracts "A" (the symbol doing the select/imply)
913+ # For "A || B", extracts both "A" and "B"
914+ # For simple "A", extracts "A"
915+ #
916+ # This avoids showing condition symbols as if they're doing the select/imply
917+
918+ sym_names = []
919+ for expr in expr_list :
920+ # Split on && first - we only want symbols before &&
921+ # For "FOO && BAR", we want FOO (the selector), not BAR (the condition)
922+ and_idx = expr .find (" && " )
923+ primary = expr [:and_idx ].strip () if and_idx != - 1 else expr .strip ()
924+
925+ # Now handle || - all parts are equal
926+ if " || " in primary :
927+ for part in primary .split (" || " ):
928+ part = part .strip ()
929+ if part and part not in sym_names :
930+ sym_names .append (part )
931+ elif primary and primary not in sym_names :
932+ sym_names .append (primary )
933+
934+ return sym_names
935+
936+
875937def _node_str (node ):
876938 # Returns the string shown to the right of the image (if any) for the node
877939
@@ -895,6 +957,11 @@ def _node_str(node):
895957
896958 s += " (NEW)"
897959
960+ # Show what's controlling this symbol if it's selected/implied
961+ force_info = _get_force_info (sym )
962+ if force_info :
963+ s += force_info
964+
898965 elif isinstance (node .item , Symbol ):
899966 # Symbol without prompt (can show up in show-all)
900967 s = "<{}>" .format (node .item .name )
@@ -2216,10 +2283,27 @@ def _value_info(sym):
22162283 # Returns a string showing 'sym's value
22172284
22182285 # Only put quotes around the value for string symbols
2219- return "Value: {}\n " .format (
2286+ s = "Value: {}\n " .format (
22202287 '"{}"' .format (sym .str_value ) if sym .orig_type == STRING else sym .str_value
22212288 )
22222289
2290+ # Add origin information to explain where the value comes from
2291+ origin = sym .origin
2292+ if origin :
2293+ kind , sources = origin
2294+ if kind == "select" :
2295+ if sources :
2296+ s += " (selected by: {})\n " .format (", " .join (sources ))
2297+ elif kind == "imply" :
2298+ if sources :
2299+ s += " (implied by: {})\n " .format (", " .join (sources ))
2300+ elif kind == "default" :
2301+ s += " (from default)\n "
2302+ elif kind == "assign" :
2303+ s += " (user assigned)\n "
2304+
2305+ return s
2306+
22232307
22242308def _choice_syms_info (choice ):
22252309 # Returns a string listing the choice symbols in 'choice'. Adds
0 commit comments