Skip to content

Commit aa294fc

Browse files
authored
Merge pull request #1223 from fendor/enhance/cabal-file
Add option to enable/disable `.cabal` file support
2 parents 5a4ed0b + fba2f31 commit aa294fc

File tree

3 files changed

+60
-8
lines changed

3 files changed

+60
-8
lines changed

package.json

+16
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,22 @@
234234
"Prefer a multiple component session, if the build tool supports it. At the moment, only `cabal` supports multiple components session loading. If the `cabal` version does not support loading multiple components at once, we gracefully fall back to \"singleComponent\" mode."
235235
]
236236
},
237+
"haskell.supportCabalFiles": {
238+
"scope": "resource",
239+
"default": "automatic",
240+
"type": "string",
241+
"enum": [
242+
"enable",
243+
"disable",
244+
"automatic"
245+
],
246+
"description": "Enable Language Server support for `.cabal` files. Requires Haskell Language Server version >= 1.9.0.0.",
247+
"enumDescriptions": [
248+
"Enable Language Server support for `.cabal` files",
249+
"Disable Language Server support for `.cabal` files",
250+
"Enable Language Server support for `.cabal` files if the HLS version supports it."
251+
]
252+
},
237253
"haskell.maxCompletions": {
238254
"scope": "resource",
239255
"default": 40,

src/extension.ts

+43-7
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import {
2121
import { RestartServerCommandName, StartServerCommandName, StopServerCommandName } from './commands/constants';
2222
import * as DocsBrowser from './docsBrowser';
2323
import { HlsError, MissingToolError, NoMatchingHls } from './errors';
24-
import { findHaskellLanguageServer, IEnvVars } from './hlsBinaries';
25-
import { addPathToProcessPath, expandHomeDir, ExtensionLogger } from './utils';
24+
import { callAsync, findHaskellLanguageServer, IEnvVars } from './hlsBinaries';
25+
import { addPathToProcessPath, comparePVP, expandHomeDir, ExtensionLogger } from './utils';
2626

2727
// The current map of documents & folders to language servers.
2828
// It may be null to indicate that we are in the process of launching a server,
@@ -205,6 +205,12 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
205205
args = args.concat(extraArgs.split(' '));
206206
}
207207

208+
const cabalFileSupport: 'automatic' | 'enable' | 'disable' = workspace.getConfiguration(
209+
'haskell',
210+
uri,
211+
).supportCabalFiles;
212+
logger.info(`Support for '.cabal' files: ${cabalFileSupport}`);
213+
208214
// If we're operating on a standalone file (i.e. not in a folder) then we need
209215
// to launch the server in a reasonable current directory. Otherwise the cradle
210216
// guessing logic in hie-bios will be wrong!
@@ -253,14 +259,44 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
253259

254260
const pat = folder ? `${folder.uri.fsPath}/**/*` : '**/*';
255261
logger.log(`document selector patten: ${pat}`);
262+
263+
const cabalDocumentSelector = { scheme: 'file', language: 'cabal', pattern: pat };
264+
const haskellDocumentSelector = [
265+
{ scheme: 'file', language: 'haskell', pattern: pat },
266+
{ scheme: 'file', language: 'literate haskell', pattern: pat },
267+
];
268+
269+
const documentSelector = [...haskellDocumentSelector];
270+
271+
switch (cabalFileSupport) {
272+
case 'automatic':
273+
const hlsVersion = await callAsync(
274+
serverExecutable,
275+
['--numeric-version'],
276+
logger,
277+
currentWorkingDir,
278+
undefined /* this command is very fast, don't show anything */,
279+
false,
280+
serverEnvironment,
281+
);
282+
if (comparePVP(hlsVersion, '1.9.0.0') >= 0) {
283+
// If hlsVersion is >= '1.9.0.0'
284+
documentSelector.push(cabalDocumentSelector);
285+
}
286+
break;
287+
case 'enable':
288+
documentSelector.push(cabalDocumentSelector);
289+
break;
290+
case 'disable':
291+
break;
292+
default:
293+
break;
294+
}
295+
256296
const clientOptions: LanguageClientOptions = {
257297
// Use the document selector to only notify the LSP on files inside the folder
258298
// path for the specific workspace.
259-
documentSelector: [
260-
{ scheme: 'file', language: 'haskell', pattern: pat },
261-
{ scheme: 'file', language: 'literate haskell', pattern: pat },
262-
{ scheme: 'file', language: 'cabal', pattern: pat },
263-
],
299+
documentSelector: [...documentSelector],
264300
synchronize: {
265301
// Synchronize the setting section 'haskell' to the server.
266302
configurationSection: 'haskell',

src/hlsBinaries.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ type ProcessCallback = (
5858
* @param callback Upon process termination, execute this callback. If given, must resolve promise. On error, stderr and stdout are logged regardless of whether the callback has been specified.
5959
* @returns Stdout of the process invocation, trimmed off newlines, or whatever the `callback` resolved to.
6060
*/
61-
async function callAsync(
61+
export async function callAsync(
6262
binary: string,
6363
args: string[],
6464
logger: Logger,

0 commit comments

Comments
 (0)