HLS support
- upgrade documentation and examples from ghcide to HLS
- test HLS and fix issues that occur
- update hie-bios documentation to cover rules_haskell support
- document full developer workflow, e.g. a video tutorial.
This is the relevant section of my WORKSPACE file for my build of haskell-language-server
http_archive(
name = "hlint-patched",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@haskell-language-server//:packages.bzl", "packages")
haskell_cabal_library(
name = "hlint",
version = packages["hlint"].version,
srcs = glob(["**"]),
deps = packages["hlint"].deps,
flags = ["+ghc-lib"],
visibility = ["//visibility:public"],
)
""",
sha256 = "98bd120a10a086c17d6bf1176a510dc12b36581e5a901f1e024555bb3ccead4f",
strip_prefix = "hlint-3.5",
urls = ["https://hackage.haskell.org/package/hlint-3.5/hlint-3.5.tar.gz"],
)
http_archive(
name = "ghc-lib-parser-ex-patched",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@haskell-language-server//:packages.bzl", "packages")
haskell_cabal_library(
name = "ghc-lib-parser-ex",
version = packages["ghc-lib-parser-ex"].version,
srcs = glob(["**"]),
deps = packages["ghc-lib-parser-ex"].deps,
flags = ["-auto"],
visibility = ["//visibility:public"],
)
""",
sha256 = "ce3ff339a0a259a18ae921c547b35732eaca1a567a33fba1a7c65c16c973191b",
strip_prefix = "ghc-lib-parser-ex-9.4.0.0",
urls = ["https://hackage.haskell.org/package/ghc-lib-parser-ex-9.4.0.0/ghc-lib-parser-ex-9.4.0.0.tar.gz"],
)
http_archive(
name = "ghc-lib-parser-patched",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@haskell-language-server//:packages.bzl", "packages")
haskell_cabal_library(
name = "ghc-lib-parser",
version = packages["ghc-lib-parser"].version,
srcs = glob(["**"]),
deps = packages["ghc-lib-parser"].deps,
tools = packages["ghc-lib-parser"].tools,
visibility = [
"@ghc-lib-parser-ex-patched//:__pkg__",
"@haskell-language-server//:__pkg__",
],
)
""",
sha256 = "5c2d44b7f1f50ebf04854e97c62b0d0f971d1636f195dc473456113067158db8",
strip_prefix = "ghc-lib-parser-9.4.5.20230430",
urls = ["https://hackage.haskell.org/package/ghc-lib-parser-9.4.5.20230430/ghc-lib-parser-9.4.5.20230430.tar.gz"],
)
http_archive(
name = "stylish-haskell-patched",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@haskell-language-server//:packages.bzl", "packages")
haskell_cabal_library(
name = "stylish-haskell",
version = packages["stylish-haskell"].version,
srcs = glob(["**"]),
deps = packages["stylish-haskell"].deps,
tools = packages["stylish-haskell"].tools,
visibility = [
"@haskell-language-server//:__pkg__",
],
flags = ["+ghc-lib"]
)
""",
sha256 = "67bda4d6b0bbc14cc7c640ab2db8e4776cd0a31dd50baed9e780efb9cb771b78",
strip_prefix = "stylish-haskell-0.14.4.0",
urls = ["https://hackage.haskell.org/package/stylish-haskell-0.14.4.0/stylish-haskell-0.14.4.0.tar.gz"],
)
http_archive(
name = "monad-dijkstra-patched",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@haskell-language-server//:packages.bzl", "packages")
haskell_cabal_library(
name = "monad-dijkstra",
version = packages["monad-dijkstra"].version,
srcs = glob(["**"]),
deps = packages["monad-dijkstra"].deps,
visibility = ["//visibility:public"],
)
""",
sha256 = "6c6270f94d27203b6974563398e4b7e81ae53e6110cffaecf8ff6297c11ceb8f",
patch_args = ["-p1"],
patches = ["//:monad-dijkstra.patch"],
strip_prefix = "monad-dijkstra-0.1.1.3",
urls = ["https://hackage.haskell.org/package/monad-dijkstra-0.1.1.3/monad-dijkstra-0.1.1.3.tar.gz"],
)
stack_snapshot(
name = "haskell-language-server",
# The rules_haskell example project shows how to import libz.
# https://github.com/tweag/rules_haskell/blob/123e3817156f9135dfa44dcb5a796c424df1f436/examples/WORKSPACE#L42-L63
extra_deps = {
"zlib": ["@zlib.dev//:zlib"],
"streaming-commons": ["@zlib.dev//:zlib"],
},
haddock = False,
local_snapshot = "//:haskell-language-server-stack-snapshot.yaml",
packages = [
"haskell-language-server",
],
components = {
"haskell-language-server": [
"lib",
"exe",
"exe:haskell-language-server-wrapper",
],
"attoparsec": [
"lib",
"lib:attoparsec-internal",
],
"ghcide": [ "lib", "exe" ],
"hie-bios": [ "lib", "exe" ],
},
components_dependencies = {
"attoparsec": """{"lib:attoparsec": ["lib:attoparsec-internal"]}""",
},
vendored_packages = {
"ghc-lib-parser": "@ghc-lib-parser-patched//:ghc-lib-parser",
"ghc-lib-parser-ex": "@ghc-lib-parser-ex-patched//:ghc-lib-parser-ex",
"hlint": "@hlint-patched//:hlint",
"monad-dijkstra": "@monad-dijkstra-patched//:monad-dijkstra",
"stylish-haskell": "@stylish-haskell-patched//:stylish-haskell",
},
stack_snapshot_json = "//:haskell-language-server_snapshot.json"
)
Here is my haskell-language-server-stack-snapshot.yaml
resolver: nightly-2023-06-15
packages:
- Cabal-3.10.1.0
- Cabal-syntax-3.10.1.0
- co-log-core-0.3.2.0
- floskell-0.10.7
- heapsize-0.3.0.1@sha256:0b69aa97a46d819b700ac7b145f3b5493c3565cf2c5b8298682238d405d0326e,1417
- hie-bios-0.12.0
- hiedb-0.4.3.0
- implicit-hie-0.1.2.7
- implicit-hie-cradle-0.5.0.1
- lsp-1.6.0.0
- lsp-test-0.14.1.0
- lsp-types-1.6.0.0
- monad-dijkstra-0.1.1.3@sha256:d2fc098d7c122555e726830a12ae0423ac187f89de9228f32e56e2f6fc2238e1,1900
- retrie-1.2.2
- aeson-2.1.2.1
- algebraic-graphs-0.6.1
- apply-refact-0.11.0.0
- data-default-0.7.1.1
- dependent-sum-0.7.2.0
- fail-4.9.0.0
- fourmolu-0.11.0.0
- free-5.2
- generically-0.1.1
- ghc-exactprint-1.6.1.3
- ghc-lib-parser-9.4.4.20221225
- ghc-lib-parser-ex-9.4.0.0
- haddock-library-1.11.0
- hlint-3.5
- hw-prim-0.6.3.2
- invariant-0.6.1
- lens-5.2.2
- ordered-containers-0.2.3
- ormolu-0.5.3.0
- primitive-0.8.0.0
- some-1.0.5
- syb-0.7.2.3
- stylish-haskell-0.14.4.0
- th-lift-instances-0.1.20
- archive: "haskell-language-server-2.0.0.1.tar.gz"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/hie-compat"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/hls-graph"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/ghcide/"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/ghcide/test"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/hls-plugin-api"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/hls-test-utils"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/shake-bench"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-call-hierarchy-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-class-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-explicit-imports-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-qualify-imported-names-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-refine-imports-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-hlint-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-rename-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-retrie-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-stylish-haskell-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-floskell-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-fourmolu-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-pragmas-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-module-name-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-ormolu-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-alternate-number-format-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-code-range-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-change-type-signature-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-gadt-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-explicit-fixity-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-refactor-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-cabal-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-cabal-fmt-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-explicit-record-fields-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-splice-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-eval-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
- archive: "haskell-language-server-2.0.0.1.tar.gz"
subdir: "/plugins/hls-overloaded-record-dot-plugin"
sha256: "6ae0be05780300427abbc6ef155b2995ef14bca7a6ab39b8055ac463cf6fdfe5"
Note that I checked in the binary haskell-language-server-2.0.0.1.tar.gz. Otherwise pinning would download it over and over and over. Maybe there needs to be a different bug, but with the sha256 specified there, maybe we could download it only once?
Contents of monad-dijkstra.patch:
diff -U5 -r a/monad-dijkstra.cabal b/monad-dijkstra.cabal
--- a/monad-dijkstra.cabal 2001-09-08 19:46:40.000000000 -0600
+++ b/monad-dijkstra.cabal 2023-06-16 16:08:16.402351266 -0600
@@ -17,11 +17,11 @@
exposed-modules: Control.Monad.Search
build-depends: base >= 4.7 && < 5
, containers >= 0.5.6.2 && < 0.7
, transformers >= 0.4.2.0 && < 0.6
, mtl >= 2.2.0 && < 2.3
- , free >= 4.12.0 && < 5.2
+ , free >= 4.12.0 && < 5.3
, psqueues >= 0.2.0.0 && < 0.3
default-language: Haskell2010
ghc-options: -Wall
test-suite test-monad-dijkstra
Contents of .bazel-hls
output_base and symlink_prefix are useful, but not necessary. output_base prevents the swith from opt to fastbuild from happening repeatedly. You want HLS to be built optimized. You want everyday builds to be fastbuild.
#!/usr/bin/env bash
set -euo pipefail
BAZEL=/home/kyle/.local/bin/bazel
$BAZEL \
--output_base=/home/kyle/.cache/bazel/_bazel_kyle_hls \
build \
--compilation_mode=opt \
--symlink_prefix=bazel-hls- \
@haskell-language-server-exe//haskell-language-server \
@haskell-language-server-exe//haskell-language-server:haskell-language-server-wrapper \
@haskell-language-server-exe//hie-bios \
@haskell-language-server-exe//ghcide
export PATH="$PWD/bazel-hls-bin/external/haskell-language-server/haskell-language-server-2.0.0.1/_install/bin:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin:/home/kyle/go/bin"
export PATH="$PWD/bazel-hls-bin/external/haskell-language-server/ghcide-2.0.0.1/_install/bin/:$PATH"
export PATH="$PWD/bazel-hls-yesod-bridge/external/rules_haskell_ghc_nixpkgs_haskell_toolchain/bin:$PATH"
bazel-hls-bin/external/haskell-language-server/haskell-language-server-2.0.0.1/_install/bin/haskell-language-server-wrapper "$@"
This is the relevant section of my WORKSPACE file for my build of haskell-language-server
@iteratee Thank you for sharing your configuration! I see a lot of patched packages in that configuration, but apart from Monad Dijkstra no patch files, so I'm not sure what the patches change relative to the Stackage snapshot. I see they're adding flags - would it work if you use the flags attribute to stack_snapshot instead?
Note that I checked in the binary
haskell-language-server-2.0.0.1.tar.gz. Otherwise pinning would download it over and over and over. Maybe there needs to be a different bug, but with the sha256 specified there, maybe we could download it only once?
Bazel's --repository_cache flag should avoid repeated downloads of these artifacts.
With the PR I just posted, I can use flags. The WORKSPACE now looks like:
http_archive(
name = "monad-dijkstra-patched",
build_file_content = """
load("@rules_haskell//haskell:cabal.bzl", "haskell_cabal_library")
load("@haskell-language-server//:packages.bzl", "packages")
haskell_cabal_library(
name = "monad-dijkstra",
version = packages["monad-dijkstra"].version,
srcs = glob(["**"]),
deps = packages["monad-dijkstra"].deps,
visibility = ["//visibility:public"],
)
""",
sha256 = "6c6270f94d27203b6974563398e4b7e81ae53e6110cffaecf8ff6297c11ceb8f",
patch_args = ["-p1"],
patches = ["//:monad-dijkstra.patch"],
strip_prefix = "monad-dijkstra-0.1.1.3",
urls = ["https://hackage.haskell.org/package/monad-dijkstra-0.1.1.3/monad-dijkstra-0.1.1.3.tar.gz"],
)
stack_snapshot(
name = "haskell-language-server",
# The rules_haskell example project shows how to import libz.
# https://github.com/tweag/rules_haskell/blob/123e3817156f9135dfa44dcb5a796c424df1f436/examples/WORKSPACE#L42-L63
extra_deps = {
"zlib": ["@zlib.dev//:zlib"],
"streaming-commons": ["@zlib.dev//:zlib"],
},
haddock = False,
local_snapshot = "//:haskell-language-server-stack-snapshot.yaml",
packages = [
"haskell-language-server",
],
components = {
"haskell-language-server": [
"lib",
"exe",
"exe:haskell-language-server-wrapper",
],
"attoparsec": [
"lib",
"lib:attoparsec-internal",
],
"ghcide": [ "lib", "exe" ],
"hie-bios": [ "lib", "exe" ],
},
flags = {
"ghc-lib-parser-ex": [ "-auto", "-no-ghc-lib" ],
"hlint": [ "+ghc-lib" ],
"stylish-haskell": [ "+ghc-lib" ],
},
components_dependencies = {
"attoparsec": """{"lib:attoparsec": ["lib:attoparsec-internal"]}""",
},
vendored_packages = {
"monad-dijkstra": "@monad-dijkstra-patched//:monad-dijkstra",
},
stack_snapshot_json = "//:haskell-language-server_snapshot.json"
)
And the haskell-language-server-stack-snapshot.yaml looks like:
resolver: nightly-2023-06-15
packages:
- Cabal-3.10.1.0
- Cabal-syntax-3.10.1.0
- co-log-core-0.3.2.0
- floskell-0.10.7
- heapsize-0.3.0.1@sha256:0b69aa97a46d819b700ac7b145f3b5493c3565cf2c5b8298682238d405d0326e,1417
- hie-bios-0.12.0
- hiedb-0.4.3.0
- implicit-hie-0.1.2.7
- implicit-hie-cradle-0.5.0.1
- lsp-1.6.0.0
- lsp-test-0.14.1.0
- lsp-types-1.6.0.0
- monad-dijkstra-0.1.1.3@sha256:d2fc098d7c122555e726830a12ae0423ac187f89de9228f32e56e2f6fc2238e1,1900
- retrie-1.2.2
- aeson-2.1.2.1
- algebraic-graphs-0.6.1
- apply-refact-0.11.0.0
- data-default-0.7.1.1
- dependent-sum-0.7.2.0
- fail-4.9.0.0
- fourmolu-0.11.0.0
- free-5.2
- generically-0.1.1
- ghc-exactprint-1.6.1.3
- ghc-lib-parser-9.4.4.20221225
- ghc-lib-parser-ex-9.4.0.0
- haddock-library-1.11.0
- hlint-3.5
- hw-prim-0.6.3.2
- invariant-0.6.1
- lens-5.2.2
- ordered-containers-0.2.3
- ormolu-0.5.3.0
- primitive-0.8.0.0
- some-1.0.5
- syb-0.7.2.3
- stylish-haskell-0.14.4.0
- th-lift-instances-0.1.20
- github: haskell/haskell-language-server
commit: 783905f211ac63edf982dd1889c671653327e441
sha256: "42e0dcbad6ac37da9f60e1be53b957c737e92e47a6d49a57910ef9cfbf775085"
subdirs:
- "."
- "/hie-compat"
- "/hls-graph"
- "/ghcide/"
- "/ghcide/test"
- "/hls-plugin-api"
- "/hls-test-utils"
- "/shake-bench"
- "/plugins/hls-call-hierarchy-plugin"
- "/plugins/hls-class-plugin"
- "/plugins/hls-explicit-imports-plugin"
- "/plugins/hls-qualify-imported-names-plugin"
- "/plugins/hls-refine-imports-plugin"
- "/plugins/hls-hlint-plugin"
- "/plugins/hls-rename-plugin"
- "/plugins/hls-retrie-plugin"
- "/plugins/hls-stylish-haskell-plugin"
- "/plugins/hls-floskell-plugin"
- "/plugins/hls-fourmolu-plugin"
- "/plugins/hls-pragmas-plugin"
- "/plugins/hls-module-name-plugin"
- "/plugins/hls-ormolu-plugin"
- "/plugins/hls-alternate-number-format-plugin"
- "/plugins/hls-code-range-plugin"
- "/plugins/hls-change-type-signature-plugin"
- "/plugins/hls-gadt-plugin"
- "/plugins/hls-explicit-fixity-plugin"
- "/plugins/hls-refactor-plugin"
- "/plugins/hls-cabal-plugin"
- "/plugins/hls-cabal-fmt-plugin"
- "/plugins/hls-explicit-record-fields-plugin"
- "/plugins/hls-splice-plugin"
- "/plugins/hls-eval-plugin"
- "/plugins/hls-overloaded-record-dot-plugin"