@@ -3453,10 +3453,27 @@ def _value_info(sym):
3453
3453
# Returns a string showing 'sym's value
3454
3454
3455
3455
# Only put quotes around the value for string symbols
3456
- return "Value: {}\n " .format (
3456
+ s = "Value: {}\n " .format (
3457
3457
'"{}"' .format (sym .str_value ) if sym .orig_type == STRING else sym .str_value
3458
3458
)
3459
3459
3460
+ # Add origin information to explain where the value comes from
3461
+ origin = sym .origin
3462
+ if origin :
3463
+ kind , sources = origin
3464
+ if kind == "select" :
3465
+ if sources :
3466
+ s += " (selected by: {})\n " .format (", " .join (sources ))
3467
+ elif kind == "imply" :
3468
+ if sources :
3469
+ s += " (implied by: {})\n " .format (", " .join (sources ))
3470
+ elif kind == "default" :
3471
+ s += " (from default)\n "
3472
+ elif kind == "assign" :
3473
+ s += " (user assigned)\n "
3474
+
3475
+ return s
3476
+
3460
3477
3461
3478
def _choice_syms_info (choice ):
3462
3479
# Returns a string listing the choice symbols in 'choice'. Adds
@@ -3818,6 +3835,68 @@ def _error(text):
3818
3835
_msg ("Error" , text )
3819
3836
3820
3837
3838
+ def _get_force_info (sym ):
3839
+ # Returns a string indicating what's forcing a symbol's value, or None
3840
+ # if the value is not being forced by select/imply.
3841
+ #
3842
+ # Example return values:
3843
+ # " [selected by FOO]"
3844
+ # " [implied by BAR, BAZ]"
3845
+
3846
+ if sym .orig_type not in (BOOL , TRISTATE ):
3847
+ return None
3848
+
3849
+ origin = sym .origin
3850
+ if not origin :
3851
+ return None
3852
+
3853
+ kind , sources = origin
3854
+ if kind not in ("select" , "imply" ) or not sources :
3855
+ return None
3856
+
3857
+ # Format the force info string
3858
+ prefix = "selected by" if kind == "select" else "implied by"
3859
+ sym_names = _extract_controlling_symbols (sources )
3860
+
3861
+ if not sym_names :
3862
+ return None
3863
+
3864
+ # Show up to 2 symbols to keep line length reasonable
3865
+ if len (sym_names ) <= 2 :
3866
+ return " [{} {}]" .format (prefix , ", " .join (sym_names ))
3867
+
3868
+ return " [{} {}, +{}]" .format (prefix , ", " .join (sym_names [:2 ]), len (sym_names ) - 2 )
3869
+
3870
+
3871
+ def _extract_controlling_symbols (expr_list ):
3872
+ # Extracts the primary controlling symbol from each expression string
3873
+ # Returns a list of unique symbol names
3874
+ #
3875
+ # For "A && B", extracts "A" (the symbol doing the select/imply)
3876
+ # For "A || B", extracts both "A" and "B"
3877
+ # For simple "A", extracts "A"
3878
+ #
3879
+ # This avoids showing condition symbols as if they're doing the select/imply
3880
+
3881
+ sym_names = []
3882
+ for expr in expr_list :
3883
+ # Split on && first - we only want symbols before &&
3884
+ # For "FOO && BAR", we want FOO (the selector), not BAR (the condition)
3885
+ and_idx = expr .find (" && " )
3886
+ primary = expr [:and_idx ].strip () if and_idx != - 1 else expr .strip ()
3887
+
3888
+ # Now handle || - all parts are equal
3889
+ if " || " in primary :
3890
+ for part in primary .split (" || " ):
3891
+ part = part .strip ()
3892
+ if part and part not in sym_names :
3893
+ sym_names .append (part )
3894
+ elif primary and primary not in sym_names :
3895
+ sym_names .append (primary )
3896
+
3897
+ return sym_names
3898
+
3899
+
3821
3900
def _node_str (node ):
3822
3901
# Returns the complete menu entry text for a menu node.
3823
3902
#
@@ -3863,6 +3942,11 @@ def _node_str(node):
3863
3942
3864
3943
s += " (NEW)"
3865
3944
3945
+ # Show what's controlling this symbol if it's selected/implied
3946
+ force_info = _get_force_info (sym )
3947
+ if force_info :
3948
+ s += force_info
3949
+
3866
3950
if isinstance (node .item , Choice ) and node .item .tri_value == 2 :
3867
3951
# Print the prompt of the selected symbol after the choice for
3868
3952
# choices in y mode
0 commit comments