tweag / rules_haskell

Haskell rules for Bazel.
https://haskell.build
Apache License 2.0
266 stars 81 forks source link

Improve Bazel experience in Dante upstream #464

Open mboes opened 6 years ago

mboes commented 6 years ago

This is really a ticket for Dante, but filing here for this team to prioritize. Several IDE integration options today are unfortunately tied pretty tightly to the existence of Stack (unnecessarily so!). This includes intero, and hence also haskero and haskelly for VSCode (since both depend on intero). Dante shows that in the case of Emacs and likely others too, you can get pretty much all of the same features working uniformly for many build tools with very little tool-specific code (typically just a few lines in dante.el). ghcid shows something else: that no IDE integration can be workable too.

It's possible to make Dante work with Bazel today in simple cases where all source files can be provided to GHCi as-is (no system dependencies etc). You have to tell Dante that you want it to spawn a naked GHCi prompt for this to work and set dante-project-root manually. To improve on this, we need to:

  1. Teach Dante to recognize the project root automatically by looking for a WORKSPACE file.
  2. Teach Dante what <target-name> to use when callingbazel run @replto spawn the REPL, given the name ofWORKSPACE`-relative source file path.
  3. (optional) make it so that Dante only uses one REPL session per *-@repl target, to save on memory. Since we have one *-@repl target per haskell_library or haskell_binary, not one per source file. I don't know how hard this would be. Maybe trivial or very hard depending on the internals of Dante.

For (2), Dante internally has a buffer-local variable called dante-target, which is the name of the target to supply to the REPL. Given the filename /path/to/Foo.hs associated with the current buffer, we can compute <target-name> as follows:

fullname=$(bazel query //path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

cc @jyp.

shmish111 commented 6 years ago

The following commands worked for me: bazel query language-plutus-core/src/Common.hs bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

Also there is an emacs function locate-dominating-file that will find the WORKSPACE file from any sub directory of its location.

With these 3 you have the workspace root from where you can run the repl command and the target to run (after appending -repl.

jyp commented 6 years ago

I won't be working on this myself (I have no use for bazel), but I'll be welcoming PRs. (If you want them processed quickly send me an email separately).