Using hoogle in haskell development environment on nix

I am trying to use Google in the Haskell development environment, for example, as described in the O'Charles wiki :

I changed shell.nix as shown below to use hoogleLocal , but it doesn't seem to install the hoogle binary for me.

 let pkgs = import <nixpkgs> {}; # I'm attempting to use hoogle here, but it is not working. haskellPackages = let callPackage = pkgs.lib.callPackageWith haskellPackages; in pkgs.recurseIntoAttrs (pkgs.haskellPackages.override { extension = self: super: { thiscurrentpackage = self.callPackage ./. {}; hoogleLocal = pkgs.haskellPackages.hoogleLocal.override { packages = self.thiscurrentpackage; }; }; }); in pkgs.myEnvFun { name = haskellPackages.thiscurrentpackage.name; buildInputs = [ (haskellPackages.ghcWithPackages (hs: ([ hs.cabalInstall hs.ghcMod hs.yesodBin # This does not appear to install the hoogle binary? hs.hoogleLocal ] ++ hs.thiscurrentpackage.propagatedNativeBuildInputs))) ]; } 

In the resulting shell, the hoogle binary is not available.

If I include hs.hoogle in buildInputs , the buildInputs binary is installed, but it cannot find the database. This is what happens when I try to use it.

 $ nix-shell ...... $ hoogle Monad Could not find some databases: default Searching in: . /nix/store/91y9q2y5a2ws8xgcsx1gkhfagc0f2qz6-haskell-hoogle-ghc7.8.3-4.2.36-shared/share/x86_64-linux-ghc-7.8.3/hoogle-4.2.36/databases There are no available databases, generate them with: hoogle data $ hoogle data hoogle: /nix/store/91y9q2y5a2ws8xgcsx1gkhfagc0f2qz6-haskell-hoogle-ghc7.8.3-4.2.36-shared/share/x86_64-linux-ghc-7.8.3/hoogle-4.2.36/databases: changeWorkingDirectory: does not exist (No such file or directory) $ 

How do I get this to work correctly for an installation similar to that described by O'Charles?

Edit : The source shell.nix file is the same as in this answer .

+13
haskell nixos hoogle
source share
3 answers

Here is what my environment for Nix Haskell dev looks like

in ~/.nixpkgs/config.nix :

Helper environment feature

First of all, define the haskellEnvFun function for building Haskell environments:

 packageOverrides = super: rec { haskellEnvFun = { withHoogle ? false, compiler ? null, name }: let hp = if compiler != null then super.haskell.packages.${compiler} else haskellPackages; ghcWith = if withHoogle then hp.ghcWithHoogle else hp.ghcWithPackages; in super.buildEnv { name = name; paths = [(ghcWith myHaskellPackages)]; }; 

Definition of some environments

Call this function to define two environments: one for launching Builder Builder with changes and one without:

 haskellEnvHoogle = haskellEnvFun { name = "haskellEnvHoogle"; withHoogle = true; }; haskellEnv = haskellEnvFun { name = "haskellEnv"; withHoogle = false; }; 

Packages

Define all the packages you want to use in your local Haskell dev environment:

 myHaskellPackages = hp: with hp; [ Boolean HTTP HUnit MissingH QuickCheck SafeSemaphore Spock aeson async attoparsec bifunctors blaze-builder blaze-builder-conduit blaze-builder-enumerator blaze-html blaze-markup blaze-textual cased cassava cereal comonad comonad-transformers directory_1_2_4_0 dlist dlist-instances doctest exceptions fingertree foldl free hamlet hashable hspec hspec-expectations html http-client http-date http-types io-memoize keys language-c language-javascript language-bash lens lens-action lens-aeson lens-datetime lens-family lens-family-core lifted-async lifted-base linear list-extras list-t logict mime-mail mime-types mmorph monad-control monad-coroutine monad-loops monad-par monad-par-extras monad-stm monadloc mongoDB monoid-extras network newtype numbers optparse-applicative parsec parsers pcg-random persistent persistent-mongoDB persistent-template pipes pipes-async pipes-attoparsec pipes-binary pipes-bytestring pipes-concurrency pipes-csv pipes-extras pipes-group pipes-http pipes-mongodb pipes-network pipes-parse pipes-safe pipes-shell pipes-text posix-paths postgresql-simple pretty-show profunctors random reducers reflection regex-applicative regex-base regex-compat regex-posix regular relational-record resourcet retry rex safe sbv scotty semigroupoids semigroups shake shakespeare shelly simple-reflect speculation split spoon stm stm-chans stm-stats streaming streaming-bytestring streaming-wai strict stringsearch strptime syb system-fileio system-filepath tagged taggy taggy-lens tar tardis tasty tasty-hspec tasty-hunit tasty-quickcheck tasty-smallcheck temporary test-framework test-framework-hunit text text-format time tinytemplate transformers transformers-base turtle uniplate unix-compat unordered-containers uuid vector void wai wai-conduit warp wreq xhtml yaml zippers zlib ]; 

Shell helpers

In your ~/.profile define a couple of bash functions to load these environments for convenience:

  env-type () {
   envtype = "$ 1"
   shift
   nix-shell -Q -p $ envtype " $@ "
 }

 haskell-env () {
   env-type "haskellEnv" " $@ "
 }

 haskell-env-hoogle () {
   env-type "haskellEnvHoogle" " $@ "
 }

Hoogle

Call haskell-env-hoogle in your shell. This will create all your packages + documents and load you into the environment with hoogle in the area. At this point, I usually type:

 hoogle server --local -p 8080 &> /tmp/hoogle.log & disown 

to start a hoogle server in the background. In the end, I want to have a systemd service for this, so that I can only nixos-rebuild update documents and start the server automatically.

Emacs

For emacs, I set haskell-hoogle-url to http://localhost:8080/?hoogle=%s , so that I can get local hoogle docs for keywords under my cursor. I use spacemacs, so just type , hh for this function.

Here you can see my full nixpkgs configuration: https://github.com/jb55/nix-files/blob/659798f2ca81fb7ad0cb5a29de576024ee16eef8/nixpkgs/config.nix#L20

Hope this helps.

+12
source share

haskellPackages.hoogleLocal looks deprecated; he no longer exists.

William Kazarin's answer seems to suggest that you are using a single haskell development environment instead of using nix-shell to have different development environments for different projects.

What I just figured out how to do this is to write my shell.nix to redefine ghc.withPackages and ghcWithPackages as ghc.withHoogle , so when nix-shell creates an environment with GHC that knows about all the necessary packages, it also creates a hoogle database that knows about the same packages.

Here is my shell.nix 1 :

 { nixpkgs ? import <nixpkgs> {}, compiler ? "default", withHoogle ? true }: let inherit (nixpkgs) pkgs; f = import ./default.nix; packageSet = ( if compiler == "default" then pkgs.haskellPackages else pkgs.haskell.packages.${compiler} ); haskellPackages = ( if withHoogle then packageSet.override { overrides = (self: super: { ghc = super.ghc // { withPackages = super.ghc.withHoogle; }; ghcWithPackages = self.ghc.withPackages; } ); } else packageSet ); drv = haskellPackages.callPackage f {}; in if pkgs.lib.inNixShell then drv.env else drv 

I am new to nix, but I believe this should be pretty much “project independent”; I can use cabal2nix . > default.nix cabal2nix . > default.nix to create the nix package from my cabal file when I change it, without having to touch shell.nix.

I have not used this in real development yet, but only a dummy project that I used to figure out how to get hoogle to work in nix-shell.


1 The skeleton of this is that cabal2nix --shell splashes out and the guts removed from the project are removed and replaced with f = import ./default.nix instead of reintroducing the nixified cabal package.

+10
source share

Using @Ben's answer as a reference, provides information on the necessary changes that need to be made to the cabal2nix --shell file:

 diff --git a/shell.nix b/shell.nix index 540ade3..e207d6e 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,4 @@ -{ nixpkgs ? import <nixpkgs> {}, compiler ? "default", doBenchmark ? false }: +{ nixpkgs ? import <nixpkgs> {}, compiler ? "default", doBenchmark ? false , withHoogle ? true}: let @@ -21,10 +21,23 @@ let license = stdenv.lib.licenses.bsd3; }; - haskellPackages = if compiler == "default" + haskellPackages' = if compiler == "default" then pkgs.haskellPackages else pkgs.haskell.packages.${compiler}; + haskellPackages = ( + if withHoogle + then haskellPackages'.override { + overrides = (self: super: + { + ghc = super.ghc // { withPackages = super.ghc.withHoogle; }; + ghcWithPackages = self.ghc.withPackages; + } + ); + } + else haskellPackages' + ); + variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id; drv = variant (haskellPackages.callPackage f {});''' 
0
source share

All Articles