In :browse, always print output in the *current* context
authorSimon Peyton Jones <simonpj@microsoft.com>
Mon, 22 Aug 2011 06:57:50 +0000 (07:57 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Mon, 22 Aug 2011 06:57:50 +0000 (07:57 +0100)
Previously :browse M (without !) printed output relative to
a context that was neither the current one, nor the top-level
context of M, but rather that established
by
     import Prelude
     import M
This was pretty confusing, so Simon and I agreed to use
a simple, uniform rule: output in GHC is always relative
to the current context.

docs/users_guide/ghci.xml
ghc/InteractiveUI.hs

index 62522e8..581b918 100644 (file)
@@ -1873,28 +1873,36 @@ $ ghci -lm
           <indexterm><primary><literal>:browse</literal></primary></indexterm>
         </term>
        <listitem>
-         <para>Displays the identifiers defined by the module
+         <para>Displays the identifiers exported by the module
          <replaceable>module</replaceable>, which must be either
          loaded into GHCi or be a member of a package.  If
          <replaceable>module</replaceable> is omitted, the most
          recently-loaded module is used.</para>
 
-          <para>If the <literal>*</literal> symbol is placed before
-         the module name, then <emphasis>all</emphasis> the
-         identifiers in scope in <replaceable>module</replaceable> are
-         shown; otherwise the list is limited to the exports of
-         <replaceable>module</replaceable>.  The
-         <literal>*</literal>-form is only available for modules
-         which are interpreted; for compiled modules (including
-         modules from packages) only the non-<literal>*</literal>
-    form of <literal>:browse</literal> is available.
-    If the <literal>!</literal> symbol is appended to the
-    command, data constructors and class methods will be
-    listed individually, otherwise, they will only be listed
-    in the context of their data type or class declaration.
-    The <literal>!</literal>-form also annotates the listing
-    with comments giving possible imports for each group of
-    entries.</para>
+         <para>Like all other GHCi commands, the output is always 
+          displayed in the current GHCi scope (<xref linkend="ghci-scope"/>).</para>
+
+          <para>There are two variants of the browse command:
+          <itemizedlist>
+          <listitem>  
+             <para>If the <literal>*</literal> symbol is placed before
+            the module name, then <emphasis>all</emphasis> the
+            identifiers in scope in <replaceable>module</replaceable> 
+             (rather that just its exports) are shown. </para>
+
+             <para>The <literal>*</literal>-form is only available for modules
+            which are interpreted; for compiled modules (including
+            modules from packages) only the non-<literal>*</literal>
+             form of <literal>:browse</literal> is available.</para>
+          </listitem>
+          <listitem>Data constructors and class methods are usually
+          displayed in the context of their data type or class declaration.
+          However, if the <literal>!</literal> symbol is appended to the
+          command, thus <literal>:browse!</literal>, 
+          they are listed individually. 
+         The <literal>!</literal>-form also annotates the listing
+         with comments giving possible imports for each group of
+         entries.  Here is an example:
 <screen>
 Prelude> :browse! Data.Maybe
 -- not currently imported
@@ -1912,15 +1920,15 @@ data Maybe a = Nothing | Just a
 Nothing :: Maybe a
 maybe :: b -> (a -> b) -> Maybe a -> b
 </screen>
-  <para>
-    This output shows that, in the context of the current session, in the scope
-    of <literal>Prelude</literal>, the first group of items from
-    <literal>Data.Maybe</literal> have not been imported (but are available in
+    This output shows that, in the context of the current session (ie in the scope
+    of <literal>Prelude</literal>), the first group of items from
+    <literal>Data.Maybe</literal> are not in scope (althought they are available in
     fully qualified form in the GHCi session - see <xref
-      linkend="ghci-scope"/>), whereas the second group of items have been
-    imported via <literal>Prelude</literal> and are therefore available either
+      linkend="ghci-scope"/>), whereas the second group of items are in scope
+    (via <literal>Prelude</literal>) and are therefore available either
     unqualified, or with a <literal>Prelude.</literal> qualifier.
   </para>
+          </listitem>
        </listitem>
       </varlistentry>
 
index 7339acc..328cfbb 100644 (file)
@@ -32,7 +32,7 @@ import StringBuffer
 import Packages
 import UniqFM
 
-import HscTypes ( handleFlagWarnings, getSafeMode, dep_pkgs )
+import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, dep_pkgs )
 import HsImpExp
 import RdrName ( RdrName, getGRE_NameQualifier_maybes )
 import Outputable hiding ( printForUser, printForUserPartWay, bold )
@@ -924,7 +924,7 @@ filterOutChildren get_thing xs
   = filterOut has_parent xs
   where
     all_names = mkNameSet (map (getName . get_thing) xs)
-    has_parent x = case pprTyThingParent_maybe (get_thing x) of
+    has_parent x = case tyThingParent_maybe (get_thing x) of
                      Just p  -> getName p `elemNameSet` all_names
                      Nothing -> False
 
@@ -1397,21 +1397,8 @@ guessCurrentModule
 -- with sorted, sort items alphabetically
 browseModule :: Bool -> Module -> Bool -> InputT GHCi ()
 browseModule bang modl exports_only = do
-  -- :browse! reports qualifiers wrt current context
-  current_unqual <- GHC.getPrintUnqual
-
-  -- Temporarily set the context to the module we're interested in,
-  -- just so we can get an appropriate PrintUnqualified
-  -- Use mySetContext so we get an implicit Prelude import 
-  -- for the PrintUnqualified
-  imports <- GHC.getContext
-  lift $ mySetContext (if exports_only 
-                       then [IIDecl $ simpleImportDecl (GHC.moduleName modl)]
-                       else [IIModule modl])
-  target_unqual <- GHC.getPrintUnqual
-  GHC.setContext imports
-
-  let unqual = if bang then current_unqual else target_unqual
+  -- :browse reports qualifiers wrt current context
+  unqual <- GHC.getPrintUnqual
 
   mb_mod_info <- GHC.getModuleInfo modl
   case mb_mod_info of
@@ -1453,10 +1440,14 @@ browseModule bang modl exports_only = do
 
             labels  [] = text "-- not currently imported"
             labels  l  = text $ intercalate "\n" $ map qualifier l
+
+           qualifier :: Maybe [ModuleName] -> String
             qualifier  = maybe "-- defined locally" 
                              (("-- imported via "++) . intercalate ", " 
                                . map GHC.moduleNameString)
-            importInfo = getGRE_NameQualifier_maybes rdr_env
+            importInfo = RdrName.getGRE_NameQualifier_maybes rdr_env
+
+           modNames :: [[Maybe [ModuleName]]]
             modNames   = map (importInfo . GHC.getName) things
                                         
             -- annotate groups of imports with their import modules
@@ -1471,7 +1462,8 @@ browseModule bang modl exports_only = do
             group mts@((m,_):_) = (m,map snd g) : group ng
               where (g,ng) = partition ((==m).fst) mts
 
-        let prettyThings = map (pretty pefas) things
+        let prettyThings, prettyThings' :: [SDoc]
+            prettyThings = map (pretty pefas) things
             prettyThings' | bang      = annotate $ zip modNames prettyThings
                           | otherwise = prettyThings
         liftIO $ putStrLn $ showSDocForUser unqual (vcat prettyThings')