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.ws.on("message", (msg) =>
|
||||||
this.msgQueue.add(() => this.receive(msg))
|
this.msgQueue.add(() => this.receive(msg))
|
||||||
);
|
);
|
||||||
|
@ -256,6 +222,12 @@ export class Session {
|
||||||
}
|
}
|
||||||
await this.formatCode(msg.code);
|
await this.formatCode(msg.code);
|
||||||
break;
|
break;
|
||||||
|
case "lspStart":
|
||||||
|
await this.startLSP();
|
||||||
|
break;
|
||||||
|
case "lspStop":
|
||||||
|
await this.stopLSP();
|
||||||
|
break;
|
||||||
case "lspInput":
|
case "lspInput":
|
||||||
if (typeof msg.input !== "object" || !msg) {
|
if (typeof msg.input !== "object" || !msg) {
|
||||||
this.logBadMessage(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) {
|
if (term.live) {
|
||||||
this.send({
|
this.send({
|
||||||
event: "serviceFailed",
|
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) {
|
} catch (err) {
|
||||||
logError(err);
|
logError(err);
|
||||||
this.sendError(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) => {
|
ensure = async (cmd) => {
|
||||||
const code = (
|
const code = (
|
||||||
await this.run(this.privilegedExec(cmd), {
|
await this.run(this.privilegedExec(cmd), {
|
||||||
|
|
|
@ -51,8 +51,8 @@
|
||||||
<i class="fas fa-code"></i>
|
<i class="fas fa-code"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button id="lspButton" type="button" class="button is-small is-warning is-pulled-right is-hidden">
|
<button id="lspButton" type="button" class="button is-small is-warning is-light is-pulled-right is-hidden">
|
||||||
<span>Autocomplete OFF</span>
|
<span>Autocomplete <span id="lspButtonState">OFF</span></span>
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fas fa-bolt"></i>
|
<i class="fas fa-bolt"></i>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -22,6 +22,8 @@ const DEBUG = window.location.hash === "#debug";
|
||||||
const config = window.rijuConfig;
|
const config = window.rijuConfig;
|
||||||
|
|
||||||
const formatButton = document.getElementById("formatButton");
|
const formatButton = document.getElementById("formatButton");
|
||||||
|
const lspButton = document.getElementById("lspButton");
|
||||||
|
const lspButtonState = document.getElementById("lspButtonState");
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
document.querySelector("html").classList.remove("is-clipped");
|
document.querySelector("html").classList.remove("is-clipped");
|
||||||
|
@ -201,7 +203,25 @@ async function main() {
|
||||||
editor.setValue(message.code);
|
editor.setValue(message.code);
|
||||||
}
|
}
|
||||||
return;
|
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":
|
case "lspStarted":
|
||||||
|
lspButton.disabled = false;
|
||||||
|
lspButton.classList.remove("is-loading");
|
||||||
|
lspButton.classList.remove("is-light");
|
||||||
|
lspButtonState.innerText = "ON";
|
||||||
if (typeof message.root !== "string") {
|
if (typeof message.root !== "string") {
|
||||||
console.error("Unexpected message from server:", message);
|
console.error("Unexpected message from server:", message);
|
||||||
return;
|
return;
|
||||||
|
@ -272,16 +292,32 @@ async function main() {
|
||||||
serviceLogLines[message.service] = lines;
|
serviceLogLines[message.service] = lines;
|
||||||
return;
|
return;
|
||||||
case "serviceFailed":
|
case "serviceFailed":
|
||||||
if (typeof message.service !== "string") {
|
if (
|
||||||
|
typeof message.service !== "string" ||
|
||||||
|
typeof message.error !== "string"
|
||||||
|
) {
|
||||||
console.error("Unexpected message from server:", message);
|
console.error("Unexpected message from server:", message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
formatButton.disabled = false;
|
switch (message.service) {
|
||||||
formatButton.classList.remove("is-loading");
|
case "formatter":
|
||||||
showError({
|
formatButton.disabled = false;
|
||||||
message: "Could not prettify code!",
|
formatButton.classList.remove("is-loading");
|
||||||
data: serviceLogLines["formatter"].join("\n"),
|
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;
|
return;
|
||||||
default:
|
default:
|
||||||
console.error("Unexpected message from server:", message);
|
console.error("Unexpected message from server:", message);
|
||||||
|
@ -352,9 +388,18 @@ async function main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (config.lsp) {
|
if (config.lsp) {
|
||||||
document.getElementById("lspButton").classList.remove("is-hidden");
|
lspButton.classList.remove("is-hidden");
|
||||||
document.getElementById("lspButton").addEventListener("click", () => {
|
lspButton.addEventListener("click", () => {
|
||||||
// Do stuff here
|
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