Open jwaldmann opened 4 years ago
No, it's not. hint is a wrapper around the ghc api, not around the ghci executable, so it's not as easy as exposing a function which forwards those commands to ghci. Furthermore, I would prefer to expose those features as independent functions with relatively-precise types rather than by extending runStmt
to mimic ghci. runStmt
already does more things than I would like!
Something like this:
docOf :: Id -> String
moduleOf :: Id -> Maybe ModuleName
instancesOf :: Id -> Maybe [...]
Would you like to try adding those features to hint yourself? I don't have a lot of time to dedicate to hint
these days.
Thanks for the quick response. I agree with the design (keep separate actions in separate functions). Is there a ghci api
? Else, it looks like we'd have to re-implement some ghci functionality? I will look into it, time permitting.
If you want to interact directly with ghci, rather than using hint or the ghc api, I recommend taking a look at the doctest project, they have a system for interacting with a ghci process and it might be easier to extract that from the doctest project than to figure out the ghc api. The ghc api is a beast, and I'm not intimately familiar with it myself, as I've inherited this codebase from someone else. hint exists to re-expose part of that beast in a hopefully much simpler API!
I did some research, taking :doc
as an example.
Actual implementation is docCmd
in ghc/GHCi/UI.hs
:
docCmd :: GHC.GhcMonad m => String -> m ()
docCmd "" =
throwGhcException (CmdLineError "syntax: ':doc <thing-you-want-docs-for>'")
docCmd s = do
-- TODO: Maybe also get module headers for module names
names <- GHC.parseName s
e_docss <- mapM GHC.getDocs names
sdocs <- mapM (either handleGetDocsFailure (pure . pprDocs)) e_docss
let sdocs' = vcat (intersperse (text "") sdocs)
unqual <- GHC.getPrintUnqual
dflags <- getDynFlags
(liftIO . putStrLn . showSDocForUser dflags unqual) sdocs'
It is exported as part of a structure:
module GHCi.UI ( ... ghciCommands, ... ) where ...
ghciCommands :: [Command]
ghciCommands = map mkCmd [ ...
("doc", keepGoing' docCmd, completeIdentifier),
...
but that's not available in https://hackage.haskell.org/package/ghc-8.10.1/docs/GHCi.html - because that does not import GHCi.UI
module GHCi (...) where ...
import GHCi.Message
#if defined(HAVE_INTERNAL_INTERPRETER)
import GHCi.Run
#endif
import GHCi.RemoteTypes
import GHCi.ResolvedBCO
import GHCi.BreakArray (BreakArray)
...
The implementation uses GHC.getDocs
which is exported https://hackage.haskell.org/package/ghc-8.10.1/docs/GHC.html#v:getDocs
So, implementation in hint
would be possibly by copying the above code block. That's what I mean by "re-implementing ghci".
Thanks for taking a look! This GHC.getDocs
seems like a better base to build on than docCmd
anyway, because the argument-parsing and multiple-input parts don't make sense for a function of type docOf :: Id -> String
. Now that I see that GHC.getDocs
can fail with a GetDocsFailure
, I think a simpler-api version of that would be docOf :: Id -> Maybe ...
.
The Map Int ...
is surprising, what's the Map Int
for?
Finally, HsDocString
's documentation says it's a UTF8-encoded ByteString, so String or Text would be a better (and simpler!) representation than HsDocString or ByteString. docCmd seems to be jumping through hoops to print that string according to some ghci-specific settings, and I don't think hint needs to emulate that either.
So while it's true that we have to do some work around GHC.getDocs
, we have to do so in order to make the api simpler, not because we're parsing a command and printing the result to stdout, so I don't think we're quite reimplementing ghci.
Right. I try to keep this in my todo-queue.
Hi. I am using hint for https://github.com/jwaldmann/safe-tidal-cli.
Is it possible to execute ghci commands
:doc
,:info
in a hint session?runStmt
givesWontCompile
.