[英]Using hoogle in a haskell development environment on nix
I'm trying to use hoogle in a Haskell development environment exactly like the one described by O'Charles' wiki : 我试图在Haskell开发环境中使用hoogle,就像O'Charles的wiki所描述的那样:
I have modified shell.nix
like below in order to use hoogleLocal
, but it doesn't seem to install the hoogle binary for me. 我已经修改了shell.nix
如下所示,以便使用hoogleLocal
,但它似乎没有为我安装hoogle二进制文件。
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 doesn't appear to install the hoogle binary?
hs.hoogleLocal
] ++ hs.thiscurrentpackage.propagatedNativeBuildInputs)))
];
}
In the resulting shell, the hoogle
binary is not available. 在生成的shell中, hoogle
二进制文件不可用。
If I include hs.hoogle
to the buildInputs
, the hoogle
binary is installed but it can't find the databases. 如果我将hs.hoogle
包含在buildInputs
,则会安装hoogle
二进制文件,但无法找到数据库。 Below 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 working correctly for a setup like described by O'Charles? 如何正确使用O'Charles描述的设置?
Edit : The original shell.nix is the same one from this answer . 编辑 :原始shell.nix与此答案中的相同。
Here's what my Nix Haskell dev environment looks like 这是我的Nix Haskell开发环境的样子
in ~/.nixpkgs/config.nix
: 在~/.nixpkgs/config.nix
:
First off, define a haskellEnvFun function for building Haskell environments: 首先,定义一个haskellEnvFun函数来构建Haskell环境:
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)];
};
Call this function to define two environments: one for running the Hoogle builder on changes, and one without: 调用此函数可以定义两个环境:一个用于在更改时运行Hoogle构建器,另一个用于:
haskellEnvHoogle = haskellEnvFun {
name = "haskellEnvHoogle";
withHoogle = true;
};
haskellEnv = haskellEnvFun {
name = "haskellEnv";
withHoogle = false;
};
Define all the packages you want to use in your local Haskell dev environment: 定义要在本地Haskell开发环境中使用的所有包:
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
];
In your ~/.profile
define a couple bash functions to load those environments for convenience: 在~/.profile
定义了几个bash函数来加载这些环境以方便:
env-type () { envtype="$1" shift nix-shell -Q -p $envtype "$@" } haskell-env () { env-type "haskellEnv" "$@" } haskell-env-hoogle () { env-type "haskellEnvHoogle" "$@" }
Call haskell-env-hoogle
in your shell. 在你的shell中调用haskell-env-hoogle
。 This will build all of your packages + docs and load you into an environment with hoogle
in scope. 这将构建您的所有软件包+文档,并将您加载到范围为hoogle
的环境中。 At this point I usually type: 此时我通常输入:
hoogle server --local -p 8080 &> /tmp/hoogle.log & disown
to launch a hoogle server the the background. 启动一个hoogle服务器的后台。 Eventually I want to have a systemd service for this so that I can just nixos-rebuild to regen docs and launch the server automatically. 最终我希望有一个systemd服务,这样我就可以通过nixos-rebuild重新生成文档并自动启动服务器。
For emacs I've set the haskell-hoogle-url
to http://localhost:8080/?hoogle=%s
, so that I can get local hoogle docs for keywords under my cursor. 对于emacs,我已经将haskell-hoogle-url
为http://localhost:8080/?hoogle=%s
,这样我就可以在光标下获取关键字的本地hoogle文档。 I use spacemacs so I just type , hh
for this functionality. 我使用spacemacs所以我只是键入, hh
这个功能。
You can see my full nixpkgs config here: https://github.com/jb55/nix-files/blob/659798f2ca81fb7ad0cb5a29de576024ee16eef8/nixpkgs/config.nix#L20 你可以在这里看到我的完整nixpkgs配置: https : //github.com/jb55/nix-files/blob/659798f2ca81fb7ad0cb5a29de576024ee16eef8/nixpkgs/config.nix#L20
Hope that helps. 希望有所帮助。
haskellPackages.hoogleLocal
appears to be out of date; haskellPackages.hoogleLocal
似乎已过时; it doesn't exist anymore. 它不再存在了。
William Casarin's answer appears to be assuming you will have a single "haskell development environment" you use, rather than using nix-shell to have different dev environments for different projects. William Casarin的回答似乎是假设您将使用单个“haskell开发环境”,而不是使用nix-shell为不同的项目设置不同的开发环境。
What I've just figured out how to do instead is to write my shell.nix to override ghc.withPackages
and ghcWithPackages
to be ghc.withHoogle
, so that when nix-shell creates an environment with a GHC that knows about all the necessary packages it also creates a hoogle database that knows about the same packages. 我刚刚弄清楚如何做的是编写我的shell.nix以覆盖ghc.withPackages
和ghcWithPackages
为ghc.withHoogle
,这样当nix-shell创建一个GHC环境时,它知道所有必需的包它还创建了一个知道相同包的hoogle数据库。
Here's my shell.nix 1 : 这是我的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'm newish to nix, but I believe this should be pretty much "project independent"; 我对nix很新,但我相信这应该是“项目独立的”; I can use cabal2nix . > default.nix
我可以使用cabal2nix . > default.nix
cabal2nix . > default.nix
to generate a nix package from my cabal file when I change it, without having to touch shell.nix. cabal2nix . > default.nix
在我更改它时从我的cabal文件生成一个nix包,而不必触及shell.nix。
I haven't actually used this in real development yet, only a dummy project I was using to try to figure out how to get hoogle working in nix-shell. 我还没有在实际开发中实际使用它,只是我用来试图找出如何让nogle-shell中的hoogle工作的虚拟项目。
1 The skeleton of this was what cabal2nix --shell
spits out, with the project-specific guts removed and replaced with f = import ./default.nix
instead of embedding the nixified cabal package again. 1这个的骨架是cabal2nix --shell
吐出来的,删除了项目特定的内容并用f = import ./default.nix
替换,而不是再次嵌入nixified cabal包。
Using @Ben's answer as reference, here is a diff on the required changes I needed to make to a cabal2nix --shell
file: 使用@ Ben的答案作为参考,这是我需要对cabal2nix --shell
文件进行必要更改的差异:
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 {});```
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.