Commit cd3d6f88 authored by Simon Peyton Jones's avatar Simon Peyton Jones

In :browse, always print output in the *current* context

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.
parent d65efb22
......@@ -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>
......
......@@ -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')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment