NixOS、Neovim 中的 Haskell LSP、XMonad 导入未找到

Ref*_*ker 1 haskell xmonad nixos neovim

这是问题的屏幕截图:\n在此输入图像描述

\n

操作系统:NixOS,通道不稳定。

\n

Neovim:0.7.2。

\n

哈斯克尔 LSP:haskell-language-server.

\n

xmonad --recompile在终端中运行是有效的。

\n

请帮忙 :-)

\n
编辑1:
\n

正如@ArtemPelenitsyn 在下面的评论中所询问的,这是我的init.lua:https: //pastebin.com/70jMHm02。\n我认为相关的部分:

\n
require\'lspconfig\'.hls.setup{}\n
Run Code Online (Sandbox Code Playgroud)\n

我认为它与 NixOS 更相关,而不是 Neovim。

\n
编辑2:
\n

正如@Ben 在下面的评论中所询问的,以下是所需的信息:

\n
\xce\xbb ghci\nGHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help\nghci> import XMonad\n\n<no location info>: error:\n    Could not find module \xe2\x80\x98XMonad\xe2\x80\x99\n    It is not a module in the current program, or in any known package.\nghci> \n
Run Code Online (Sandbox Code Playgroud)\n

这是我的configuration.nix中与Haskell和XMonad相关的所有内容:

\n
\xce\xbb ghci\nGHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help\nghci> import XMonad\n\n<no location info>: error:\n    Could not find module \xe2\x80\x98XMonad\xe2\x80\x99\n    It is not a module in the current program, or in any known package.\nghci> \n
Run Code Online (Sandbox Code Playgroud)\n

Ben*_*Ben 5

在你的configuration.nix中,你有以下内容:

environment.systemPackages = with pkgs; [
  ghc
  haskell-language-server
  haskellPackages.xmobar
  haskellPackages.xmonad
  haskellPackages.xmonad-contrib
];
Run Code Online (Sandbox Code Playgroud)

这里你实际上还没有xmobar安装可以访问、xmonad、 和包的GHC xmonad-contrib。安装后,您安装了一个不知道任何软件包的 GHC,并单独安装了那些 Haskell 软件包。这些包中的任何可执行文件都将添加到PATH环境变量中(这就是您实际运行的方式xmonad),但PATH不知道 GHC 是否找到已安装的包。您需要另一个步骤将 GHC 的安装与软件包连接起来,以便您(和haskell-language-server)可以导入它们。

原因是 GHC 期望的工作方式是安装软件包是对文件系统的变异操作。在“普通”系统上,您安装 GHC 并且它知道与其捆绑在一起的软件包,然后您将另一个软件包安装xmonad到 GHc 将在其中查找软件包1的文件夹中,现在运行同一ghc程序的效果已经改变。

尼克斯不喜欢这样。Nix 中的包应该是不可变的。您无法事后将 GHC-without-xmonad 更改为 GHC-with-xmonad。

所以仅仅安装pkgs.ghc实际上并不是您想要的。该包已经完全由计算结果的 nix 代码确定,并且它确定的包是ghc没有其他包的基线。相反,您需要创建一个全新的包,其中包含随xmonad.

幸运的是,这是一个极其常见的需求,因此已经有一个包装函数可以为您生成此包。haskellPackages.ghcWithPackages2 . 该函数采用单个参数,该参数必须是您提供的函数。该函数本身将在单个参数上调用,该参数是可用的 Haskell 包的集合,并且应该返回您想要包含在正在构建的 GHC 安装包中的列表。

所以这意味着你真正想要的是这样的:

environment.systemPackages = with pkgs; [
  haskell-language-server

  # If you want you can use `with hpkgs; [` to avoid explicitly
  # selecting into the hpkgs set on every line
  (haskellPackages.ghcWithPackages (hpkgs: [  
    hpkgs.xmobar
    hpkgs.xmonad
    hpkgs.xmonad-contrib
  ]))
];
Run Code Online (Sandbox Code Playgroud)

在幕后,ghcWithPackages实际所做的是安装ghc和这些软件包,就像您所做的那样,但它还会创建一个非常小的“包装程序包”,围绕ghc它设置环境变量,告诉它在哪里可以找到您安装的特定软件包集。PATH添加到提供诸如ghc、等命令的东西ghci不是底层 GHC,而是包装的 GHC。3

您实际上并不需要了解任何“幕后”内容,只是每次您需要 GHC 拥有一组特定的软件包时,您都需要使用ghcWithPackages. 知道它是基于包装脚本可以帮助您减轻空间浪费的压力;如果你有 100 个 Haskell 项目,它们都可以共享任何通用的 GHC 版本和 Haskell 包版本;这只是你有 100 份的小包装纸。

这也是大多数在 nixpkgs 中直接支持的编程语言所使用的基本模型(甚至还有一些其他东西,严格来说不是编程语言,但可以通过事后安装插件来扩展)。对于每种语言来说,它的工作方式并不完全相同,因为它取决于必须围绕每种语言所具有的打包工具编写的代码。但基本的概念模型通常是这样的。

这一切都记录在nixpkgs 手册中;与 Nix 本身或 NixOS 的手册相反。它有一个关于语言和框架的部分,您可以在其中找到有关 nixpkgs 如何支持多种编程语言生态系统的文档。尽管下面的 Haskell 部分已变成一小段,告诉您转到单独的站点获取nixpkgs Haskell 文档


最后一点:我不能 100% 确定是否haskell-language-server会自动选择ghc您的PATH软件包并运行这些软件包,或者您是否需要任何进一步的配置。由于我是 Haskell 开发人员,我有许多项目,每个项目都需要不同的可用包集(甚至在某些情况下甚至是 GHC 版本),因此我没有在该级别安装任何GHC(或 HLS)environment.system-packages;我的每个项目都有自己的 shell 环境,最终从项目.cabal文件生成。这意味着我从未真正使用haskell-language-server过项目之外的“松散”Haskell 文件,并且我不确定您是否需要做更多事情才能使其正常工作。但这绝对是您开始ghci> import XMonad工作所需要的(无需显着改变您的工作方式)。


1我相信还更新了一些注册表文件,但我并没有 100% 掌握所有细节。它们对于这种级别的解释并不重要。


2如果您不喜欢 中包含的 GHC(以及其他所有内容)的版本haskellPackages,则所有其他 Haskell 包集也包含此ghcWithPackages函数,例如haskell.packages.ghc924haskell.packages.ghc8102等(顶层haskellPackages是这些集之一;以确定的为准)是您正在使用的 nixpkgs 修订版中的一个很好的默认值)。


3我在包装脚本中看到的环境变量都包含NIX_在名称中,因此我怀疑 nixpkgs 中的基本 GHC 包已被修补以支持此行为。