From eb66554ce489e005984fe629987fd3f454612a95 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Sun, 5 Jul 2020 14:29:45 -0600 Subject: [PATCH] Configure LSP for C, C++, Objective-C, Rust --- backend/src/api.ts | 13 +++++++++++-- backend/src/langs.ts | 7 +++++++ backend/src/util.ts | 5 ++++- frontend/src/app.ts | 13 +++++++++++-- scripts/docker-install-phase3c.bash | 3 --- scripts/docker-install-phase4.bash | 17 +++++++++++++++++ 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/backend/src/api.ts b/backend/src/api.ts index 8f596c5..951aec1 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -123,6 +123,7 @@ export class Session { alwaysCreate, compile, run, + lspSetup, lsp, hacks, } = this.config; @@ -230,6 +231,14 @@ export class Session { } }); if (lsp && this.lsp === null) { + if (lspSetup) { + await spawnPrivileged( + this.uid!, + this.uuid, + ["bash", "-c", lspSetup], + this.log + ); + } const lspArgs = [ rijuSystemPrivileged, "spawn", @@ -261,7 +270,7 @@ export class Session { await spawnPrivileged( this.uid!, this.uuid, - ["kill", "-9", `${this.term.pty.pid}`], + ["bash", "-c", `kill -9 ${this.term.pty.pid} 2>/dev/null || true`], this.log ); } @@ -269,7 +278,7 @@ export class Session { await spawnPrivileged( this.uid!, this.uuid, - ["kill", "-9", `${this.lsp.proc.pid}`], + ["bash", "-c", `kill -9 ${this.lsp.proc.pid} 2>/dev/null || true`], this.log ); } diff --git a/backend/src/langs.ts b/backend/src/langs.ts index 8cdaa63..436a376 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -9,6 +9,7 @@ export interface LangConfig { alwaysCreate?: boolean; compile?: string; run: string; + lspSetup?: string; lsp?: string; lspInit?: any; lspConfig?: any; @@ -147,6 +148,7 @@ implement main0 () = () main: "main.c", compile: "clang -Wall -Wextra main.c -o main", run: "./main", + lspSetup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, lsp: "clangd", template: `#include @@ -202,6 +204,8 @@ int main() { main: "main.cpp", compile: "clang++ -Wall -Wextra main.cpp -o main", run: "./main", + lspSetup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, + lsp: "clangd", template: `#include int main() { @@ -640,6 +644,8 @@ require("repl").start() compile: "gcc $(gnustep-config --objc-flags) main.m $(gnustep-config --base-libs) -o main", run: "./main", + lspSetup: `(gnustep-config --objc-flags && gnustep-config --base-libs) | sed -E 's/\\s+/\\n/g' > compile_flags.txt`, + lsp: "clangd", template: `#import int main() { @@ -813,6 +819,7 @@ binding_irb.run(IRB.conf) main: "main.rs", compile: "rustc main.rs", run: "./main", + lsp: "rls", template: `fn main() { println!("Hello, world!"); } diff --git a/backend/src/util.ts b/backend/src/util.ts index b1d7a64..328f13a 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -5,6 +5,7 @@ import * as appRoot from "app-root-path"; interface Options extends SpawnOptions { input?: string; + check?: boolean; } export const rijuSystemPrivileged = appRoot.resolve( @@ -32,7 +33,9 @@ export async function call( ) { options = options || {}; const input = options.input; + const check = options.check === undefined ? true : options.check; delete options.input; + delete options.check; const proc = spawn(args[0], args.slice(1), options); if (input) { proc.stdin!.end(input); @@ -51,7 +54,7 @@ export async function call( if (output) { log(`Output from ${args[0]}:\n` + output); } - if (code === 0) { + if (code === 0 || !check) { resolve(); } else { reject(`command ${args[0]} failed with error code ${code}`); diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 29ef230..045affa 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -3,6 +3,7 @@ import { createConnection, MonacoLanguageClient, MonacoServices, + Services, } from "monaco-languageclient"; import { Disposable } from "vscode"; import { createMessageConnection } from "vscode-jsonrpc"; @@ -117,6 +118,7 @@ async function main() { function tryConnect() { let clientDisposable: Disposable | null = null; + let servicesDisposable: Disposable | null = null; console.log("Connecting to server..."); socket = new WebSocket( (document.location.protocol === "http:" ? "ws://" : "wss://") + @@ -156,6 +158,10 @@ async function main() { console.error("Unexpected message from server:", message); return; } + const services = MonacoServices.create(editor, { + rootUri: `file://${message.root}`, + }); + servicesDisposable = Services.install(services); editor.setModel( monaco.editor.createModel( editor.getModel()!.getValue(), @@ -205,6 +211,11 @@ async function main() { } if (clientDisposable) { clientDisposable.dispose(); + clientDisposable = null; + } + if (servicesDisposable) { + servicesDisposable.dispose(); + servicesDisposable = null; } scheduleConnect(); }); @@ -233,8 +244,6 @@ async function main() { document.getElementById("runButton")!.addEventListener("click", () => { sendMessage({ event: "runCode", code: editor.getValue() }); }); - - MonacoServices.install(editor); } main().catch(console.error); diff --git a/scripts/docker-install-phase3c.bash b/scripts/docker-install-phase3c.bash index e14bf0c..e4271e4 100755 --- a/scripts/docker-install-phase3c.bash +++ b/scripts/docker-install-phase3c.bash @@ -58,9 +58,6 @@ qemu-user-static # Ruby ruby -# Rust -rustc - " export DEBIAN_FRONTEND=noninteractive diff --git a/scripts/docker-install-phase4.bash b/scripts/docker-install-phase4.bash index 8274235..70e03ba 100755 --- a/scripts/docker-install-phase4.bash +++ b/scripts/docker-install-phase4.bash @@ -4,10 +4,24 @@ set -e set -o pipefail set -x +# Needed for project infrastructure npm config set unsafe-perm true PERL_MM_USE_DEFAULT=1 cpan App::cpanminus rm -rf /tmp/cpan_install_*.txt +export CARGO_HOME=/opt/rust +export RUSTUP_HOME=/opt/rust +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path + +tee /opt/rust/wrapper >/dev/null <<"EOF" +#!/usr/bin/env bash +RUSTUP_HOME=/opt/rust exec /opt/rust/bin/${0##*/} "$@" +EOF +chmod +x /opt/rust/wrapper +for file in /opt/rust/bin/*; do + ln -s /opt/rust/wrapper /usr/bin/${file##*/} +done + # Befunge npm install -g befunge93 prompt-sync @@ -26,6 +40,9 @@ cpanm -n Devel::REPL # ReasonML npm install -g bs-platform +# Rust +rustup component add rls rust-analysis rust-src + # Shakespeare pip3 install shakespearelang