adjusts on client-server connection (LSP)

This commit is contained in:
bQUARKz 2026-05-06 04:06:09 +01:00
parent 85a224fc7b
commit 0ac7d9e732
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 468 additions and 405 deletions

View File

@ -7,7 +7,7 @@ import lombok.Getter;
@Getter
public class LspServerConfiguration {
public static final String DEFAULT_HOST = "127.0.0.1";
public static final int DEFAULT_PORT = 7777;
public static final int DEFAULT_PORT = 7775;
@Builder.Default
private final LspServerEndpoint endpoint = new LspServerEndpoint(DEFAULT_HOST, DEFAULT_PORT);

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ This extension does **not** start the language server itself. It connects to the
```text
VS Code Extension
-> vscode-languageclient
-> TCP 127.0.0.1:7777
-> TCP 127.0.0.1:7775
-> Prometeu Studio Java/LSP4J
```
@ -21,7 +21,7 @@ VS Code Extension
The Studio LSP server must be listening on:
```text
127.0.0.1:7777
127.0.0.1:7775
```
## Install dependencies
@ -80,7 +80,7 @@ View -> Output -> Prometeu LSP
```text
Prometeu VS Code extension activated.
Connecting to Prometeu Studio LSP at 127.0.0.1:7777...
Connecting to Prometeu Studio LSP at 127.0.0.1:7775...
TCP connection established with Prometeu Studio.
Prometeu Studio LSP client started.
[Info] Hello from Prometeu Studio LSP
@ -136,7 +136,7 @@ Default settings:
```json
{
"prometeu.studio.host": "127.0.0.1",
"prometeu.studio.port": 7777
"prometeu.studio.port": 7775
}
```

View File

@ -48,7 +48,7 @@
},
"prometeu.studio.port": {
"type": "number",
"default": 7777,
"default": 7775,
"description": "Prometeu Studio LSP TCP port."
}
}

View File

@ -2,16 +2,25 @@ import * as net from "node:net";
import * as vscode from "vscode";
import {
CloseAction,
ErrorAction,
LanguageClient,
LanguageClientOptions,
ServerOptions,
State,
StreamInfo
} from "vscode-languageclient/node";
let client: LanguageClient | undefined;
let output: vscode.OutputChannel;
let reconnectTimer: NodeJS.Timeout | undefined;
let reconnectContext: vscode.ExtensionContext | undefined;
let stoppingClient = false;
const RECONNECT_DELAY_MS = 2000;
export function activate(context: vscode.ExtensionContext): void {
reconnectContext = context;
output = vscode.window.createOutputChannel("Prometeu LSP");
output.appendLine("Prometeu VS Code extension activated.");
@ -40,6 +49,8 @@ export async function deactivate(): Promise<void> {
}
async function startClient(context: vscode.ExtensionContext): Promise<void> {
clearReconnectTimer();
if (client) {
output.appendLine("Prometeu LSP client is already running.");
return;
@ -48,7 +59,7 @@ async function startClient(context: vscode.ExtensionContext): Promise<void> {
const config = vscode.workspace.getConfiguration("prometeu.studio");
const host = config.get<string>("host", "127.0.0.1");
const port = config.get<number>("port", 7777);
const port = config.get<number>("port", 7775);
output.show(true);
output.appendLine(`Connecting to Prometeu Studio LSP at ${host}:${port}...`);
@ -114,38 +125,66 @@ async function startClient(context: vscode.ExtensionContext): Promise<void> {
clientKind: "vscode",
prometeuClientVersion: context.extension.packageJSON.version
},
outputChannel: output
outputChannel: output,
errorHandler: {
error: (error) => {
output.appendLine(`Prometeu LSP transport error: ${error.message}`);
return { action: ErrorAction.Continue };
},
closed: () => {
output.appendLine("Prometeu LSP transport closed.");
return { action: CloseAction.DoNotRestart };
}
}
};
client = new LanguageClient(
const nextClient = new LanguageClient(
"prometeuStudioLsp",
"Prometeu Studio LSP",
serverOptions,
clientOptions
);
client = nextClient;
nextClient.onDidChangeState((event) => {
output.appendLine(`Prometeu LSP state changed: ${State[event.oldState]} -> ${State[event.newState]}`);
if (event.newState !== State.Stopped) {
return;
}
if (client === nextClient) {
client = undefined;
}
if (!stoppingClient) {
scheduleReconnect();
}
});
try {
await client.start();
await nextClient.start();
output.appendLine("Prometeu Studio LSP client started.");
vscode.window.showInformationMessage("Connected to Prometeu Studio LSP.");
} catch (error) {
if (client === nextClient) {
client = undefined;
}
const message = error instanceof Error ? error.message : String(error);
output.appendLine(`Failed to start Prometeu LSP client: ${message}`);
vscode.window.showErrorMessage(`Could not connect to Prometeu Studio LSP: ${message}`);
scheduleReconnect();
}
}
async function stopClient(): Promise<void> {
clearReconnectTimer();
if (!client) {
return;
}
const currentClient = client;
client = undefined;
stoppingClient = true;
output.appendLine("Stopping Prometeu Studio LSP client...");
@ -155,5 +194,29 @@ async function stopClient(): Promise<void> {
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
output.appendLine(`Failed to stop Prometeu LSP client cleanly: ${message}`);
} finally {
stoppingClient = false;
}
}
function scheduleReconnect(): void {
if (!reconnectContext) {
return;
}
if (reconnectTimer || client) {
return;
}
output.appendLine(`Scheduling Prometeu LSP reconnect in ${RECONNECT_DELAY_MS}ms...`);
reconnectTimer = setTimeout(() => {
reconnectTimer = undefined;
void startClient(reconnectContext!);
}, RECONNECT_DELAY_MS);
}
function clearReconnectTimer(): void {
if (!reconnectTimer) {
return;
}
clearTimeout(reconnectTimer);
reconnectTimer = undefined;
}