Skip to content

Commit af0ed98

Browse files
hasufellfendor
authored andcommitted
Simplify configuration/updates
This removes 'ignorePATH' and 'updateBehavior' config options and instead introduces a simple 'manageHLS' setting, which decides whether ghcup is used to install the appropriate HLS or not.
1 parent f996155 commit af0ed98

File tree

4 files changed

+87
-197
lines changed

4 files changed

+87
-197
lines changed

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,26 @@ The environment _only will be visible for the lsp server_, not for other extensi
7171

7272
### Downloaded binaries
7373

74-
This extension will download `haskell-language-server` binaries to a specific location depending on your system.
74+
This extension will download `haskell-language-server` binaries via an (internal) ghcup to a specific location depending
75+
on your system, unless you set the config option `haskell.manageHLS` to `false` (the default is `true`).
7576

7677
It will download the newest version of haskell-language-server which has support for the required ghc.
7778
That means it could use an older version than the latest one, without the last features and bug fixes.
7879
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.
7980

8081
If you find yourself running out of disk space, you can try deleting old versions of language servers in this directory. The extension will redownload them, no strings attached.
8182

82-
| Platform | Path |
83-
| -------- | ------------------------------------------------------------------------- |
84-
| macOS | `~/Library/Application\ Support/Code/User/globalStorage/haskell.haskell/` |
85-
| Windows | `%APPDATA%\Code\User\globalStorage\haskell.haskell` |
86-
| Linux | `$HOME/.config/Code/User/globalStorage/haskell.haskell` |
83+
| Platform | Path |
84+
| -------- | ------------------------------------------------------------------------------- |
85+
| macOS | `~/Library/Application\ Support/Code/User/globalStorage/haskell.haskell/.ghcup` |
86+
| Windows | `%APPDATA%\Code\User\globalStorage\haskell.haskell/ghcup` |
87+
| Linux | `$HOME/.config/Code/User/globalStorage/haskell.haskell/.ghcup` |
8788

88-
Note that if `haskell-language-server-wrapper`/`haskell-language-server` is already on the PATH or you have set the `haskell.serverExecutablePath` option, then the extension will launch it directly instead of downloading binaries, even if the version of the former is older then the latter.
89+
Note that if `haskell-language-server-wrapper`/`haskell-language-server` is already on the PATH or you have set the
90+
`haskell.serverExecutablePath` option, then the extension will try to launch it directly, and only fall back to
91+
downloading other binaries if these are unsuitable and `haskell.manageHLS` is set to `true`.
92+
93+
You can also tell HLS to use your system provided ghcup by setting `haskell.useSystemGHCup` to `true` (default is `false`).
8994

9095
### Supported GHC versions
9196

package.json

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -151,27 +151,11 @@
151151
"default": {},
152152
"markdownDescription": "Define environment variables for the language server."
153153
},
154-
"haskell.updateBehavior": {
155-
"scope": "machine",
156-
"type": "string",
157-
"enum": [
158-
"keep-up-to-date",
159-
"prompt",
160-
"never-check"
161-
],
162-
"enumDescriptions": [
163-
"Always download the latest available version when it is published",
164-
"Prompt before upgrading to a newer version",
165-
"Don't check for newer versions"
166-
],
167-
"default": "keep-up-to-date",
168-
"markdownDescription": "Determine what to do when a new version of the language server is available."
169-
},
170-
"haskell.ignorePATH": {
154+
"haskell.manageHLS": {
171155
"scope": "resource",
172156
"type": "boolean",
173-
"default": false,
174-
"description": "Whether to ignore haskell-language-server on PATH"
157+
"default": true,
158+
"description": "Let this extension manage required HLS versions via ghcup."
175159
},
176160
"haskell.useSystemGHCup": {
177161
"scope": "resource",

src/extension.ts

Lines changed: 7 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import {
2222
import { CommandNames } from './commands/constants';
2323
import { ImportIdentifier } from './commands/importIdentifier';
2424
import { DocsBrowser } from './docsBrowser';
25-
import { addPathToProcessPath, downloadGHCup, downloadHaskellLanguageServer, IEnvVars, validateHLSToolchain } from './hlsBinaries';
26-
import { directoryExists, executableExists, expandHomeDir, ExtensionLogger, resolvePathPlaceHolders } from './utils';
25+
import { addPathToProcessPath, findHaskellLanguageServer, IEnvVars, validateHLSToolchain } from './hlsBinaries';
26+
import { expandHomeDir, ExtensionLogger } from './utils';
2727

2828
// The current map of documents & folders to language servers.
2929
// It may be null to indicate that we are in the process of launching a server,
@@ -96,49 +96,6 @@ export async function activate(context: ExtensionContext) {
9696
context.subscriptions.push(openOnHackageDisposable);
9797
}
9898

99-
function findManualExecutable(logger: Logger, uri: Uri, folder?: WorkspaceFolder): string | null {
100-
let exePath = workspace.getConfiguration('haskell', uri).serverExecutablePath;
101-
if (exePath === '') {
102-
return null;
103-
}
104-
logger.info(`Trying to find the server executable in: ${exePath}`);
105-
exePath = resolvePathPlaceHolders(exePath, folder);
106-
logger.log(`Location after path variables substitution: ${exePath}`);
107-
108-
if (!executableExists(exePath)) {
109-
let msg = `serverExecutablePath is set to ${exePath}`;
110-
if (directoryExists(exePath)) {
111-
msg += ' but it is a directory and the config option should point to the executable file full path';
112-
} else {
113-
msg += " but it doesn't exist and it is not on the PATH";
114-
}
115-
throw new Error(msg);
116-
}
117-
return exePath;
118-
}
119-
120-
/** Searches the PATH for whatever is set in serverVariant
121-
*
122-
* return null when **haskell.ignorePATH** set
123-
*/
124-
function findLocalServer(context: ExtensionContext, logger: Logger, uri: Uri, folder?: WorkspaceFolder): string | null {
125-
if (workspace.getConfiguration('haskell').get('ignorePATH') === true) {
126-
logger.info('Ignoring haskell-language-server on PATH');
127-
return null;
128-
}
129-
const exes: string[] = ['haskell-language-server-wrapper', 'haskell-language-server'];
130-
logger.info(`Searching for server executables ${exes.join(',')} in $PATH`);
131-
logger.info(`$PATH environment variable: ${process.env.PATH}`);
132-
for (const exe of exes) {
133-
if (executableExists(exe)) {
134-
logger.info(`Found server executable in $PATH: ${exe}`);
135-
return exe;
136-
}
137-
}
138-
139-
return null;
140-
}
141-
14299
async function activeServer(context: ExtensionContext, document: TextDocument) {
143100
// We are only interested in Haskell files.
144101
if (
@@ -190,17 +147,11 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
190147
let serverExecutable;
191148
let addInternalServerPath: string | undefined; // if we download HLS, add that bin dir to PATH
192149
try {
193-
// Try and find local installations first
194-
serverExecutable = findManualExecutable(logger, uri, folder) ?? findLocalServer(context, logger, uri, folder);
195-
if (serverExecutable === null) {
196-
// If not, then try to download haskell-language-server binaries if it's selected
197-
await downloadGHCup(context, logger);
198-
serverExecutable = await downloadHaskellLanguageServer(context, logger, currentWorkingDir);
199-
await validateHLSToolchain(serverExecutable, currentWorkingDir, logger);
200-
addInternalServerPath = path.dirname(serverExecutable);
201-
if (!serverExecutable) {
202-
return;
203-
}
150+
serverExecutable = await findHaskellLanguageServer(context, logger, currentWorkingDir, folder);
151+
await validateHLSToolchain(serverExecutable, currentWorkingDir, logger);
152+
addInternalServerPath = path.dirname(serverExecutable);
153+
if (!serverExecutable) {
154+
return;
204155
}
205156
} catch (e) {
206157
if (e instanceof Error) {

0 commit comments

Comments
 (0)