113 lines
2.6 KiB
JavaScript
113 lines
2.6 KiB
JavaScript
import child_process from "child_process";
|
|
import process from "process";
|
|
|
|
import readline from "historic-readline";
|
|
import rpc from "vscode-jsonrpc";
|
|
|
|
import { langsPromise } from "./langs.js";
|
|
import { quote } from "./util.js";
|
|
|
|
const args = process.argv.slice(2);
|
|
|
|
function printUsage() {
|
|
console.log(`usage: yarn lsp-repl (LANG | CMDLINE...)`);
|
|
}
|
|
|
|
if (args.length === 0) {
|
|
printUsage();
|
|
process.exit(1);
|
|
}
|
|
|
|
if (["-h", "-help", "--help", "help"].includes(args[0])) {
|
|
printUsage();
|
|
process.exit(0);
|
|
}
|
|
|
|
const langs = await langsPromise;
|
|
|
|
let cmdline;
|
|
if (args.length === 1 && langs[args[0]] && langs[args[0]].lsp) {
|
|
cmdline = ["bash", "-c", langs[args[0]].lsp.start];
|
|
} else {
|
|
cmdline = args;
|
|
}
|
|
|
|
console.error(cmdline.map(quote).join(" "));
|
|
const proc = child_process.spawn(cmdline[0], cmdline.slice(1));
|
|
|
|
proc.stderr.on("data", (data) => process.stderr.write(data));
|
|
proc.on("close", (code, signal) => {
|
|
if (code) {
|
|
console.error(`Language server exited with code ${code}`);
|
|
process.exit(code);
|
|
} else {
|
|
console.error(`Language server exited due to signal ${signal}`);
|
|
process.exit(1);
|
|
}
|
|
});
|
|
proc.on("error", (err) => {
|
|
console.error(`Failed to start language server: ${err}`);
|
|
process.exit(1);
|
|
});
|
|
|
|
const reader = new rpc.StreamMessageReader(proc.stdout);
|
|
const writer = new rpc.StreamMessageWriter(proc.stdin);
|
|
|
|
reader.listen((data) => {
|
|
console.log("<<< " + JSON.stringify(data) + "\n");
|
|
});
|
|
|
|
// https://stackoverflow.com/a/10608048/3538165
|
|
function fixStdoutFor(cli) {
|
|
var oldStdout = process.stdout;
|
|
var newStdout = Object.create(oldStdout);
|
|
newStdout.write = function () {
|
|
cli.output.write("\x1b[2K\r");
|
|
var result = oldStdout.write.apply(
|
|
this,
|
|
Array.prototype.slice.call(arguments)
|
|
);
|
|
cli._refreshLine();
|
|
return result;
|
|
};
|
|
process.__defineGetter__("stdout", function () {
|
|
return newStdout;
|
|
});
|
|
}
|
|
|
|
readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout,
|
|
path: ".lsp-repl-history",
|
|
next: (cli) => {
|
|
fixStdoutFor(cli);
|
|
cli.setPrompt(">>> ");
|
|
cli.on("line", (line) => {
|
|
if (line) {
|
|
let data;
|
|
try {
|
|
data = JSON.parse(line);
|
|
} catch (err) {
|
|
console.error(`Invalid JSON: ${err}`);
|
|
cli.prompt();
|
|
return;
|
|
}
|
|
console.log();
|
|
writer.write(data);
|
|
}
|
|
cli.prompt();
|
|
});
|
|
cli.on("SIGINT", () => {
|
|
console.error("^C");
|
|
cli.write("", { ctrl: true, name: "u" });
|
|
cli.prompt();
|
|
});
|
|
cli.on("close", () => {
|
|
console.error();
|
|
process.exit(0);
|
|
});
|
|
console.log();
|
|
cli.prompt();
|
|
},
|
|
});
|