Using the GHC API: pretty printing with qualified names
Claus Reinke
claus.reinke at talk21.com
Thu Nov 18 04:53:05 EST 2010
> scion-server mimics a GHCi command line, of sorts. scion-server
> is used very successfully to syntax-highlight the Eclipse editor,
> show a source's outline, provide type information when hovering
> over a name, and provide completions.
> That's not the problem, per se. Let's say I'm hovering over a
> function that's imported by Data.Map. When resolved, the
> symbols appear to come from Ghc.Map (if memory serves
> correctly), which makes finding the correct "haddock" impossible.
"Impossible" is such an ugly word;-)
The problem you encounter is that the GHC API is still, to a
large part, just an open window into what happens to be
in GHC. Since GHC's aims as a compiler differ from those
of IDEs, its exposed functionality will sometimes be too
limited to serve your purposes (eg, if GHC knows where
a function is defined, it doesn't need to know how it was
imported, once it gets past error reporting).
If you tie yourself too closely to GHC's view, some things
you'd like to do in an IDE will _appear_ to be impossible.
That is why I recommend looking into the GHCi sources,
because GHCi's needs are closer to those of an IDE.
I assume you mean things like Data.List.map being a
re-exported GHC.List.map being a re-exported GHC.Base.map,
and :info not knowing about the intended abstractions:
Prelude> :i map
map :: (a -> b) -> [a] -> [b] -- Defined in GHC.Base
You can actually get information about possible import
paths via :browse!
Prelude> :m +Data.List
Prelude Data.List> :grep map|imported :browse!
-- imported via Data.List
mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
mapAccumR :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
-- imported via Data.List, Prelude
map :: (a -> b) -> [a] -> [b]
(:browse! is standard GHCi, :grep is non-standard, just to filter
:browse! output). So the :browse! command seems to be able
to find more of the information you want.
haskellmode for Vim, on the other hand, has long provided
haddock lookup, and will offer you a menu of possible
destinations when your cursor is over 'map'. This menu is
built from an index of Haddock entries, which is extracted
from installed Haddock documentation.
Nothing impossible about that, just ugly: so far, the index
is scraped from Haddock's HTML index files. That route
breaks occasionally (recent Haddock HTML changes,
ghc-pkg listing wrong Haddock paths, ..; I'm about to
publish updated scraping code for GHC-7.0.1's Haddock..).
To get something less ugly, I'm currently recoding the
extraction by using Haddock's API and .haddock files
(that'll still break when the API changes, also there is
a pending bug about ghc-pkg, cabal, and haddock
disagreeing about filepath formats, meaning that
.haddock files aren't found on Windows).
I assume that code will be useful to other Haskell IDEs,
though it is mostly exposing Haddock's internal ability to
build an index from .haddock files, which I'd like to see
exposed in Haddock's less-than-well-known API:
http://trac.haskell.org/haddock/ticket/157
Claus
More information about the Glasgow-haskell-users
mailing list