Skip to content

Commit 999b3ee

Browse files
committed
Merge #170: Add "Install Server" button to VSCode extension
237deb5 fmt + fix boolean logic issue (Volodymyr Herashchenko) d9781c7 apply suggestion for find_server.ts (Volodymyr Herashchenko) a3a210f add option for disabling autoupdates (Volodymyr Herashchenko) 6e994dc fix: ensure server is installed before restarting (Volodymyr Herashchenko) 9203a40 change install to show in notification (Volodymyr Herashchenko) 90deb28 Linting. Ran npm install. (Kyryl R) 1166f73 eslint: change `let` to `const` (Volodymyr Herashchenko) 2980c20 change server installation process to automatic (Volodymyr Herashchenko) b438089 bump vscode extension version to 0.2.2 (Volodymyr Herashchenko) 7c09cd3 add "Install server" option in notification (Volodymyr Herashchenko) f4b91fe change installation instructions for lsp (Volodymyr Herashchenko) Pull request description: fixes #169 This button appears if the user is missing the `simplicityhl-lsp` executable. It spawns the `cargo install simplicityhl-lsp` and shows progress notification for compiling. This also updates the LSP installation method in the README and changes the `Learn more` link to point to this repository instead of the old one. ACKs for top commit: KyrylR: ACK 237deb5 Tree-SHA512: 8fd9330f65dbe9c8b6c0d135ea9e3e9ff7edd30158fbe9ad714914c269ba2e79657a5225e9d5e356252530a6f76b6d2d165297ec59129b256d1bbe4196513479
2 parents 131fd6c + 237deb5 commit 999b3ee

File tree

5 files changed

+105
-25
lines changed

5 files changed

+105
-25
lines changed

lsp/README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,10 @@ Language Server for [SimplicityHL language](https://simplicity-lang.org/).
2222

2323
## Installation
2424

25-
Clone this repository and install using Cargo:
25+
Install Language Server using `cargo`:
2626

2727
```bash
28-
https://github.com/distributed-lab/simplicityhl-lsp
29-
cd simplicityhl-lsp
30-
cargo install --path .
28+
cargo install simplicityhl-lsp
3129
```
3230

3331
## Integration with editors

vscode/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "simplicityhl",
33
"displayName": "SimplicityHL Language Support",
44
"description": "Syntax highlighting and autocompletion for SimplicityHL (Simfony) language",
5-
"version": "0.2.1",
5+
"version": "0.2.2",
66
"publisher": "Blockstream",
77
"repository": {
88
"type": "git",
@@ -67,6 +67,11 @@
6767
"type": "boolean",
6868
"default": false,
6969
"description": "Do not show missing LSP executable warning."
70+
},
71+
"simplicityhl.disableAutoupdate": {
72+
"type": "boolean",
73+
"default": false,
74+
"description": "Do not autoupdate LSP server."
7075
}
7176
}
7277
},

vscode/src/client.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ export class LspClient {
5353
}
5454
}
5555

56-
public stop(): Thenable<void> | undefined {
56+
public async stop(): Promise<void> {
5757
if (!this.client) {
58-
return undefined;
58+
return;
5959
}
60-
return this.client.stop();
60+
await this.client.stop();
61+
this.client = undefined;
6162
}
6263

6364
public async restart(): Promise<void> {
@@ -67,8 +68,8 @@ export class LspClient {
6768
}
6869

6970
try {
70-
await this.client.stop();
71-
await this.client.start();
71+
await this.stop();
72+
await this.start();
7273
window.showInformationMessage("SimplicityHL Language Server restarted successfully!");
7374
} catch (e) {
7475
window.showErrorMessage(`Failed to restart LSP: ${e}`);

vscode/src/find_server.ts

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import * as cp from "child_process";
1+
import * as os from "os";
22
import * as fs from "fs";
33
import * as path from "path";
4-
import * as os from "os";
5-
import { env, Uri, window, workspace } from "vscode";
4+
65
import process from "node:process";
6+
import * as cp from "child_process";
7+
8+
import { env, ProgressLocation, Uri, window, workspace } from "vscode";
79

810
function findExecutable(command: string): string | null {
911
try {
@@ -51,27 +53,81 @@ function findExecutable(command: string): string | null {
5153
return null;
5254
}
5355

56+
async function installServer(command: string) {
57+
const cargoPath = findExecutable("cargo");
58+
if (!cargoPath) {
59+
throw new Error("Unable to find 'cargo'. Please ensure Rust is installed and in your PATH.");
60+
}
61+
62+
const action = findExecutable(command) ? "Updating" : "Installing";
63+
64+
return window.withProgress({
65+
location: ProgressLocation.Notification,
66+
title: `${action} ${command}`,
67+
cancellable: true
68+
}, async (progress, token) => {
69+
return new Promise<void>((resolve, reject) => {
70+
const installProcess = cp.spawn(cargoPath!, ["install", "--color", "never", command]);
71+
72+
token.onCancellationRequested(() => {
73+
installProcess.kill("SIGTERM");
74+
reject(new Error("Installation canceled"));
75+
});
76+
77+
const reportProgress = (data: Buffer) => {
78+
const lines = data.toString()
79+
.split(/\r?\n/)
80+
.map(l => l.trim())
81+
82+
for (const line of lines) {
83+
if (line.startsWith("Compiling") && line !== "Compiling") {
84+
progress.report({ message: line });
85+
}
86+
}
87+
};
88+
89+
installProcess.stderr?.on('data', reportProgress);
90+
91+
installProcess.on('close', (code) => {
92+
if (code === 0) {
93+
resolve();
94+
} else {
95+
reject(new Error(`Installation failed with exit code ${code}`));
96+
}
97+
});
98+
99+
installProcess.on('error', (err) => {
100+
reject(new Error(`Failed to start cargo process: ${err.message}`));
101+
});
102+
});
103+
});
104+
}
105+
54106
export async function ensureExecutable(
55107
command: string,
56108
): Promise<string | null> {
57-
const exePath = findExecutable(command);
109+
const cargoPath = findExecutable("cargo");
58110
const config = workspace.getConfiguration("simplicityhl");
59111

60-
const suppressWarning = config.get<boolean>(
61-
"suppressMissingLspWarning",
62-
false,
63-
);
112+
let serverPath = findExecutable(command);
113+
114+
if (!cargoPath && !serverPath) {
115+
const suppressWarning = config.get<boolean>(
116+
"suppressMissingLspWarning",
117+
false,
118+
);
119+
if (suppressWarning) {
120+
return null;
121+
}
64122

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

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

81137
return null;
82138
}
83-
return exePath;
139+
140+
if (!cargoPath) {
141+
return serverPath;
142+
}
143+
144+
const disableAutoupdate = config.get<boolean>("disableAutoupdate", false);
145+
146+
if (serverPath && disableAutoupdate) {
147+
return serverPath;
148+
}
149+
150+
try {
151+
await installServer(command);
152+
153+
serverPath = findExecutable(command);
154+
} catch (err) {
155+
window.showErrorMessage(err);
156+
return null;
157+
}
158+
159+
return serverPath;
84160
}

0 commit comments

Comments
 (0)