Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can hint run :d, :i commands? #101

Open
jwaldmann opened this issue May 11, 2020 · 6 comments
Open

can hint run :d, :i commands? #101

jwaldmann opened this issue May 11, 2020 · 6 comments

Comments

@jwaldmann
Copy link

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 gives WontCompile.

@gelisam
Copy link
Contributor

gelisam commented May 11, 2020

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.

@jwaldmann
Copy link
Author

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.

@gelisam
Copy link
Contributor

gelisam commented May 11, 2020

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!

@jwaldmann
Copy link
Author

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".

@gelisam
Copy link
Contributor

gelisam commented May 12, 2020

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.

@jwaldmann
Copy link
Author

Right. I try to keep this in my todo-queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants