Skip to main content
6 of 6
added 95 characters in body
Szabolcs
  • 238.9k
  • 32
  • 653
  • 1.3k

Link to the code on GitHub


I have been using this. It's mostly Leonid's code from the stackoverflow question you linked to, but it uses Definition instead of DownValues. Symbol names are printed without any context, but the full symbol name is put into a Tooltip so you can always find out what context a symbol is in.

Update

FullDefinition[symbol] claims to "print the definitions given for symbol, and all symbols on which these depend", but sometimes one wants to explore deeper than the first level of dependency. Here is a version of Spelunk which uses plain Definition instead of FullDefinition, but allows you to click on symbols in the definition to get their definition. So you can dig right down into the dependency chain.

Update 2

The code now copes with definitions containing strings with backticks in, and cases where Definition throws an error.

Also, it now works for symbols which have OwnValues, e.g. Internal`$VideoEncodings.

BeginPackage["Spelunk`"]; Spelunk::usage = "Spelunk[symbol]"; Begin["`Private`"]; defboxes[symbol_Symbol] := Hold[symbol] /. _[sym_] :> If[MemberQ[Attributes[sym], Locked], "Locked", Internal`InheritedBlock[{sym}, Unprotect[sym]; ClearAttributes[sym, ReadProtected]; Quiet@Check[ToBoxes[Definition@sym], "DefError"] /. InterpretationBox[a_, b___] :> a ]]; defboxes[s_String] := defboxes[#] &@ToExpression[s, InputForm, Unevaluated] prettyboxes[boxes_] := boxes /. {" "} -> {"\n-----------\n"} //. {RowBox[{left___, ";", next : Except["\n"], right___}] :> RowBox[{left, ";", "\n", "\t", next, right}], RowBox[{sc : ("Block" | "Module" | "With"), "[", RowBox[{vars_, ",", body_}], "]"}] :> RowBox[{sc, "[", RowBox[{vars, ",", "\n\t", body}], "]"}]}; fancydefinition[symbol_Symbol] := Cell[BoxData[ prettyboxes[ defboxes[symbol] /. s_String?(StringMatchQ[#, __ ~~ "`" ~~ __] &) :> First@StringCases[s, a : (__ ~~ "`" ~~ b__) :> processsymbol[a, b]]]], "Output", Background -> RGBColor[1, 0.95, 0.9], CellGroupingRules->"OutputGrouping", GeneratedCell->True, CellAutoOverwrite->True, ShowAutoStyles->True, LanguageCategory->"Mathematica", FontWeight->"Bold" ]; processsymbol[a_, b_] := Module[{db}, Which[ ! StringFreeQ[a, "\""], a, ! StringFreeQ[a, "_"] || (db = defboxes[a]) === "Null", TooltipBox[b, a], db === "Locked", TooltipBox[b, a <> "\nLocked Symbol"], db === "DefError", TooltipBox[b, a <> "\nError getting Definition"], True, ButtonBox[TooltipBox[b, a], ButtonFunction :> Spelunk@a, BaseStyle -> {}, Evaluator -> Automatic]]] Spelunk[symbol_Symbol] := CellPrint[fancydefinition[symbol]]; Spelunk[s_String] := CellPrint[fancydefinition[#] &@ToExpression[s, InputForm, Unevaluated]]; SetAttributes[{defboxes, fancydefinition, Spelunk}, HoldFirst] End[]; EndPackage[]; 
Simon Woods
  • 85.9k
  • 8
  • 183
  • 332