From 35411697791c7149762262f35ed25506991810af Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 15 Aug 2021 16:32:09 -0700 Subject: [PATCH] Start and stop LSP --- backend/api.js | 108 ++++++++++++++++++++++++++++------------- frontend/pages/app.ejs | 4 +- frontend/src/app.js | 65 +++++++++++++++++++++---- 3 files changed, 130 insertions(+), 47 deletions(-) diff --git a/backend/api.js b/backend/api.js index 91d801c..80b26c8 100644 --- a/backend/api.js +++ b/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), { diff --git a/frontend/pages/app.ejs b/frontend/pages/app.ejs index df459eb..8afa2c5 100644 --- a/frontend/pages/app.ejs +++ b/frontend/pages/app.ejs @@ -51,8 +51,8 @@ -