Skip to content

Commit 334f400

Browse files
authored
Merge pull request #547 from hasufell/issue-540
Manage all the Haskell things
2 parents e48238c + 9c0ffb9 commit 334f400

File tree

7 files changed

+316
-212
lines changed

7 files changed

+316
-212
lines changed

.github/workflows/test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
jobs:
1010
build:
1111
strategy:
12+
fail-fast: false
1213
matrix:
1314
os: [macos-11, ubuntu-latest, windows-latest]
1415
ghc: [9.0.1, 8.10.4]
@@ -20,6 +21,9 @@ jobs:
2021
uses: actions/setup-node@v1
2122
with:
2223
node-version: 17
24+
- name: Upgrade ghcup
25+
run: ghcup upgrade -i -f
26+
shell: bash
2327
# Setup the environment for the tests
2428
- name: Ensure there is a supported ghc versions
2529
uses: haskell/actions/setup@v1

README.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ You can watch demos for some of these features [here](https://haskell-language-s
3232
- For Cabal based projects, both ghc and [cabal-install](https://www.haskell.org/cabal/) must be installed and on the PATH. It can also be installed with [ghcup](https://www.haskell.org/ghcup/) or [Chocolatey](https://www.haskell.org/platform/windows.html) on Windows.
3333
- For Stack based projects, [stack](http://haskellstack.org) must be installed and on the PATH.
3434
- If you are installing from an offline VSIX file, you need to install [language-haskell](https://github.com/JustusAdam/language-haskell) too after installation (either from the marketplace or offline).
35+
- Alternatively, you can let the extension manage your entire toolchain automatically (you'll be asked on first startup) via
36+
[ghcup](https://www.haskell.org/ghcup/), which should be pre-installed
3537

3638
## Configuration options
3739

@@ -71,17 +73,26 @@ The environment _only will be visible for the lsp server_, not for other extensi
7173

7274
### Downloaded binaries
7375

74-
This extension will download `haskell-language-server` binaries either via an internal ghcup (it will download it automaticlaly)
75-
or via a system ghcup (which must be present), unless you set the config option `haskell.manageHLS` to `PATH` (the extension
76-
will ask you on first start).
76+
This extension will download `haskell-language-server` binaries and the rest of the toolchain if you selected to use GHCup during
77+
first start. Check the `haskell.manageHLS` setting.
7778

7879
It will then download the newest version of haskell-language-server which has support for the required ghc.
7980
That means it could use an older version than the latest one, without the last features and bug fixes.
8081
For example, if a project needs ghc-8.10.4 the extension will download and use haskell-language-server-1.4.0, the lastest version which supported ghc-8.10.4. Even if the lastest global haskell language-server version is 1.5.1.
8182

82-
If you have disk space issues and use system ghcup, check `ghcup gc --help`.
83-
If you have disk space issues and use the internal ghcup, check the following directories, depending on your platform
84-
and possible delete them:
83+
If you have disk space issues, check `ghcup gc --help`.
84+
85+
You can also instruct the extension to use a different installation directory for the toolchain,
86+
e.g. to not interfere with system GHCup installation. Depending on your platform, add the full
87+
resolved path like so:
88+
89+
```json
90+
"haskell.serverEnvironment": {
91+
"GHCUP_INSTALL_BASE_PREFIX": "/home/foo/.config/Code/User/globalStorage/haskell.haskell/"
92+
}
93+
```
94+
95+
The internal storage paths for the extension depend on the platform:
8596

8697
| Platform | Path |
8798
| -------- | ------------------------------------------------------------------------------- |

package.json

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
"scope": "resource",
138138
"type": "string",
139139
"default": "",
140-
"markdownDescription": "An optional path where downloaded binaries will be stored. Check the default value [here](https://github.com/haskell/vscode-haskell#downloaded-binaries)"
140+
"markdownDescription": "An optional path where downloaded metadata will be stored. Check the default value [here](https://github.com/haskell/vscode-haskell#downloaded-binaries)"
141141
},
142142
"haskell.serverExecutablePath": {
143143
"scope": "resource",
@@ -151,6 +151,12 @@
151151
"default": "",
152152
"markdownDescription": "Pass additional arguments to the language server."
153153
},
154+
"haskell.ghcupExecutablePath": {
155+
"scope": "resource",
156+
"type": "string",
157+
"default": "",
158+
"markdownDescription": "Manually set a ghcup executable path."
159+
},
154160
"haskell.serverEnvironment": {
155161
"scope": "resource",
156162
"type": "object",
@@ -163,21 +169,37 @@
163169
"default": null,
164170
"description": "How to manage/find HLS installations.",
165171
"enum": [
166-
"system-ghcup",
167-
"internal-ghcup",
172+
"GHCup",
168173
"PATH"
169174
],
170175
"enumDescriptions": [
171-
"Will use a user-wide installation of ghcup (usually in '~/.ghcup') to manage HLS automatically",
172-
"Will use an internal installation of ghcup to manage HLS automatically, to avoid interfering with system ghcup",
173-
"Discovers HLS executables in system PATH"
176+
"Will use ghcup and manage Haskell toolchain in the default location (usually '~/.ghcup')",
177+
"Discovers HLS and other executables in system PATH"
174178
]
175179
},
176-
"haskell.useSystemGHCup": {
180+
"haskell.installStack": {
177181
"scope": "resource",
178182
"type": "boolean",
179-
"default": null,
180-
"description": "Whether to use the system ghcup or an internal one for installing HLS."
183+
"default": true,
184+
"description": "Whether to also install/manage stack when 'manageHLS' is set to 'GHCup'."
185+
},
186+
"haskell.installCabal": {
187+
"scope": "resource",
188+
"type": "boolean",
189+
"default": true,
190+
"description": "Whether to also install/manage cabal when 'manageHLS' is set to 'GHCup'."
191+
},
192+
"haskell.installGHC": {
193+
"scope": "resource",
194+
"type": "boolean",
195+
"default": true,
196+
"description": "Whether to also install/manage GHC when 'manageHLS' is set to 'GHCup'."
197+
},
198+
"haskell.upgradeGHCup": {
199+
"scope": "resource",
200+
"type": "boolean",
201+
"default": true,
202+
"description": "Whether to upgrade GHCup automatically when 'manageHLS' is set to 'GHCup'."
181203
},
182204
"haskell.checkProject": {
183205
"scope": "resource",

src/extension.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use strict';
22
import * as path from 'path';
33
import {
4-
env,
54
commands,
5+
env,
66
ExtensionContext,
77
OutputChannel,
88
TextDocument,
@@ -23,8 +23,8 @@ import {
2323
import { CommandNames } from './commands/constants';
2424
import { ImportIdentifier } from './commands/importIdentifier';
2525
import { DocsBrowser } from './docsBrowser';
26-
import { MissingToolError, addPathToProcessPath, findHaskellLanguageServer, IEnvVars } from './hlsBinaries';
27-
import { expandHomeDir, ExtensionLogger } from './utils';
26+
import { findHaskellLanguageServer, IEnvVars, MissingToolError } from './hlsBinaries';
27+
import { addPathToProcessPath, expandHomeDir, ExtensionLogger } from './utils';
2828

2929
// The current map of documents & folders to language servers.
3030
// It may be null to indicate that we are in the process of launching a server,
@@ -196,17 +196,17 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
196196
}
197197
logger.info(cwdMsg);
198198

199-
let serverEnvironment: IEnvVars = workspace.getConfiguration('haskell', uri).serverEnvironment;
199+
let serverEnvironment: IEnvVars = await workspace.getConfiguration('haskell', uri).serverEnvironment;
200200
if (addInternalServerPath !== undefined) {
201-
const newPath = addPathToProcessPath(addInternalServerPath);
201+
const newPath = await addPathToProcessPath(addInternalServerPath, logger);
202202
serverEnvironment = {
203-
PATH: newPath,
204203
...serverEnvironment,
204+
...{ PATH: newPath },
205205
};
206206
}
207207
const exeOptions: ExecutableOptions = {
208208
cwd: folder ? undefined : path.dirname(uri.fsPath),
209-
env: Object.assign(process.env, serverEnvironment),
209+
env: { ...process.env, ...serverEnvironment },
210210
};
211211

212212
// We don't want empty strings in our args

0 commit comments

Comments
 (0)