vburenin / ifacemaker

Generate interfaces from structure methods.
Apache License 2.0
320 stars 43 forks source link

Add VSCode extension #68

Open ashtonian opened 7 months ago

ashtonian commented 7 months ago

Would you be interested in adding a vscode extension or should that be somewhere else?

Here is a starter snippet for how it could work, it would get as much context as it could and then ask for the struct and interface name from the user and output the file in the same directory.

import * as vscode from 'vscode';
import { exec } from 'child_process';
import * as path from 'path';
import * as fs from 'fs';

function installIfacemaker() {
    const cmd = 'go install github.com/vburenin/ifacemaker@latest';
    exec(cmd, (error, stdout, stderr) => {
        if (error) {
            vscode.window.showErrorMessage(`Error installing ifacemaker: ${error.message}`);
            return;
        }
        if (stderr) {
            vscode.window.showErrorMessage(`Error: ${stderr}`);
            return;
        }
        vscode.window.showInformationMessage('ifacemaker installed successfully');
    });
}

export function activate(context: vscode.ExtensionContext) {
    let disposable = vscode.commands.registerCommand('extension.useIfacemaker', async () => {
        const editor = vscode.window.activeTextEditor;
        if (!editor) {
            vscode.window.showErrorMessage('No active Go file.');
            return;
        }

        const filePath = editor.document.fileName;
        if (path.extname(filePath) !== '.go') {
            vscode.window.showErrorMessage('Active file is not a Go file.');
            return;
        }

        // Get struct name from user
        const structName = await vscode.window.showInputBox({ prompt: 'Enter Struct Name' });
        if (!structName) {
            vscode.window.showErrorMessage('Struct name is required.');
            return;
        }

        // Get interface name from user
        const interfaceName = await vscode.window.showInputBox({ prompt: 'Enter Interface Name' });
        if (!interfaceName) {
            vscode.window.showErrorMessage('Interface name is required.');
            return;
        }

        // Try to parse the package name from the file
        const content = fs.readFileSync(filePath, 'utf8');
        const packageMatch = content.match(/^package (\w+)/m);
        if (!packageMatch) {
            vscode.window.showErrorMessage('Could not determine the package name from the file.');
            return;
        }
        const packageName = packageMatch[1];

        // Construct and execute the command
        const outputFilePath = `${filePath.replace('.go', '')}_${interfaceName}.go`;
        const cmd = `ifacemaker -f ${filePath} -s ${structName} -i ${interfaceName} -p ${packageName} > ${outputFilePath}`;

        exec(cmd, (error, stdout, stderr) => {
            if (error) {
                vscode.window.showErrorMessage(`Error: ${error.message}`);
                return;
            }
            if (stderr) {
                vscode.window.showErrorMessage(`Error: ${stderr}`);
                return;
            }
            vscode.window.showInformationMessage('Interface generated successfully');
        });
    });

    context.subscriptions.push(disposable);
}