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

Expose a little bit more functionality in the library API #138

Open
danr opened this issue Feb 17, 2018 · 7 comments
Open

Expose a little bit more functionality in the library API #138

danr opened this issue Feb 17, 2018 · 7 comments

Comments

@danr
Copy link

danr commented Feb 17, 2018

I was amusing myself with trying to make a language-server-protocol server on top of ghcid (over at https://github.com/danr/sixserver/blob/master/app/Main.hs). I find the library API very pleasant to use but it is missing two features which would be helpful:

  • Figure out how to launch ghci (via stack, cabal repl etc), which is done in autoOptions right now: https://github.com/ndmitchell/ghcid/blob/master/src/Ghcid.hs#L102

  • Expose parsing error messages from ghci on other occasions than on a load. Namely, if I get a list of strings from exec or execStream I would like to try to parse them into a list of Load.

If this functionality was available it would be easier to make a language server on top of ghcid.
Thanks!

@ndmitchell
Copy link
Owner

Awesome! I've been wanting to try this myself for a while. How do you run your code to try it? I use VS Code normally - do you know what extension you would use?

Regarding loading, sure, that can get its own entry point. One word of warning, it's nasty heuristics, but that is a good reason for no one else to have to try to do it.

Have you seen the Session file? That's a higher level API which might answer questions like parsing load messages. If so, I can expose all of it. If not we can figure out something else.

@danr
Copy link
Author

danr commented Feb 17, 2018

I think the functions in Language.Haskell.Ghcid.Parser would be more useful than those in the Session file.

Unfortunately what's in sixserver it's not really testable. I found the functionality exposed from the haskell-lsp bindings quite painful to use.I think what I will go for is to write the language server in typescript communicating with a tiny json-based wrapper over ghcid.

@ndmitchell
Copy link
Owner

Are you invoking reload to get the list of loaded modules? Or are you sending :load directly at ghcid via exec? I suspect the parser makes more sense exposed in conjunction with a command rather than arbitrarily, but happy to be proved wrong if you can give me a bit more context.

Concretely, what's your plan of attack? As far as I can see, there are a few options:

  • Have ghcid talk JSON over a web server, or alternatively have it talk JSON over the console. I'm not averse to the web server, but the console keeps things simpler for testing and less dependencies.
  • Have ghcid talk LSP, or alternatively have it talk approximately the Haskell API, over JSON. Then either put a lot in a TypeScript server, or a little. I like the idea of a lot being in Haskell, but I wonder if it's choosing the wrong language for the wrong reasons and having a harder debug cycle.

I am very interested in helping, since it's on my todo list to do this anyway.

@prikhi
Copy link

prikhi commented Mar 29, 2019

alternatively have it talk JSON over the console

I'm running ghcid in a thread and transforming the output in a build/watch script:
https://github.com/prikhi/quickbooks-for-communes/blob/master/manage.hs#L125-L140

Ideally, I'd love to be able to fork an IO action that runs ghcid with some Config datatype and dumps the errors/warnings/successes in a TQueue. Then I can just pull from the queue & do whatever I want with them.

But just being able to read a line from ghcid's stdout & decode it with aeson would be a great benefit.

For now, I think I can just use --outputfile=/some/tmp/dir/ghcid.json & redirect stdout to /dev/null, but I haven't experimented with this yet and it requires watching the output file for changes instead of simply using decode <$> hGetLine ghcidStdoutHandle

@ndmitchell
Copy link
Owner

If the overhead of watching a .json file (either CPU wise or complexity wise) is too large I'm not averse to ghcid --json which spits out the JSON output on stdout. For writing the VS Code extension it wasn't very difficult to do the file watching though, since VS Code is easily set up for that kind of thing, but happy to tweak for other editors.

@prikhi
Copy link

prikhi commented Apr 22, 2019

I wouldn't say file watching is prohibitively expensive. I'm forking ghcid from a Haskell script(not an editor) so I can use the fsnotify package to set up file watching. But it would be a nice reduction of complexity to just read the stdout or stderr of the forked ghcid process.

@ndmitchell
Copy link
Owner

Seems reasonable enough simplification that I'd happily take a patch, although not hard enough work that I'm likely to write such a patch in the near future :)

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

3 participants