This is correct, the only feasible way is to compile HLS with Nix in ghc. (There is actually the alternative to compile hls yourself with cabal inside your nix shell, but that is a bit brittle.) An expression like the tcards above is correct in principle. Yet, it might be broken or give you a terribly outdated hls.
For me and my colleagues at work I maintain haskellPackages
overrides for the newest HLS compatible with our corresponding ghcs in our obelisk project. We apply the following overrides via:
shellToolOverrides = obeliskHaskellPackages: defaultTools:
let
hash-nixpkgs = import ./tooling/dep/nixos-unstable-for-hashes { };
toolHaskellPackages = obeliskHaskellPackages.override {
# This overlay fixes haskell-language-server
overrides = import ./tooling/overlay.nix { inherit pkgs; };
# Use a newer hackage database than distributed with reflex-platform
all-cabal-hashes = hash-nixpkgs.all-cabal-hashes;
};
in {
# We take hlint and haskell-language-server from the same overrides so
# that they stay compatible.
inherit (toolHaskellPackages) haskell-language-server;
};
For ghc 8.10, that is hls 2.2:
{ pkgs }:
final: prev:
let
inherit (pkgs) lib;
inherit (pkgs.haskell.lib)
doJailbreak
dontCheck
disableCabalFlag
unmarkBroken
overrideCabal
;
hlsVersion = "2.2.0.0";
new =
lib.mapAttrs (name: version: dontCheck (final.callHackage name version { }))
{
# This is generally then newest version of these packages which is
# compatible with ghc 8.10.7 and hlsVersion.
# Figured out via iterative testing.
co-log-core = "0.3.2.0";
ghc-check = "0.5.0.8";
ghc-lib-parser = "9.2.8.20230729";
ghc-lib-parser-ex = "9.2.1.1";
ghc-source-gen = "0.4.3.0";
ghcide = hlsVersion;
githash = "0.1.6.1";
haskell-language-server = hlsVersion;
hie-bios = "0.12.0";
hie-compat = "0.3.0.0";
hiedb = "0.4.3.0";
hlint = "3.4.1";
hls-alternate-number-format-plugin = hlsVersion;
hls-call-hierarchy-plugin = hlsVersion;
hls-change-type-signature-plugin = hlsVersion;
hls-class-plugin = hlsVersion;
hls-code-range-plugin = hlsVersion;
hls-eval-plugin = hlsVersion;
hls-explicit-fixity-plugin = hlsVersion;
hls-explicit-imports-plugin = hlsVersion;
hls-gadt-plugin = hlsVersion;
hls-graph = hlsVersion;
hls-haddock-comments-plugin = hlsVersion;
hls-hlint-plugin = hlsVersion;
hls-module-name-plugin = hlsVersion;
hls-plugin-api = hlsVersion;
hls-pragmas-plugin = hlsVersion;
hls-qualify-imported-names-plugin = hlsVersion;
hls-refactor-plugin = hlsVersion;
hls-refine-imports-plugin = hlsVersion;
hls-rename-plugin = hlsVersion;
hls-retrie-plugin = hlsVersion;
hls-splice-plugin = hlsVersion;
hls-tactics-plugin = hlsVersion;
hls-cabal-fmt-plugin = hlsVersion;
hls-cabal-plugin = hlsVersion;
hls-explicit-record-fields-plugin = hlsVersion;
implicit-hie = "0.1.2.7";
implicit-hie-cradle = "0.5.0.1";
lsp = hlsVersion;
lsp-test = "0.16.0.0";
lsp-types = "2.0.2.0";
retrie = "0.1.1.1";
text-rope = "0.2";
};
in
new
// {
retrie = doJailbreak new.retrie;
extensions = unmarkBroken prev.extensions;
trial-tomland = unmarkBroken prev.trial-tomland;
# Formatters are disabled because we don’t need them.
# ormolu is disabled because our ormolu version is not compatible with ghc 8.6.5
hls-brittany-plugin = null;
hls-floskell-plugin = null;
hls-fourmolu-plugin = null;
hls-ormolu-plugin = null;
hls-stylish-haskell-plugin = null;
# Unimportant plugins which would require more work to fix
hls-stan-plugin = null;
hls-retrie-plugin = null;
hls-cabal-plugin = null;
# We need no testing utils
ghcide-bench = null;
hls-test-utils = null;
ghcide-test-utils = null;
haskell-language-server = lib.pipe new.haskell-language-server (
map (lib.flip disableCabalFlag) [
"floskell"
"fourmolu"
"ormolu"
"stylishhaskell"
"brittany"
"stan"
"retrie"
"cabal"
]
++ [
(lib.flip overrideCabal {
enableSharedExecutables = true;
postInstall = ''
mv "$out/bin/haskell-language-server" "$out/bin/haskell-language-server-${final.ghc.version}"
'';
})
]
);
}
For ghc 8.6, that is hls 1.8:
{ pkgs }:
final: prev:
let
inherit (pkgs) lib;
inherit (pkgs.haskell.lib)
doJailbreak
dontCheck
disableCabalFlag
addSetupDepends
overrideCabal
;
newerCabal = lib.flip addSetupDepends [
(final.callHackage "Cabal" "3.2.0.0" { })
];
new =
lib.mapAttrs (name: version: dontCheck (final.callHackage name version { }))
{
# This is generally then newest version of these packages which is
# compatible with ghc 8.6.5 and hls 1.8.0.0.
# Figured out via iterative testing.
co-log-core = "0.3.2.0";
ghc-check = "0.5.0.8";
ghc-lib-parser = "8.10.4.20210206";
ghc-lib-parser-ex = "8.10.0.24";
ghc-source-gen = "0.4.3.0";
ghcide = "1.8.0.0";
githash = "0.1.6.1";
haskell-language-server = "1.8.0.0";
hie-bios = "0.11.0";
hie-compat = "0.3.0.0";
hiedb = "0.4.2.0";
hlint = "3.2.8";
hls-alternate-number-format-plugin = "1.2.0.0";
hls-call-hierarchy-plugin = "1.1.0.0";
hls-change-type-signature-plugin = "1.0.1.1";
hls-class-plugin = "1.1.0.0";
hls-code-range-plugin = "1.0.0.0";
hls-eval-plugin = "1.3.0.0";
hls-explicit-fixity-plugin = "1.0.0.0";
hls-explicit-imports-plugin = "1.1.0.1";
hls-gadt-plugin = "1.0.0.0";
hls-graph = "1.8.0.0";
hls-haddock-comments-plugin = "1.1.0.0";
hls-hlint-plugin = "1.1.0.0";
hls-module-name-plugin = "1.1.0.0";
hls-plugin-api = "1.5.0.0";
hls-pragmas-plugin = "1.0.4.0";
hls-qualify-imported-names-plugin = "1.0.1.0";
hls-refactor-plugin = "1.0.0.0";
hls-refine-imports-plugin = "1.0.3.0";
hls-rename-plugin = "1.0.1.0";
hls-retrie-plugin = "1.0.2.2";
hls-splice-plugin = "1.0.2.0";
hls-tactics-plugin = "1.7.0.0";
implicit-hie = "0.1.4.0";
implicit-hie-cradle = "0.5.0.1";
lsp = "1.6.0.0";
lsp-test = "0.14.1.0";
lsp-types = "1.6.0.0";
retrie = "0.1.1.1";
text-rope = "0.2";
};
in
new
// {
retrie = doJailbreak new.retrie;
# These packages use a too new syntax in their .cabal file.
ghcide = newerCabal new.ghcide;
implicit-hie-cradle = newerCabal new.implicit-hie-cradle;
hls-refactor-plugin = newerCabal new.hls-refactor-plugin;
# Formatters are disabled because we don’t need them.
# ormolu is disabled because our ormolu version is not compatible with ghc 8.6.5
hls-brittany-plugin = null;
hls-floskell-plugin = null;
hls-fourmolu-plugin = null;
hls-ormolu-plugin = null;
hls-stylish-haskell-plugin = null;
# We need no testing utils
ghcide-bench = null;
hls-test-utils = null;
ghcide-test-utils = null;
haskell-language-server = lib.pipe new.haskell-language-server (
map (lib.flip disableCabalFlag) [
"floskell"
"fourmolu"
"ormolu"
"stylishhaskell"
"brittany"
]
++ [
newerCabal
(lib.flip overrideCabal {
enableSharedExecutables = true;
postInstall = ''
mv "$out/bin/haskell-language-server" "$out/bin/haskell-language-server-${final.ghc.version}"
'';
})
]
);
}
I hope this is helpful (and compatible with the newest ob release, I assume so but haven’t tried). Have fun compiling!