Skip to content
Merged
6 changes: 2 additions & 4 deletions lsp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ Language Server for [SimplicityHL language](https://simplicity-lang.org/).

## Installation

Clone this repository and install using Cargo:
Install Language Server using `cargo`:

```bash
https://github.com/distributed-lab/simplicityhl-lsp
cd simplicityhl-lsp
cargo install --path .
cargo install simplicityhl-lsp
```

## Integration with editors
Expand Down
2 changes: 1 addition & 1 deletion vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "simplicityhl",
"displayName": "SimplicityHL Language Support",
"description": "Syntax highlighting and autocompletion for SimplicityHL (Simfony) language",
"version": "0.2.1",
"version": "0.2.2",
"publisher": "Blockstream",
"repository": {
"type": "git",
Expand Down
69 changes: 62 additions & 7 deletions vscode/src/find_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as cp from "child_process";
import * as fs from "fs";
import * as path from "path";
import * as os from "os";
import { env, Uri, window, workspace } from "vscode";
import { env, ProgressLocation, Uri, window, workspace } from "vscode";
import process from "node:process";
import { spawn } from "node:child_process";

function findExecutable(command: string): string | null {
try {
Expand Down Expand Up @@ -51,27 +52,72 @@ function findExecutable(command: string): string | null {
return null;
}

async function installServer(command: string) {
const cargoPath = findExecutable("cargo");
if (!cargoPath) {
throw new Error("Unable to find 'cargo'. Please ensure Rust is installed and in your PATH.");
}
const action = findExecutable(command) ? "Updating" : "Installing";


return window.withProgress({
location: ProgressLocation.Window,
title: `${action} ${command}`,
cancellable: false
}, async (progress) => {
return new Promise<void>((resolve, reject) => {
const installProcess = spawn(cargoPath!, ["install", "--color", "never", command]);

const reportProgress = (data: Buffer) => {
const lines = data.toString()
.split(/\r?\n/)
.map(l => l.trim())

for (const line of lines) {
if (line.startsWith("Compiling") && line !== "Compiling") {
progress.report({ message: line });
}
}
};

installProcess.stderr?.on('data', reportProgress);

installProcess.on('close', (code) => {
if (code === 0) {
resolve();
} else {
reject(new Error(`Installation failed with exit code ${code}`));
}
});

installProcess.on('error', (err) => {
reject(new Error(`Failed to start cargo process: ${err.message}`));
});
});
});
}


export async function ensureExecutable(
command: string,
): Promise<string | null> {
const exePath = findExecutable(command);
const cargoPath = findExecutable("cargo");
const config = workspace.getConfiguration("simplicityhl");

const suppressWarning = config.get<boolean>(
"suppressMissingLspWarning",
false,
);

if (!exePath && !suppressWarning) {
if (!cargoPath && !suppressWarning) {
const choice = await window.showWarningMessage(
`LSP server "${command}" was not found in PATH or common locations. To use language server feautures, please install server to PATH`,
`To use SimplicityHL language server, please install cargo`,
"Learn more",
"Don't show again",
"Close",
);

if (choice === "Learn more") {
const url = "https://github.com/distributed-lab/simplicityhl-lsp";
const url = "https://rust-lang.org/tools/install";
await env.openExternal(Uri.parse(url));
} else if (choice === "Don't show again") {
const config = workspace.getConfiguration("simplicityhl");
Expand All @@ -80,5 +126,14 @@ export async function ensureExecutable(

return null;
}
return exePath;

if (cargoPath) {
try {
await installServer(command);
return findExecutable(command);
} catch (err) {
window.showErrorMessage(err);
return null;
}
}
}