Skip to content

Commit d3e4fc3

Browse files
Refactor and Rearrange Extension activation to handle cases of no effekt exe, old effekt exe and current effekt exe without blocking lsp
1 parent 5f9ae2d commit d3e4fc3

2 files changed

Lines changed: 56 additions & 36 deletions

File tree

src/effektManager.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ interface EffektExecutableInfo {
1919
version: string;
2020
}
2121

22+
export class EffektExecutableNotFoundError extends Error {
23+
constructor(message: string = "Effekt executable not found") {
24+
super(message);
25+
this.name = "EffektExecutableNotFoundError";
26+
}
27+
}
28+
2229
/**
2330
* Manages Effekt installation, updates, and status within VS Code.
2431
*/
@@ -171,7 +178,7 @@ export class EffektManager {
171178
}
172179
}
173180

174-
throw new Error('Effekt executable not found');
181+
throw new EffektExecutableNotFoundError('Effekt executable not found');
175182
}
176183

177184
/**
@@ -180,7 +187,7 @@ export class EffektManager {
180187
* @param action The action being performed ('install' or 'update').
181188
* @returns A promise that resolves with the installed/updated version or an empty string.
182189
*/
183-
private async installOrUpdateEffekt(version: string, action: 'install' | 'update', client : EffektLanguageClient): Promise<string> {
190+
private async installOrUpdateEffekt(version: string, action: 'install' | 'update', client? : EffektLanguageClient): Promise<string> {
184191
if (!(await this.checkJava())) {
185192
this.logMessage('INFO', 'Java is not installed.');
186193
return '';
@@ -196,10 +203,9 @@ export class EffektManager {
196203
cancellable: false
197204
}, async (progress) => {
198205
try {
199-
console.log("Right before the try stop")
200-
await client.stop(10000)
201-
console.log("right after the try - stop")
202-
206+
if (client) {
207+
await client.stop();
208+
}
203209
progress.report({ increment: 0, message: 'Preparing...' });
204210
await this.runNpmInstall();
205211
progress.report({ increment: 50, message: 'Verifying installation...' });
@@ -208,19 +214,18 @@ export class EffektManager {
208214
progress.report({ increment: 100, message: 'Completed' });
209215

210216
this.handleInstallationResult(verificationResult, action);
211-
console.log("right before the try start")
212-
await client.start();
213-
console.log("right after the try start")
214-
217+
218+
if (client) {
219+
await client.start();
220+
}
215221
return verificationResult.success ? verificationResult.version || '' : '';
216222
} catch (error) {
217223
this.showErrorWithLogs(`Failed to ${action} Effekt: ${error}`);
218224
this.updateStatusBar();
219-
console.log("right before the catch start")
220-
221-
await client.start();
222-
console.log("right after the catch start")
223225

226+
if (client) {
227+
await client.start();
228+
}
224229
return '';
225230
}
226231
});
@@ -329,14 +334,14 @@ export class EffektManager {
329334
* Checks for Effekt updates and offers to install/update if necessary.
330335
* @returns A promise that resolves with the current Effekt version.
331336
*/
332-
public async checkForUpdatesAndInstall(client: EffektLanguageClient): Promise<string> {
337+
public async checkForUpdatesAndInstall(client?: EffektLanguageClient): Promise<string> {
333338
try {
334339
let currentVersion = await this.getEffektVersion();
335340
const latestVersion = await this.getLatestNPMVersion(this.effektNPMPackage);
336341

337342
// check if the latest version strictly newer than the current version
338343
if (!currentVersion || compareVersion(latestVersion, currentVersion, '>')) {
339-
return this.promptForAction(latestVersion, 'update',client);
344+
return this.promptForAction(latestVersion, 'update', client );
340345
} else {
341346
vscode.window.showInformationMessage(`Effekt is up-to-date (version ${currentVersion}).`);
342347
}
@@ -360,7 +365,7 @@ export class EffektManager {
360365
* @param action The action to perform ('install' or 'update').
361366
* @returns A promise that resolves with the installed/updated version or an empty string.
362367
*/
363-
private async promptForAction(version: string, action: 'install' | 'update', client : EffektLanguageClient): Promise<string> {
368+
private async promptForAction(version: string, action: 'install' | 'update', client? : EffektLanguageClient): Promise<string> {
364369
const message = action === 'update'
365370
? `A new version of Effekt is available (${version}). Would you like to update?`
366371
: `Effekt ${version} is available. Would you like to install it?`;

src/extension.ts

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
StreamInfo,
88
State as ClientState
99
} from 'vscode-languageclient/node';
10-
import { EffektManager } from './effektManager';
10+
import { EffektManager, EffektExecutableNotFoundError } from './effektManager';
1111
import { EffektIRContentProvider } from './irProvider';
1212
import { InlayHintProvider } from './inlayHintsProvider';
1313
import { EffektLanguageClient } from './effektLanguageClient';
@@ -107,24 +107,47 @@ class EffektRunCodeLensProvider implements vscode.CodeLensProvider {
107107
export async function activate(context: vscode.ExtensionContext) {
108108
effektManager = new EffektManager();
109109

110-
await startEffektLanguageServer(context);
110+
try {
111+
// If effekt exists (no matter which version) start lsp
112+
await ensureEffektIsAvailable();
113+
await initializeLSPAndProviders(context);
114+
115+
await handleEffektUpdates();
116+
} catch (error) {
117+
if (error instanceof EffektExecutableNotFoundError) {
118+
// Handle the case where Effekt is not installed
119+
await handleEffektUpdates();
120+
await initializeLSPAndProviders(context);
121+
} else {
122+
// Handle unexpected errors
123+
console.error("An unexpected error occurred:", error);
124+
vscode.window.showErrorMessage('An unexpected error occurred. Check the logs for details.');
125+
}
126+
}
127+
}
111128

129+
async function ensureEffektIsAvailable() {
130+
await effektManager.locateEffektExecutable();
131+
}
132+
133+
async function initializeLSPAndProviders(context: vscode.ExtensionContext) {
134+
await startEffektLanguageServer(context);
112135
registerCommands(context);
113136
registerCodeLensProviders(context);
114137
registerIRProvider(context);
115138
registerInlayProvider();
116-
117139
initializeHoleDecorations(context);
140+
}
118141

142+
async function handleEffektUpdates() {
119143
const installedEffektVersion = await effektManager.checkForUpdatesAndInstall(client);
120144
if (!installedEffektVersion) {
121-
vscode.window.showWarningMessage('Effekt is not installed. LSP features may not work correctly.');
122-
}/* else if (installedEffektVersion !== await effektManager.getEffektVersion()) {
123-
await restartEffektLanguageServer(context);
124-
} */else {
125-
logMessage('INFO', "Using the existing version of Effekt");
145+
vscode.window.showWarningMessage(
146+
'Effekt is not installed. LSP features may not work correctly.'
147+
);
148+
} else {
149+
logMessage('INFO', "Using the existing version of Effekt");
126150
}
127-
128151
}
129152

130153
async function startEffektLanguageServer(context: vscode.ExtensionContext) {
@@ -142,7 +165,9 @@ async function startEffektLanguageServer(context: vscode.ExtensionContext) {
142165
return Promise.resolve(result);
143166
};
144167
} else {
168+
145169
const effektExecutable = await effektManager.locateEffektExecutable();
170+
146171
const args = ["--server", ...effektManager.getEffektArgs()];
147172

148173
/* > Node.js will now error with EINVAL if a .bat or .cmd file is passed to child_process.spawn and child_process.spawnSync without the shell option set.
@@ -189,16 +214,6 @@ async function startEffektLanguageServer(context: vscode.ExtensionContext) {
189214
context.subscriptions.push(client);
190215
}
191216

192-
/*
193-
async function restartEffektLanguageServer(context: vscode.ExtensionContext) {
194-
if (client) {
195-
console.log("restart stop")
196-
await client.stop();
197-
198-
}
199-
await startEffektLanguageServer(context);
200-
}*/
201-
202217
function registerCodeLensProviders(context: vscode.ExtensionContext) {
203218
context.subscriptions.push(
204219
vscode.languages.registerCodeLensProvider(

0 commit comments

Comments
 (0)