Skip to content

Commit bc0f0d5

Browse files
authored
Merge pull request #223 from alanz/backend-config-option
Use enumeration to choose between hie, hls or ghcide
2 parents dd6eaa6 + 52a3b2c commit bc0f0d5

File tree

5 files changed

+80
-112
lines changed

5 files changed

+80
-112
lines changed

Changelog.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
### 0.0.40
2+
3+
Change the way the backend is configured, simplifying it.
4+
5+
* remove wrapper scripts (hie-vscode.sh/hie-vscode.bat)
6+
* dropdown choice between `haskell-ide-engine`, `haskell-language-server` or
7+
`ghcide` in the `hieVariant` setting.
8+
* this can be overridden by an explicit `hieExecutablePath`, as before.
9+
110
### 0.0.39
211

312
Remove verbose logging option, it is not longer supported.

hie-vscode.bat

Lines changed: 0 additions & 21 deletions
This file was deleted.

hie-vscode.sh

Lines changed: 0 additions & 26 deletions
This file was deleted.

package.json

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "vscode-hie-server",
33
"displayName": "Haskell Language Server",
44
"description": "Language Server Protocol for Haskell via HIE",
5-
"version": "0.0.39",
5+
"version": "0.0.40",
66
"license": "MIT",
77
"publisher": "alanz",
88
"engines": {
@@ -88,33 +88,6 @@
8888
"default": "brittany",
8989
"description": "The tool to use for formatting requests."
9090
},
91-
"languageServerHaskell.hieExecutablePath": {
92-
"scope": "resource",
93-
"type": "string",
94-
"default": "",
95-
"description":
96-
"Set the path to your hie executable, if it's not already on your $PATH. Works with ~, ${HOME} and ${workspaceFolder}."
97-
},
98-
"languageServerHaskell.useCustomHieWrapper": {
99-
"scope": "resource",
100-
"type": "boolean",
101-
"default": false,
102-
"description":
103-
"Use your own custom wrapper for hie (remember to specify the path!). This will take precedence over useHieWrapper and hieExecutablePath."
104-
},
105-
"languageServerHaskell.useCustomHieWrapperPath": {
106-
"scope": "resource",
107-
"type": "string",
108-
"default": "",
109-
"description":
110-
"Specify the full path to your own custom hie wrapper (e.g. ${HOME}/.hie-wrapper.sh). Works with ~, ${HOME} and ${workspaceFolder}."
111-
},
112-
"languageServerHaskell.noLspParam": {
113-
"scope": "resource",
114-
"type": "boolean",
115-
"default": false,
116-
"description": "Do not set the '--lsp' flag in the hie/hie-wrapper arguments when launching it"
117-
},
11891
"languageServerHaskell.showTypeForSelection.onHover": {
11992
"scope": "resource",
12093
"type": "boolean",
@@ -143,6 +116,20 @@
143116
"default": "",
144117
"description": "If set, redirects the logs to a file."
145118
},
119+
"languageServerHaskell.hieVariant": {
120+
"scope": "resource",
121+
"type": "string",
122+
"enum": ["haskell-ide-engine", "haskell-language-server", "ghcide"],
123+
"default": "haskell-ide-engine",
124+
"description": "Which haskell language server to use."
125+
},
126+
"languageServerHaskell.hieExecutablePath": {
127+
"scope": "resource",
128+
"type": "string",
129+
"default": "",
130+
"description":
131+
"Set the path to your hie executable, if it's not already on your $PATH. Works with ~, ${HOME} and ${workspaceFolder}."
132+
},
146133
"languageServerHaskell.enableHIE": {
147134
"scope": "resource",
148135
"type": "boolean",

src/extension.ts

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
import * as child_process from 'child_process';
33
import * as os from 'os';
4-
import * as path from 'path';
54
import {
65
commands,
76
ExtensionContext,
@@ -69,13 +68,33 @@ async function activateHie(context: ExtensionContext, document: TextDocument) {
6968
}
7069

7170
try {
72-
const useCustomWrapper = workspace.getConfiguration('languageServerHaskell', uri).useCustomHieWrapper;
71+
const hieVariant = workspace.getConfiguration('languageServerHaskell', uri).hieVariant;
7372
const hieExecutablePath = workspace.getConfiguration('languageServerHaskell', uri).hieExecutablePath;
7473
// Check if hie is installed.
75-
if (!await isHieInstalled() && !useCustomWrapper && hieExecutablePath === '') {
74+
let exeName = 'hie';
75+
switch (hieVariant) {
76+
case 'haskell-ide-engine':
77+
break;
78+
case 'haskell-language-server':
79+
case 'ghcide':
80+
exeName = hieVariant;
81+
break;
82+
}
83+
if (!await isHieInstalled(exeName) && hieExecutablePath === '') {
7684
// TODO: Once haskell-ide-engine is on hackage/stackage, enable an option to install it via cabal/stack.
85+
let hieProjectUrl = '/haskell/haskell-ide-engine';
86+
switch (hieVariant) {
87+
case 'haskell-ide-engine':
88+
break;
89+
case 'haskell-language-server':
90+
hieProjectUrl = '/haskell/haskell-language-server';
91+
break;
92+
case 'ghcide':
93+
hieProjectUrl = '/digital-asset/ghcide';
94+
break;
95+
}
7796
const notInstalledMsg: string =
78-
'hie executable missing, please make sure it is installed, see github.com/haskell/haskell-ide-engine.';
97+
exeName + ' executable missing, please make sure it is installed, see https://github.com' + hieProjectUrl + '.';
7998
const forceStart: string = 'Force Start';
8099
window.showErrorMessage(notInstalledMsg, forceStart).then(option => {
81100
if (option === forceStart) {
@@ -104,22 +123,13 @@ function activateHieNoCheck(context: ExtensionContext, folder: WorkspaceFolder,
104123
docsBrowserRegistered = true;
105124
}
106125

107-
const useCustomWrapper = workspace.getConfiguration('languageServerHaskell', uri).useCustomHieWrapper;
126+
const hieVariant = workspace.getConfiguration('languageServerHaskell', uri).hieVariant;
108127
let hieExecutablePath = workspace.getConfiguration('languageServerHaskell', uri).hieExecutablePath;
109-
let customWrapperPath = workspace.getConfiguration('languageServerHaskell', uri).useCustomHieWrapperPath;
110-
const noLspParam = workspace.getConfiguration('languageServerHaskell', uri).noLspParam;
111128
const logLevel = workspace.getConfiguration('languageServerHaskell', uri).trace.server;
112129
const logFile = workspace.getConfiguration('languageServerHaskell', uri).logFile;
113130

114131
// Substitute path variables with their corresponding locations.
115-
if (useCustomWrapper) {
116-
customWrapperPath = customWrapperPath
117-
.replace('${workspaceFolder}', folder.uri.path)
118-
.replace('${workspaceRoot}', folder.uri.path)
119-
.replace('${HOME}', os.homedir)
120-
.replace('${home}', os.homedir)
121-
.replace(/^~/, os.homedir);
122-
} else if (hieExecutablePath !== '') {
132+
if (hieExecutablePath !== '') {
123133
hieExecutablePath = hieExecutablePath
124134
.replace('${workspaceFolder}', folder.uri.path)
125135
.replace('${workspaceRoot}', folder.uri.path)
@@ -128,32 +138,39 @@ function activateHieNoCheck(context: ExtensionContext, folder: WorkspaceFolder,
128138
.replace(/^~/, os.homedir);
129139
}
130140

131-
// Set the executable, based on the settings. The order goes: First
132-
// check useCustomWrapper, then check hieExecutablePath, else retain
133-
// original path.
134-
let hieLaunchScript = process.platform === 'win32' ? 'hie-vscode.bat' : 'hie-vscode.sh';
135-
if (useCustomWrapper) {
136-
hieLaunchScript = customWrapperPath;
137-
} else if (hieExecutablePath !== '') {
141+
// Set the executable, based on the settings.
142+
let hieLaunchScript = 'hie'; // should get set below
143+
switch (hieVariant) {
144+
case 'haskell-ide-engine':
145+
hieLaunchScript = 'hie-wrapper';
146+
break;
147+
case 'haskell-language-server':
148+
hieLaunchScript = 'haskell-language-server-wrapper';
149+
break;
150+
case 'ghcide':
151+
hieLaunchScript = 'ghcide';
152+
break;
153+
}
154+
if (hieExecutablePath !== '') {
138155
hieLaunchScript = hieExecutablePath;
139156
}
140157

141158
// If using a custom wrapper or specificed an executable path, the path is assumed to already
142159
// be absolute.
143-
const serverPath =
144-
useCustomWrapper || hieExecutablePath ? hieLaunchScript : context.asAbsolutePath(path.join('.', hieLaunchScript));
160+
const serverPath = hieLaunchScript;
145161

146-
const runArgs: string[] = [];
147-
let debugArgs: string[] = [];
148-
if (logLevel === 'messages') {
149-
debugArgs = ['-d'];
150-
}
151-
if (!noLspParam) {
152-
runArgs.unshift('--lsp');
153-
debugArgs.unshift('--lsp');
154-
}
155-
if (logFile !== '') {
156-
debugArgs = debugArgs.concat(['-l', logFile]);
162+
const runArgs: string[] = ['--lsp'];
163+
let debugArgs: string[] = ['--lsp'];
164+
165+
// ghcide does not accept -d and -l params
166+
if (hieVariant !== 'ghcide') {
167+
if (logLevel === 'messages') {
168+
debugArgs = debugArgs.concat(['-d']);
169+
}
170+
171+
if (logFile !== '') {
172+
debugArgs = debugArgs.concat(['-l', logFile]);
173+
}
157174
}
158175

159176
// If the extension is launched in debug mode then the debug server options are used,
@@ -166,6 +183,8 @@ function activateHieNoCheck(context: ExtensionContext, folder: WorkspaceFolder,
166183
// Set a unique name per workspace folder (useful for multi-root workspaces).
167184
const langName = 'Haskell HIE (' + folder.name + ')';
168185
const outputChannel: OutputChannel = window.createOutputChannel(langName);
186+
outputChannel.appendLine('[client] run command = "' + serverPath + ' ' + runArgs.join(' ') + '"');
187+
outputChannel.appendLine('[client] debug command = "' + serverPath + ' ' + debugArgs.join(' ') + '"');
169188
const clientOptions: LanguageClientOptions = {
170189
// Use the document selector to only notify the LSP on files inside the folder
171190
// path for the specific workspace.
@@ -242,9 +261,9 @@ export function deactivate(): Thenable<void> {
242261
/*
243262
* Check if HIE is installed.
244263
*/
245-
async function isHieInstalled(): Promise<boolean> {
264+
async function isHieInstalled(exeName: string): Promise<boolean> {
246265
return new Promise<boolean>((resolve, reject) => {
247-
const cmd: string = process.platform === 'win32' ? 'where hie' : 'which hie';
266+
const cmd: string = process.platform === 'win32' ? 'where ' + exeName : 'which ' + exeName;
248267
child_process.exec(cmd, (error, stdout, stderr) => resolve(!error));
249268
});
250269
}

0 commit comments

Comments
 (0)