Start and stop LSP
This commit is contained in:
parent
f92c12d8b0
commit
3541169779
108
backend/api.js
108
backend/api.js
|
@ -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), {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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" });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue