+info :: String -> GHCi ()
+info "" = throwDyn (CmdLineError "syntax: `:i <thing-you-want-info-about>'")
+info s = do
+ let names = words s
+ state <- getGHCiState
+ dflags <- io getDynFlags
+ let
+ infoThings cms [] = return cms
+ infoThings cms (name:names) = do
+ (cms, unqual, stuff) <- io (cmInfoThing cms dflags name)
+ io (putStrLn (showSDocForUser unqual (
+ vcat (intersperse (text "") (map showThing stuff))))
+ )
+ infoThings cms names
+
+ showThing (ty_thing, fixity)
+ = vcat [ text "-- " <> showTyThing ty_thing,
+ showFixity fixity (getName ty_thing),
+ ppr (ifaceTyThing ty_thing) ]
+
+ showFixity fix name
+ | fix == defaultFixity = empty
+ | otherwise = ppr fix <+>
+ (if isSymOcc (nameOccName name)
+ then ppr name
+ else char '`' <> ppr name <> char '`')
+
+ showTyThing (AClass cl)
+ = hcat [ppr cl, text " is a class", showSrcLoc (className cl)]
+ showTyThing (ATyCon ty)
+ | isPrimTyCon ty
+ = hcat [ppr ty, text " is a primitive type constructor"]
+ | otherwise
+ = hcat [ppr ty, text " is a type constructor", showSrcLoc (tyConName ty)]
+ showTyThing (AnId id)
+ = hcat [ppr id, text " is a ", idDescr id, showSrcLoc (idName id)]
+
+ idDescr id
+ | isRecordSelector id =
+ case tyConClass_maybe (fieldLabelTyCon (
+ recordSelectorFieldLabel id)) of
+ Nothing -> text "record selector"
+ Just c -> text "method in class " <> ppr c
+ | isDataConWrapId id = text "data constructor"
+ | otherwise = text "variable"
+
+ -- also print out the source location for home things
+ showSrcLoc name
+ | isHomePackageName name && isGoodSrcLoc loc
+ = hsep [ text ", defined at", ppr loc ]
+ | otherwise
+ = empty
+ where loc = nameSrcLoc name
+
+ cms <- infoThings (cmstate state) names
+ setGHCiState state{ cmstate = cms }
+ return ()
+
+