exceedsystem / vscode-macros

This extension gives the macro features to your vscode.
https://marketplace.visualstudio.com/items?itemName=EXCEEDSYSTEM.vscode-macros
MIT License
38 stars 2 forks source link

Importing code from another file #15

Closed PhiLhoSoft closed 3 months ago

PhiLhoSoft commented 3 months ago

Hello.

I like your project, where you can edit real JavaScript files instead of a bunch of Json lines like in other macro extensions, bleah!

But I have trouble to use functions defined in another file. I give an example: In the macro folder, I have a file editor.functions.js, with the following content:

const vscode = require('vscode');

const expandWords = (editor) => {
    editor.selections = editor.selections.map((selection) => {
        if (selection.isEmpty) {
            const range = editor.document.getWordRangeAtPosition(selection.start);
            return new vscode.Selection(range.start, range.end);
        }
        return selection;
    });
};

const other = () => { return 'Other'; }

module.exports = {
    expandWords,
    other,
};

Simple enough, expandWords transforms all empty selections to word selections. I try to use it as follows, in a different file (VSCMacros - Tests.js):

const vscode = require('vscode');
const plsf = require('./editor.functions');

function surroundWithQuotes() {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
        // Return an error message if necessary. For example when focus when running the macro isn't on an editor.
        return 'Editor is not opening.';
    }
    const document = editor.document;
    plsf.expandWords(editor);

    editor.edit((edit) => {
        editor.selections.forEach((selection) => {
            const text = document.getText(selection);
            if (text.length > 0) {
                edit.replace(selection, `"${text}"`);
            }
        });
    });
}

If expandWords is defined in the same file, it works (calling expandWords() directly, of course), the multiple cursors become multiple selections. When I run the code (with the function in a separated file, as shown) in debug mode, step by step, it works too, plsf is an object with two fields, good. BUT, when I run the macro directly, it fails:

An uncaught exception occurred in the macro 'SurroundWithQuotes'(TypeError: plsf.expandWords is not a function).

When I display JSON.stringify(plfs), it shows an empty object.

I am missing something? Or is it a limitation of the extension or of VSC ?

exceedsystem commented 3 months ago

@PhiLhoSoft

I have tried the following macro and it appears to work well. Am I not understanding the intent of your question?

If the problem persists, please attach a set of reproducible macro files.

Best regards,

// ext_module_test.js

const vscode = require('vscode');
const extModule = require('./test.js');

module.exports.macroCommands = {
    ExtModuleTest: {
        no: 1,
        func: extModuleTestFunc,
    },
};

function extModuleTestFunc() {
    extModule.surroundWithQuotes();
}
// test.js

const vscode = require('vscode');
const plsf = require('./editor.functions');

function surroundWithQuotes() {
    const editor = vscode.window.activeTextEditor;
    if (!editor) {
        return 'Editor is not opening.';
    }
    const document = editor.document;
    plsf.expandWords(editor);
    // Added this line
    vscode.window.showInformationMessage(editor.selections.length.toString());
}
// Added exports
module.exports = {
    surroundWithQuotes,
};
// editor.functions.js

const vscode = require('vscode');

const expandWords = (editor) => {
    editor.selections = editor.selections.map((selection) => {
        if (selection.isEmpty) {
            const range = editor.document.getWordRangeAtPosition(selection.start);
            return new vscode.Selection(range.start, range.end);
        }
        return selection;
    });
};

const other = () => { return 'Other'; }

module.exports = {
    expandWords,
    other,
};

https://github.com/exceedsystem/vscode-macros/assets/70489172/fa71b6e8-6ef4-4155-976e-195e6cba06f6

PhiLhoSoft commented 3 months ago

Actually, it works… after I restarted VSC! Sorry for the noise (at least, it leaves an example of syntax for external files, I had to search for that, I am more used to TS syntax…). I close this issue. Thank you for the quick answer and your test. And thank you for this fine extension!

exceedsystem commented 3 months ago

@PhiLhoSoft

Thanks for reporting the results.

The macro file modules are removed from Node's Require cache and re-registered each time the macro is executed.

However, external modules loaded dynamically in the macro file are not managed by this extension, so it may be better to explicitly remove and re-register them in the macro file.

https://github.com/exceedsystem/vscode-macros/blob/59c275fbc94a036b03878d7a6ee784d04fd825fb/src/extension.ts#L271