Skip to content

Commit 93c5bae

Browse files
authored
Merge pull request #5796 from mpilgrem/docs-vscode
Add docs on Stack and VS Code
2 parents 62ecfc9 + 69977b3 commit 93c5bae

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

doc/Stack_and_VS_Code.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<div class="hidden-warning"><a href="https://docs.haskellstack.org/"><img src="https://cdn.jsdelivr.net/gh/commercialhaskell/stack/doc/img/hidden-warning.svg"></a></div>
2+
3+
# Stack and Visual Studio Code
4+
5+
[Visual Studio Code](https://code.visualstudio.com/) (VS Code) is a popular
6+
source code editor, and
7+
['Haskell'](https://marketplace.visualstudio.com/items?itemName=haskell.haskell)
8+
is an extension for VS Code that is popular with Haskell coders.
9+
10+
The 'Haskell' extension can be used with Stack but there are some things to be
11+
aware of, set out below.
12+
13+
## Haskell Language Server
14+
15+
The VS Code extension makes use of the Haskell Language Server (HLS). To work,
16+
HLS has to be built with the same version of GHC that it will support. That is,
17+
a version of HLS is required for each version of GHC in use. It is possible that
18+
the most recent versions of GHC are not supported by HLS.
19+
20+
By default, the VS Code extension uses tools that are in the PATH. However, the
21+
extension's settings (under 'Haskell: Manage HLS') allow a user to specify
22+
that the extension should use a separate application,
23+
[GHCup](https://www.haskell.org/ghcup/), to download and install the versions of
24+
HLS that it needs. GHCup can download and install things other than HLS,
25+
including GHC, MSYS2 (on Windows), Cabal (a build tool), and Stack itself. GHCup
26+
can also update itself. On Windows, GHCup has the capability of using the
27+
Stack-supplied MSYS2 rather than installing a duplicate copy. Cabal (the build
28+
tool), like Stack, depends on the Cabal (the library). Cabal (the tool), unlike
29+
Stack, does not have the capability to automatically install necessary versions
30+
of GHC, and (as well as supporting the extension) GHCup fills a important gap
31+
for users of the Cabal tool.
32+
33+
If the VS Code extension is set not to use GHCup, its user needs to ensure that
34+
each version of HLS that the extension needs is on the PATH.
35+
36+
For the most part, the versions of HLS provided by GHCup are built with the same
37+
versions of GHC that Stack downloads from its default `setup-info` dictionary
38+
(see [YAML configuration: setup-info](yaml_configuration.md)). Stack's default
39+
is to mirror the 'official' binary distributions published by GHC. However, in
40+
some cases, it is possible that a GHCup-supplied and GHCup-selected HLS has been
41+
built with a different binary distribution of GHC than the one which Stack has
42+
installed.
43+
44+
One example of that occurred with the release of GHC 9.0.2. For some Linux users
45+
(Debian 9 and Fedora 27), the version of GHC 9.0.2 linked on GHC’s download
46+
[web page](https://www.haskell.org/ghc/download_ghc_9_0_2.html) was broken. The
47+
GHC developers made alternative ‘9.0.2a’ versions available. For a while, Stack
48+
referred to the versions published by GHC on its download web page while the
49+
GHCup-supplied versions of HLS were built using alternative versions. This
50+
incompatibility led to problems. It was resolved by Stack's default also being
51+
changed to refer to the '9.0.2a' versions. (Where Stack has already installed
52+
GHC 9.0.2, it is necessary to delete GHC 9.0.2 from the `stack path --programs`
53+
directory. This will cause Stack to reinstall the alternative version, when it
54+
first needs GHC 9.0.2. Stack should distinguish what it builds with the
55+
alternative from what it has built, and cached, with the original GHC 9.0.2.)
56+
57+
### Workaround #1
58+
59+
One workaround is to allow GHCup to install versions of GHC on the PATH and to
60+
cause Stack to use those versions of GHC, by making use of Stack's `install-ghc`
61+
option (which needs to be disabled) and Stack's `system-ghc` option (which needs
62+
to be enabled) (see [YAML configuration](yaml_configuration.md)).
63+
64+
For this workaround to work, each time that a resolver is used that references a
65+
different version of GHC, then GHCup must be used to install it (if GHCup has
66+
not already installed that version). For example, to use `resolver: lts-19.16`
67+
(GHC 9.0.2), the command `ghcup install ghc 9.0.2` must have been used to
68+
install GHC 9.0.2. That may be a minor inconvenience for some people, as one the
69+
primary benefits of Stack over other Haskell build tools has been that Stack
70+
automatically ensures that the necessary version of GHC is available.
71+
72+
It is hoped that the next release of Stack will include a new feature that will
73+
allow the VS Code extension/GHCup to customise Stack, so that Stack can
74+
automatically obtain versions of GHC using GHCup and switch between GHC versions
75+
that GHCup has obtained. It is hoped a future release of the extension/GHCup
76+
will take advantage of that new feature. See
77+
[Stack #5585](https://github.com/commercialhaskell/stack/pull/5585) and
78+
[GHCup #392](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/392).
79+
80+
### Workaround #2
81+
82+
Another partial workaround is to install GHCup so that it is 'empty' except for
83+
the current version of HLS, allow the VS Code extension to use GHCup to manage
84+
HLS requirements only, and to ignore any messages (if any) from the extension on
85+
start-up that installation of GHC, Cabal (the tool) and/or Stack are also
86+
necessary (they are not, if only Stack is being used).
87+
88+
For this workaround to work, however, there can be no differences between the
89+
version of GHC that the GHCup-supplied HLS was built with and the version that
90+
Stack has installed. A slight inconvenience here is also the posibility of false
91+
messages from the start-up that need to be ignored. In principle, those messages
92+
can be disabled by
93+
[setting the following](https://github.com/haskell/vscode-haskell#setting-a-specific-toolchain)
94+
for the VS Code extension:
95+
96+
~~~yaml
97+
"haskell.toolchain": {
98+
"ghc": null,
99+
"cabal": null,
100+
"stack": null
101+
}
102+
~~~
103+
104+
To install a version of GHCup that is 'empty' is a little more complicated than
105+
a default installation of GHCup.
106+
107+
On Unix-like operating systems, the following environment variable must be set
108+
before GHCup's installation `sh` script is run: `BOOTSTRAP_HASKELL_MINIMAL`.
109+
110+
On Windows, the second argument to the PowerShell script must be set to
111+
`$false`, namely:
112+
113+
Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Invoke-WebRequest https://www.haskell.org/ghcup/sh/bootstrap-haskell.ps1 -UseBasicParsing))) -ArgumentList $true,$false
114+
115+
### Cradle
116+
117+
HLS may need a 'cradle' - an
118+
[`hie.yaml` file](https://hackage.haskell.org/package/hie-bios#stack) - in the
119+
project's root directory in order to work well.
120+
121+
The [`gen-hie` tool](https://hackage.haskell.org/package/implicit-hie) can help
122+
generate such a cradle.
123+
124+
### Tips
125+
126+
It has been suggested that a project must have been successfully built before
127+
the VS code extension (and HLS) is first activated on the project, for HLS to
128+
work reliably.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pages:
2222
- Configuration (project and global): yaml_configuration.md
2323
- stack.yaml vs cabal package files: stack_yaml_vs_cabal_package_file.md
2424
- Build command: build_command.md
25+
- Stack and Visual Studio Code: Stack_and_VS_Code.md
2526
- Developing on Windows: developing_on_windows.md
2627
- Dependency visualization: dependency_visualization.md
2728
- Docker integration: docker_integration.md

0 commit comments

Comments
 (0)