Skip to content

Commit

Permalink
WIP: Run main function code lens
Browse files Browse the repository at this point in the history
  • Loading branch information
jiribenes committed Oct 20, 2024
1 parent 2d481a0 commit 1e2d142
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/effektManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export class EffektManager {
* Gets the command arguments for starting the Effekt server.
* @returns An array of command arguments.
*/
public getEffektArgs(): string[] {
public getEffektArgs(server: boolean = true): string[] {
const args: string[] = [];
const effektBackend = this.config.get<string>("backend");
const effektLib = this.config.get<string>("lib");
Expand All @@ -519,7 +519,9 @@ export class EffektManager {
const folders = vscode.workspace.workspaceFolders || [];
folders.forEach(folder => args.push("--includes", folder.uri.fsPath));

args.push("--server");
if (server) {
args.push("--server");
}
return args;
}
}
92 changes: 91 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { EffektManager } from './effektManager';
import { Monto } from './monto';

import * as net from 'net';
import * as path from 'path';

let client: LanguageClient;
let effektManager: EffektManager;
const runnerTerminals: Map<string, vscode.Terminal> = new Map();

function registerCommands(context: vscode.ExtensionContext) {
context.subscriptions.push(
Expand All @@ -18,10 +20,78 @@ function registerCommands(context: vscode.ExtensionContext) {
vscode.commands.registerCommand('effekt.restartServer', async () => {
await client?.stop();
client?.start();
})
}),
vscode.commands.registerCommand('effekt.runFile', runEffektFile),
vscode.commands.registerCommand('effekt.stopRunning', stopRunningEffekt),
vscode.commands.registerCommand('effekt.clearTerminal', clearEffektTerminal)
);
}

async function runEffektFile(uri: vscode.Uri) {
const effektExecutable = await effektManager.locateEffektExecutable();
const args = [ uri.fsPath, ...effektManager.getEffektArgs(/* server = */ false) ];

const terminalName = `Effekt: ${path.basename(uri.fsPath)}`;
let terminal = runnerTerminals.get(uri.fsPath)

if (!terminal || terminal.exitStatus !== undefined) {
terminal = vscode.window.createTerminal(terminalName);
runnerTerminals.set(uri.fsPath, terminal)
}

terminal.show();
terminal.sendText("clear");
terminal.sendText(`"${effektExecutable.path}" ${args.join(' ')}`);
}

async function stopRunningEffekt(uri: vscode.Uri) {
const terminal = runnerTerminals.get(uri.fsPath);
if (terminal) {
terminal.sendText('\x03'); // Send Ctrl+C to stop the running process
}
}

async function clearEffektTerminal(uri: vscode.Uri) {
const terminal = runnerTerminals.get(uri.fsPath);
if (terminal) {
terminal.sendText('clear');
}
}

class EffektRunCodeLensProvider implements vscode.CodeLensProvider {
public provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] {
const codeLenses: vscode.CodeLens[] = [];
const text = document.getText();
const mainFunctionRegex = /^def\s+main\s*\(\s*\)/gm;
let match: RegExpExecArray | null;

while ((match = mainFunctionRegex.exec(text)) !== null) {
const line = document.lineAt(document.positionAt(match.index).line);
const range = new vscode.Range(line.range.start, line.range.end);

codeLenses.push(new vscode.CodeLens(range, {
title: '$(play) Run',
command: 'effekt.runFile',
arguments: [document.uri]
}));

codeLenses.push(new vscode.CodeLens(range, {
title: '$(debug-stop) Stop',
command: 'effekt.stopRunning',
arguments: [document.uri]
}));

codeLenses.push(new vscode.CodeLens(range, {
title: '$(clear-all) Clear',
command: 'effekt.clearTerminal',
arguments: [document.uri]
}));
}

return codeLenses;
}
}

export async function activate(context: vscode.ExtensionContext) {
effektManager = new EffektManager();

Expand All @@ -32,6 +102,26 @@ export async function activate(context: vscode.ExtensionContext) {

registerCommands(context);

// Register the CodeLens provider
context.subscriptions.push(
vscode.languages.registerCodeLensProvider(
{ language: 'effekt', scheme: 'file' },
new EffektRunCodeLensProvider()
)
);

// Clean up terminals when closed
context.subscriptions.push(
vscode.window.onDidCloseTerminal(terminal => {
for (const [uri, t] of runnerTerminals.entries()) {
if (t === terminal) {
runnerTerminals.delete(uri);
break;
}
}
})
);

const config = vscode.workspace.getConfiguration("effekt");

let serverOptions: ServerOptions;
Expand Down

0 comments on commit 1e2d142

Please sign in to comment.