Added env generators

This commit is contained in:
iko 2022-03-20 12:49:21 +03:00
parent 3eb1500944
commit 2eda210e16
Signed by untrusted user: iko
GPG Key ID: 82C257048D1026F2
4 changed files with 114 additions and 30 deletions

View File

@ -5,6 +5,8 @@ const {
const {
readStream,
getStorage,
call,
hasCustomEnv
} = require("utils");
exports.getHLS = getHLS;
@ -147,8 +149,12 @@ async function getHLS() {
return explicitPath
}
const version = await getGHCVersion();
const localHLSPath = await which("haskell-language-server").catch((_) => null)
if (hasCustomEnv() && localHLSPath) {
return localHLSPath
}
const version = await getGHCVersion();
if (localHLSPath) {
sendNotification("Found HLS", "Found haskell-language-server in PATH. Checking if it is the right version.")
const v = await getHLSVersion(localHLSPath)
@ -175,35 +181,17 @@ function notifyToolDownloading(name) {
}
function getHLSVersion(path) {
return call(new Process(path, {
return call(path, {
args: ["--version"],
}))
})
.then((x) => x.match(/\(GHC: (\S+)\)/)[1].trim())
.catch((err) => sendPermanentNotification("HLS version check failed", err))
}
function which(name) {
return call(new Process("/usr/bin/which", {
return call("/usr/bin/which", {
args: [name],
shell: true,
})).then((p) => p.trim())
}).then((p) => p.trim())
}
function call(process) {
const promise = new Promise((resolve, reject) => {
process.onDidExit((exitCode) => {
console.log(exitCode)
if (exitCode == 0) {
readStream(process.stdout).then((x) => {
resolve(x);
});
} else {
readStream(process.stderr).then((x) => {
reject(x)
});
}
});
})
process.start()
return promise
}

View File

@ -9,8 +9,9 @@ const {
getHLSConfig,
} = require("configuration");
const {
getFileName,
getFileName, createEnv, getEnv
} = require("utils");
exports.activate = function () {
nova.commands.register("stop", (_workspace) => {
stopServer();
@ -107,10 +108,12 @@ function applyAllLSPEdits(edits, text) {
}
let lspClient = null;
async function startServer() {
await createEnv()
stopServer();
const path = await getServerPath();
const env = await getEnv()
const serverOptions = {
path: path,
path, env,
args: ["lsp", "--cwd", nova.workspace.path],
};
const clientOptions = {
@ -137,7 +140,3 @@ function stopServer() {
function getServerPath() {
return getHLS();
}
// function getLogPath() {
// return getStorage() + "/haskell-language-server.log";
// }

View File

@ -1,3 +1,8 @@
const {
sendNotification,
sendPermanentNotification,
} = require("notifications");
function readStream(readableStream) {
return new Promise((resolve, _reject) => {
const reader = readableStream.getReader();
@ -48,4 +53,88 @@ function traceRaw(x) {
return x;
}
module.exports = { readStream, getStorage, getFileName, trace, traceRaw };
async function call(path, args) {
const env = await getEnv()
const process = new Process(path, {...args, ...{env}});
const promise = new Promise((resolve, reject) => {
process.onDidExit((exitCode) => {
console.log(exitCode)
if (exitCode == 0) {
readStream(process.stdout).then((x) => {
resolve(x);
});
} else {
readStream(process.stderr).then((x) => {
reject(x)
});
}
});
})
process.start()
return promise
}
function parseEnvs(x) {
const env = {}
for (line of x.split("\n")) {
const res = line.match(/(.*?)=(.*)/)
if (res) {
env[res[1]] = res[2]
}
}
console.log(JSON.stringify(env))
return env
}
let envCache = null
async function createEnv() {
const generator = nova.workspace.config.get("env-generator")
if (generator) {
const [prog, ...args] = generator.split(/\s+/)
sendNotification("Generating environment", "Executing " + generator + ".")
const process = new Process(prog, {
shell: true,
args,
cwd: nova.workspace.path
});
const promise = new Promise((resolve, reject) => {
process.onDidExit((exitCode) => {
console.log(exitCode)
if (exitCode == 0) {
readStream(process.stdout).then((x) => {
resolve(x);
});
} else {
readStream(process.stderr).then((x) => {
reject(x)
});
}
});
})
process.start()
const envStr = await promise
.catch((err) => sendPermanentNotification("Generating environment failed", err))
envCache = parseEnvs(envStr)
}
}
async function getEnv() {
console.log(JSON.stringify(envCache))
if (!envCache) {
await createEnv()
}
return envCache
}
function hasCustomEnv() {
return (nova.workspace.config.get("env-generator") !== null)
}
module.exports = { readStream, getStorage, getFileName, trace, traceRaw, call, createEnv, hasCustomEnv, getEnv };

View File

@ -20,6 +20,14 @@
"type": "path",
"placeholder": "/usr/local/bin/example"
},
{
"key": "env-generator",
"title": "Environment generator",
"description": "You can specify a shell command which will be used to generate the environment, in which the extension will be executes. This is useful if you want to utilize `nix-shell`, `direnv` or any similar command.\n\nExpects the command to have the same stdout as the `env` command.",
"type": "enum",
"allowsCustom": true,
"values": ["nix-shell --run env", "direnv exec env"]
},
{
"type": "section",
"title": "Haskell Language Server settings",