Document use with editor (f.e. emacs)
Hi!
Is there any information around how to use an obelisk based project smoothly with emacs (haskell-mode, propably other related packages)? (at least saw that @ryantrinkle was using emacs in his YOW talk :))
So f.e. how to get interactive hasekll mode (REPL) working (for ghc / ghcjs) - guess ob repl has to be used?
Or do you just run ob run in an emacs term/shell? Is there a working way to get the error parser working that buffer, so I can jump to source file when ob run hits an compiler error?
Hey! Personally, I use ob run separately from emacs, and as far as I know, integration for jumping straight to errors doesn't exist yet. Maybe we could get ob run to run a Language Server Protocol server and connect emacs to that?
@ryantrinkle Integrating obelisk with haskell-ide-engine would be excellent.
You can use nix-buffer for this but it requires some extra configuration.
I just got something like this working, with Visual Studio Code but Emacs should work too since it's through hie. It's a bit unfortunate that it's not very feasible to use stack-based tools (stack+intero always "just worked" for me), but haskell-ide-engine (hie) is pretty good now and it looks like it's in position to be the dominating IDE integration point. What I did to get this working, maybe it will help you or somebody else:
- Start project with ob, i.e.
ob init, probably do oneob runto make sure it's all good. - Get
hiewith GHC 8.0.2 working in project directory. There are ways to install it for multiple versions and get your project to choose the right one, and there's probably even a way to get it working via the nix shell in 3), but to get things working I just installed it for GHC 8.0.2 globally. See https://github.com/domenkozar/hie-nix for details, I believe I rannix-env -iA hie80 -f https://github.com/domenkozar/hie-nix/tarball/master -
nix-shell -A shells.ghcto get into the same shell that obelisk uses, so you have access to ghc commands. Make sure that you start emacs or VSC or whatever on the command line through this shell. - Like you said, use
ob replto get into a REPL where you can play with your code.
At this point code you write in common at least will have nice IDE features (my minimum for this is red underlining of compile errors). For various reasons though, when it tries to run cabal configure for the frontend package, this will fail since it can't find the common project.
- So, maybe there's a better way to do this but I then did the following manually to get
frontendto recognizecommon:
cd frontend
cabal sandbox init
cabal install ../common/common.cabal
cabal configure
aand at this point I can see compile errors in common and frontend files using HIE. Let me know if this helps or if you run into any issues!
FYI this still won't have a local hoogle or local documentation in general (which you might want when talking about using an IDE)...if anybody has suggestions for that, that would be great!
I had success with Emacs + Dante, so I thought I would share.
Put this snippet at the end of the code. Syntax checking with flycheck and completion with company-mode is wokring
-- Local Variables:
-- dante-project-root: "/obelisk/project/root/path/"
-- dante-repl-command-line: ("nix-shell" "--pure" "-A" "shells.ghc" "--run" "cabal new-repl --builddir=dist/dante --project-file=cabal.project frontend")
-- eval: (dante-mode)
-- eval: (flycheck-mode)
-- End:
- Needs to add
dant-project-rootanddante-repl-command-linetosafe-local-variable. - Needs to add
ghcjs-dompackage as frontend dependency, even thoughob runruns without it. - Couldn't use
ob repl. It freezes and I don't know why.
With this https://github.com/jyp/dante/pull/93 it works fine for me.
Nice! I tried using ob repl for dante again and now it works. Think I had some mistakes somewhere.
Some notes on using ob run with VSCode's ghcid plugin:
For older versions of the plugin, the ghcid integration is pretty simple, as all you have to do is run the Watch ghcid output command on the ghcid-output.txt file created by ob run.
Newer versions deprecated this command in favor of a single configurable path to a shell executable that it calls with some randomly generated file path to use for the output. You can create a bash script that wraps a call to ob repl and passes along the output path, but that means you essentially need two instances of ghcid running to have both the IDE features and a running application.
Here's a script:
#!/bin/bash
nix-shell -A shells.ghc --run "ghcid --command='ob watch' $@"
Another solution is to just revert to an older version of the extension (<= 0.7). See https://github.com/Microsoft/vscode/issues/12764#issuecomment-442370545.
EDIT: Switched ghcid command in bash script from ob repl to ob watch.
ob watch is just ghcid under the hood so you could use that probably.
@3noch I don't think we pass through arguments to ghcid, which I think is the issue here. Maybe that would be worth fixing?
I was hoping the integration didn't need to pass special arguments. But aside from that yes it would be nice if ob watch/ob run let you configure ghcid somehow.
Just thought I'd mention that the following in a .dir-locals.el in the root directory of the reflex project gets dante ~~working for me~~ (edit: see my next comment):
((nil . (
(dante-project-root . "~/app")
(dante-repl-command-line . ("ob" "repl"))
)))
I haven't tested this extensively, but it appears to work because ob repl loads both the frontend and backend targets into the repl, so I don't think we need directory local variables set in both the frontend and backend directories.
The string ~/app should be replaced with the path to your project root. Dante actually works for me without the dante-project-root set, but it's probably best to set it. From the documentation on the variable dante-project-root it says it will try to guess the project root when the value is left nil by looking for a cabal file.
It also seems there could be some cross pollination between this issue and the following: https://github.com/reflex-frp/reflex-platform/pull/237
Eh never mind, because --builddir=dist/dante isn't specified dante just leaves the build files next to the source:
backend/src/Backend.hi
backend/src/Backend.o
common/src/Common/Api.hi
common/src/Common/Api.o
common/src/Common/Route.hi
common/src/Common/Route.o
frontend/src/Frontend.hi
frontend/src/Frontend.o
Looks like I'll need something like this in the frontend folder and another like it in the backend.
((nil . (
(dante-project-root . "~/app")
(dante-repl-command-line . ("nix-shell" "--pure" "-A" "shells.ghc" "--run"
"cabal new-repl frontend --builddir=dist/dante"))
)))
looking at @JBetz comment, so how I can integrate my ob project to the VSCode? Using the script and start ghcid from VSCode command?
Is support for haskell-ide-engine possible at the moment? I saw on Reddit a while ago that support for it may be coming soon?
I believe @mpickering did some preparations work for this. Also hie gets installed into the nix shell by default these days in an Obelisk project. So, I believe there is just a little push needed to get it over the finish line. I haven't found the time yet to check it out, maybe it even already works :-P
I believe @mpickering did some preparations work for this.
Indeed: https://github.com/obsidiansystems/obelisk/issues/363#issuecomment-468267291
Yeah hie is now bundled with Obelisk, which is great :+1: It works great with the Visual Studio Code plugin, but I still have to do
cd frontend cabal sandbox init cabal install ../common/common.cabal cabal configure
like @cah6 suggested to get it working. Is there any way to avoid this? Having these cabal files around is kind of annoying and makes the setup harder.
Just wanted to share reflex-frp/reflex-platform could now include the haskell-language-server LSP server with this PR https://github.com/reflex-frp/reflex-platform/pull/716.
I haven't tried this project yet (still in the process of getting through how-to-use and how-to-install-correctly) and so I'm wondering, how is the IDE experience in VS Code with the haskel LSP using the addition you try to add to reflex @ibizaman ?
@reallymemorable with Emacs and for what I use - on-the-fly syntax checking and code formatting upon saving - it’s flawless.
Are you launching vscode from inside ob shell's shell?
Sent with ProtonMail Secure Email.
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Thursday, February 11th, 2021 at 2:48 AM, Raptazure [email protected] wrote:
Hi, I am trying to open a new project with VS Code inside ob shell, but there are a bunch of errors with haskell.haskell extension on. Is there a way to fix this? Thanks.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.
Are you launching vscode from inside
ob shell's shell? Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ … On Thursday, February 11th, 2021 at 2:48 AM, Raptazure @.***> wrote: Hi, I am trying to open a new project with VS Code inside ob shell, but there are a bunch of errors with haskell.haskell extension on. Is there a way to fix this? Thanks. image — You are receiving this because you are subscribed to this thread. Reply to this email directly, [view it on GitHub](#184 (comment)), or unsubscribe.
cd frontend ob shell and then code . works for me! Thanks!
I also have this hie.yaml:
cradle:
cabal:
- path: "./frontend/src/"
component: "lib:frontend"
- path: "./common/src/"
component: "lib:common"
- path: "./backend/src/"
component: "lib:backend"
I have my IDE set up with nixos, spacemacs, direnv, and easy-hls-nix, but it's not perfect and there are some problems right now. Notably, nixos-21.05 (and nixpkgs-unstable) dropped support for ghc-8.6.5. From the hls readme https://github.com/haskell/haskell-language-server#installation-from-source:
GHC 8.6.5 is not supported here because nixpkgs-unstable no longer maintains the corresponding packages set.
Direnv should let you hls builld the project fine without having to start it with ob shell / nix-shell (my envrc):
use nix -A shells.ghc
Unfortunately, due to a different problem (https://github.com/haskell/haskell-language-server/issues/1601), hls binaries downloaded from their github releases page don't seem to work well with nix, so I tried building it locally, though of course, building locally only works for more recent versions of GHC and does not work with GHC 8.6.5, which is the only version supported by obelisk.
I wish there was some way that I could just use whatever version of GHC I want with Obelisk, but it doesn't look like the core Obelisk libraries are available in Hackage...
I would still appreciate documentation for using obelisk with an editor being added.
This is how I trie to work with haskell-language-server, using easy-hls-nix:
{ system ? builtins.currentSystem
, pkgs ? import <nixpkgs> {}
}:
let
# latest, hls 1.5.0
# easy-hls-src = pkgs.fetchFromGitHub {
# owner = "jkachmar";
# repo = "easy-hls-nix";
# rev = "7c123399ef8a67dc0e505d9cf7f2c7f64f1cd847";
# sha256 = "0402ih4jla62l59g80f21fmgklj7rv0hmn82347qzms18lffbjpx";
# };
# hls 1.0.0, easy-hls-nix initial commit
easy-hls-src = pkgs.fetchFromGitHub {
owner = "jkachmar";
repo = "easy-hls-nix";
rev = "f2ef4a9c3ab6a54c30f80503d97cb5a617fc6e1a";
sha256 = "QiYwfVR2gieFhZBGAeZ74j7HkH5165bgXT9t2iMoRlM=";
};
easy-hls = pkgs.callPackage easy-hls-src { ghcVersions = [ "8.6.5" ]; };
obelisk = (import ./.obelisk/impl {
inherit system;
iosSdkVersion = "13.2";
terms.security.acme.acceptTerms = true;
});
in
with pkgs.haskell.lib;
obelisk.project ./. ({ ... }: {
shellToolOverrides = self: super: {
# inherit (pkgs.haskell.packages.ghc865) haskell-language-server;
haskell-language-server = easy-hls;
};
staticFiles = import ./static.nix { inherit pkgs; };
};
})
If I use any of the later available commits of easy-hls-nix, I get a problem running haskell-language-server:
cabal: relocation error: /usr/lib/libc.so.6: symbol _dl_fatal_printf version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
Those early version that do work in principle come with there own problems, however. This earliest version I use above says:
Installation error: unable to load package `ghc-prim-0.5.3'