Configure LSP for C, C++, Objective-C, Rust

This commit is contained in:
Radon Rosborough 2020-07-05 14:29:45 -06:00
parent 67cb37423c
commit eb66554ce4
6 changed files with 50 additions and 8 deletions

View File

@ -123,6 +123,7 @@ export class Session {
alwaysCreate, alwaysCreate,
compile, compile,
run, run,
lspSetup,
lsp, lsp,
hacks, hacks,
} = this.config; } = this.config;
@ -230,6 +231,14 @@ export class Session {
} }
}); });
if (lsp && this.lsp === null) { if (lsp && this.lsp === null) {
if (lspSetup) {
await spawnPrivileged(
this.uid!,
this.uuid,
["bash", "-c", lspSetup],
this.log
);
}
const lspArgs = [ const lspArgs = [
rijuSystemPrivileged, rijuSystemPrivileged,
"spawn", "spawn",
@ -261,7 +270,7 @@ export class Session {
await spawnPrivileged( await spawnPrivileged(
this.uid!, this.uid!,
this.uuid, this.uuid,
["kill", "-9", `${this.term.pty.pid}`], ["bash", "-c", `kill -9 ${this.term.pty.pid} 2>/dev/null || true`],
this.log this.log
); );
} }
@ -269,7 +278,7 @@ export class Session {
await spawnPrivileged( await spawnPrivileged(
this.uid!, this.uid!,
this.uuid, this.uuid,
["kill", "-9", `${this.lsp.proc.pid}`], ["bash", "-c", `kill -9 ${this.lsp.proc.pid} 2>/dev/null || true`],
this.log this.log
); );
} }

View File

@ -9,6 +9,7 @@ export interface LangConfig {
alwaysCreate?: boolean; alwaysCreate?: boolean;
compile?: string; compile?: string;
run: string; run: string;
lspSetup?: string;
lsp?: string; lsp?: string;
lspInit?: any; lspInit?: any;
lspConfig?: any; lspConfig?: any;
@ -147,6 +148,7 @@ implement main0 () = ()
main: "main.c", main: "main.c",
compile: "clang -Wall -Wextra main.c -o main", compile: "clang -Wall -Wextra main.c -o main",
run: "./main", run: "./main",
lspSetup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`,
lsp: "clangd", lsp: "clangd",
template: `#include <stdio.h> template: `#include <stdio.h>
@ -202,6 +204,8 @@ int main() {
main: "main.cpp", main: "main.cpp",
compile: "clang++ -Wall -Wextra main.cpp -o main", compile: "clang++ -Wall -Wextra main.cpp -o main",
run: "./main", run: "./main",
lspSetup: `echo '-Wall -Wextra' | sed -E 's/\\s+/\\n/g' > compile_flags.txt`,
lsp: "clangd",
template: `#include <iostream> template: `#include <iostream>
int main() { int main() {
@ -640,6 +644,8 @@ require("repl").start()
compile: compile:
"gcc $(gnustep-config --objc-flags) main.m $(gnustep-config --base-libs) -o main", "gcc $(gnustep-config --objc-flags) main.m $(gnustep-config --base-libs) -o main",
run: "./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 <Foundation/Foundation.h> template: `#import <Foundation/Foundation.h>
int main() { int main() {
@ -813,6 +819,7 @@ binding_irb.run(IRB.conf)
main: "main.rs", main: "main.rs",
compile: "rustc main.rs", compile: "rustc main.rs",
run: "./main", run: "./main",
lsp: "rls",
template: `fn main() { template: `fn main() {
println!("Hello, world!"); println!("Hello, world!");
} }

View File

@ -5,6 +5,7 @@ import * as appRoot from "app-root-path";
interface Options extends SpawnOptions { interface Options extends SpawnOptions {
input?: string; input?: string;
check?: boolean;
} }
export const rijuSystemPrivileged = appRoot.resolve( export const rijuSystemPrivileged = appRoot.resolve(
@ -32,7 +33,9 @@ export async function call(
) { ) {
options = options || {}; options = options || {};
const input = options.input; const input = options.input;
const check = options.check === undefined ? true : options.check;
delete options.input; delete options.input;
delete options.check;
const proc = spawn(args[0], args.slice(1), options); const proc = spawn(args[0], args.slice(1), options);
if (input) { if (input) {
proc.stdin!.end(input); proc.stdin!.end(input);
@ -51,7 +54,7 @@ export async function call(
if (output) { if (output) {
log(`Output from ${args[0]}:\n` + output); log(`Output from ${args[0]}:\n` + output);
} }
if (code === 0) { if (code === 0 || !check) {
resolve(); resolve();
} else { } else {
reject(`command ${args[0]} failed with error code ${code}`); reject(`command ${args[0]} failed with error code ${code}`);

View File

@ -3,6 +3,7 @@ import {
createConnection, createConnection,
MonacoLanguageClient, MonacoLanguageClient,
MonacoServices, MonacoServices,
Services,
} from "monaco-languageclient"; } from "monaco-languageclient";
import { Disposable } from "vscode"; import { Disposable } from "vscode";
import { createMessageConnection } from "vscode-jsonrpc"; import { createMessageConnection } from "vscode-jsonrpc";
@ -117,6 +118,7 @@ async function main() {
function tryConnect() { function tryConnect() {
let clientDisposable: Disposable | null = null; let clientDisposable: Disposable | null = null;
let servicesDisposable: Disposable | null = null;
console.log("Connecting to server..."); console.log("Connecting to server...");
socket = new WebSocket( socket = new WebSocket(
(document.location.protocol === "http:" ? "ws://" : "wss://") + (document.location.protocol === "http:" ? "ws://" : "wss://") +
@ -156,6 +158,10 @@ async function main() {
console.error("Unexpected message from server:", message); console.error("Unexpected message from server:", message);
return; return;
} }
const services = MonacoServices.create(editor, {
rootUri: `file://${message.root}`,
});
servicesDisposable = Services.install(services);
editor.setModel( editor.setModel(
monaco.editor.createModel( monaco.editor.createModel(
editor.getModel()!.getValue(), editor.getModel()!.getValue(),
@ -205,6 +211,11 @@ async function main() {
} }
if (clientDisposable) { if (clientDisposable) {
clientDisposable.dispose(); clientDisposable.dispose();
clientDisposable = null;
}
if (servicesDisposable) {
servicesDisposable.dispose();
servicesDisposable = null;
} }
scheduleConnect(); scheduleConnect();
}); });
@ -233,8 +244,6 @@ async function main() {
document.getElementById("runButton")!.addEventListener("click", () => { document.getElementById("runButton")!.addEventListener("click", () => {
sendMessage({ event: "runCode", code: editor.getValue() }); sendMessage({ event: "runCode", code: editor.getValue() });
}); });
MonacoServices.install(editor);
} }
main().catch(console.error); main().catch(console.error);

View File

@ -58,9 +58,6 @@ qemu-user-static
# Ruby # Ruby
ruby ruby
# Rust
rustc
" "
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive

View File

@ -4,10 +4,24 @@ set -e
set -o pipefail set -o pipefail
set -x set -x
# Needed for project infrastructure
npm config set unsafe-perm true npm config set unsafe-perm true
PERL_MM_USE_DEFAULT=1 cpan App::cpanminus PERL_MM_USE_DEFAULT=1 cpan App::cpanminus
rm -rf /tmp/cpan_install_*.txt 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 # Befunge
npm install -g befunge93 prompt-sync npm install -g befunge93 prompt-sync
@ -26,6 +40,9 @@ cpanm -n Devel::REPL
# ReasonML # ReasonML
npm install -g bs-platform npm install -g bs-platform
# Rust
rustup component add rls rust-analysis rust-src
# Shakespeare # Shakespeare
pip3 install shakespearelang pip3 install shakespearelang