#76 Plugin Macro Handling

Next_major_release
closed
nobody
None
5
2014-08-17
2008-07-11
Nathan Jeffords
No

Currently when a plugin makes changes only the final edit/navigation operations are recorded. This causes features that change the cursor position based of the current position to fail since NotePad++ only records the position the cursor went to. So when playing back the macro, the plugins logic is not executed, it just jumps to the cursor position that was record into the macro.

This patch allows plugins to block the recording of edit/navigation operations while the plugin command is executing, then add a "pluging macro operation" to the recorded macro that will call back into the plugin with arbitraty data to allow the plugin to "do the right thing"

The problem is part of the "plugin macro operation" is a pointer to a function to call with the operation data. While this works, these pointers cannot be reliabaly saved and would break the persistant macro feature.

I would have posted the patch to the forum to solicit feedback on the best way to aproach this issue but I see no way to attach files to forum posts, so I am posting it here so that I may cross reference it from a forum post.

Discussion

  • the patch

     
    Attachments
  • Logged In: YES
    user_id=2144632
    Originator: YES

    I posted a version of the patch that was created against the latest SVN revision
    File Added: plugin macro support.patch

     
  • Greg Bullock
    Greg Bullock
    2008-09-05

    Logged In: YES
    user_id=1131257
    Originator: NO

    I like your ideas.

    To preserve the the persistence property of macros, perhaps the structs PLUGIN_MACRO_OPERATION and recordedMacroStep should be modified:

    typedef struct PLUGIN_MACRO_OPERATION {
    // typedef PLUGIN_MACRO_OPERATION_PROC PROC; -- remove this
    // PROC Proc; -- remove this
    char *PluginGUID; // -- add this
    char *PluginFunctionGUID; // -- add this
    DWORD Size;
    LPBYTE Data;
    } PLUGIN_MACRO_OPERATION, * PLUGIN_MACRO_OPERATION_PTR;

    struct recordedMacroStep {
    enum MacroTypeIndex {mtUseLParameter, mtUseSParameter, mtMenuCommand, mtPluginOperation};

    typedef PLUGIN\_MACRO\_OPERATION\_PROC plugin\_op\_proc;
    std::string PluginGUID; // -- add this
    std::string PluginFunctionGUID; // -- add this
    typedef std::vector <BYTE>            plugin\_op\_data;
    
    // plugin\_op\_proc PluginOpProc;  -- remove this
    plugin\_op\_proc getPluginOpProc\(\); // -- add this
    plugin\_op\_data PluginOpData;
    

    // (everything else the same) ...
    }

    where

    PluginGUID and 
    PluginFunctionGUID
    

    are GUIDs supplied by the plugin to uniquely identify the plugin (PluginGUID) and the operation therein (PluginFunctionGUID) that is to be called by the macro, and

    recordedMacroStep::plugin_op_proc recordedMacroStep::getPluginOpProc();

    is a function that decodes the unique identifiers PluginGUID and PluginFunctionGUID to determine the operation pointer.

    Then in recordedMacroStep::PlayBack(...), instead of calling

    PluginOpProc \(PluginOpData.size \(\), &PluginOpData.front \(\)\);
    

    it would call

    \(getPluginOpProc\(\)\)\(PluginOpData.size \(\), &PluginOpData.front \(\)\);
    

    Regards.
    Greg

     
  • Don HO
    Don HO
    2014-08-17

    • status: open --> closed
    • Group: --> Next_major_release
     
  • Don HO
    Don HO
    2014-08-17

    Outdated.