Start and stop LSP

This commit is contained in:
Radon Rosborough 2021-08-15 16:32:09 -07:00
parent f92c12d8b0
commit 3541169779
3 changed files with 130 additions and 47 deletions

View File

@ -140,40 +140,6 @@ export class Session {
);
}
}
if (this.config.lsp) {
if (this.config.lsp.setup) {
await this.run(this.privilegedExec(this.config.lsp.setup));
}
const lspArgs = this.privilegedExec(this.config.lsp.start);
const lspProc = spawn(lspArgs[0], lspArgs.slice(1));
this.lsp = {
proc: lspProc,
reader: new rpc.StreamMessageReader(lspProc.stdout),
writer: new rpc.StreamMessageWriter(lspProc.stdin),
};
this.lsp.reader.listen((data) => {
this.send({ event: "lspOutput", output: data });
});
lspProc.stderr.on("data", (data) =>
this.send({
event: "serviceLog",
service: "lsp",
output: data.toString("utf8"),
})
);
lspProc.on("close", (code, signal) =>
this.send({
event: "serviceFailed",
service: "lsp",
error: `Exited with status ${signal || code}`,
code: signal || code,
})
);
lspProc.on("error", (err) =>
this.send({ event: "serviceFailed", service: "lsp", error: `${err}` })
);
this.send({ event: "lspStarted", root: this.homedir });
}
this.ws.on("message", (msg) =>
this.msgQueue.add(() => this.receive(msg))
);
@ -256,6 +222,12 @@ export class Session {
}
await this.formatCode(msg.code);
break;
case "lspStart":
await this.startLSP();
break;
case "lspStop":
await this.stopLSP();
break;
case "lspInput":
if (typeof msg.input !== "object" || !msg) {
this.logBadMessage(msg);
@ -348,7 +320,7 @@ export class Session {
});
}
});
this.term.pty.on("exit", (code, signal) => {
this.term.pty.on("close", (code, signal) => {
if (term.live) {
this.send({
event: "serviceFailed",
@ -358,6 +330,15 @@ export class Session {
});
}
});
this.term.pty.on("error", (err) => {
if (term.live) {
this.send({
event: "serviceFailed",
service: "terminal",
error: `${err}`,
});
}
});
} catch (err) {
logError(err);
this.sendError(err);
@ -431,6 +412,63 @@ export class Session {
}
};
stopLSP = async () => {
if (this.lsp) {
this.lsp.stopping = true;
this.lsp.proc.kill();
this.lsp = null;
}
};
startLSP = async () => {
if (this.config.lsp) {
await this.stopLSP();
if (this.config.lsp.setup) {
await this.run(this.privilegedExec(this.config.lsp.setup));
}
const lspArgs = this.privilegedExec(this.config.lsp.start);
const lspProc = spawn(lspArgs[0], lspArgs.slice(1));
const lsp = {
proc: lspProc,
reader: new rpc.StreamMessageReader(lspProc.stdout),
writer: new rpc.StreamMessageWriter(lspProc.stdin),
live: true,
stopping: false,
};
this.lsp = lsp;
this.lsp.reader.listen((data) => {
this.send({ event: "lspOutput", output: data });
});
lspProc.stderr.on("data", (data) => {
if (lsp.live) {
this.send({
event: "serviceLog",
service: "lsp",
output: data.toString("utf8"),
});
}
});
lspProc.on("close", (code, signal) => {
if (lsp.stopping) {
this.send({
event: "lspStopped",
});
} else {
this.send({
event: "serviceFailed",
service: "lsp",
error: `Exited with status ${signal || code}`,
code: signal || code,
});
}
});
lspProc.on("error", (err) =>
this.send({ event: "serviceFailed", service: "lsp", error: `${err}` })
);
this.send({ event: "lspStarted", root: this.homedir });
}
};
ensure = async (cmd) => {
const code = (
await this.run(this.privilegedExec(cmd), {

View File

@ -51,8 +51,8 @@
<i class="fas fa-code"></i>
</span>
</button>
<button id="lspButton" type="button" class="button is-small is-warning is-pulled-right is-hidden">
<span>Autocomplete OFF</span>
<button id="lspButton" type="button" class="button is-small is-warning is-light is-pulled-right is-hidden">
<span>Autocomplete <span id="lspButtonState">OFF</span></span>
<span class="icon is-small">
<i class="fas fa-bolt"></i>
</span>

View File

@ -22,6 +22,8 @@ const DEBUG = window.location.hash === "#debug";
const config = window.rijuConfig;
const formatButton = document.getElementById("formatButton");
const lspButton = document.getElementById("lspButton");
const lspButtonState = document.getElementById("lspButtonState");
function closeModal() {
document.querySelector("html").classList.remove("is-clipped");
@ -201,7 +203,25 @@ async function main() {
editor.setValue(message.code);
}
return;
case "lspStopped":
lspButton.disabled = false;
lspButton.classList.remove("is-loading");
lspButton.classList.add("is-light");
lspButtonState.innerText = "OFF";
if (clientDisposable) {
clientDisposable.dispose();
clientDisposable = null;
}
if (servicesDisposable) {
servicesDisposable.dispose();
servicesDisposable = null;
}
break;
case "lspStarted":
lspButton.disabled = false;
lspButton.classList.remove("is-loading");
lspButton.classList.remove("is-light");
lspButtonState.innerText = "ON";
if (typeof message.root !== "string") {
console.error("Unexpected message from server:", message);
return;
@ -272,16 +292,32 @@ async function main() {
serviceLogLines[message.service] = lines;
return;
case "serviceFailed":
if (typeof message.service !== "string") {
if (
typeof message.service !== "string" ||
typeof message.error !== "string"
) {
console.error("Unexpected message from server:", message);
return;
}
formatButton.disabled = false;
formatButton.classList.remove("is-loading");
showError({
message: "Could not prettify code!",
data: serviceLogLines["formatter"].join("\n"),
});
switch (message.service) {
case "formatter":
formatButton.disabled = false;
formatButton.classList.remove("is-loading");
showError({
message: "Could not prettify code!",
data: serviceLogLines["formatter"].join("\n"),
});
break;
case "lsp":
lspButton.disabled = false;
lspButton.classList.remove("is-loading");
lspButton.classList.remove("is-light");
lspButtonState.innerText = "CRASHED";
break;
case "terminal":
term.write(`\r\n[${message.error}]`);
break;
}
return;
default:
console.error("Unexpected message from server:", message);
@ -352,9 +388,18 @@ async function main() {
});
}
if (config.lsp) {
document.getElementById("lspButton").classList.remove("is-hidden");
document.getElementById("lspButton").addEventListener("click", () => {
// Do stuff here
lspButton.classList.remove("is-hidden");
lspButton.addEventListener("click", () => {
lspButton.classList.add("is-loading");
lspButton.disabled = true;
lspButton.classList.remove("is-light");
if (lspButtonState.innerText === "ON") {
sendMessage({ event: "lspStop" });
} else {
serviceLogBuffers["lsp"] = "";
serviceLogLines["lsp"] = [];
sendMessage({ event: "lspStart" });
}
});
}