Author Topic: Execute Save Macro submenu  (Read 206 times)

Dennis

  • Senior Community Member
  • Posts: 3999
  • Hero Points: 522
Execute Save Macro submenu
« on: October 03, 2025, 08:06:52 PM »
The following code inserts a sub-menu after the "List Macros..." menu item of the MDI Macro menu, with the names of each saved user macro, select from the menu and the macro is executed.

This is easier / faster than going to list-macros and selecting a macro.
Code: [Select]
/**
 * init-menu callback for the Macros -> Execute Macro submenu
 */
void _init_menu_macros(int menuHandle, int noChildWindows)
{
   // find the tools menu
   if (_menu_find_loaded_menu_caption(menuHandle, "Macro", auto macroMenuHandle) < 0) {
      return;
   }

   // find macros submenu placeholder, add it if we don't have it
   execMacroMenuIndex := _menu_find_loaded_menu_caption(macroMenuHandle,
                                                        "Execute Saved Macro",
                                                        auto execMacroMenuHandle);
   if (execMacroMenuIndex < 0) {
      //say(__FUNCTION__ :+ ": Added sub menu");
      listMacrosMenuIndex := _menu_find_loaded_menu_caption(macroMenuHandle,
                                                            "List Macros...");
      _menu_insert(macroMenuHandle,
                   listMacrosMenuIndex+1,
                   MF_ENABLED|MF_SUBMENU,
                   "Execute S&aved Macro",
                   /*command*/ "",
                   /*categories*/ "",
                   /*help-command*/ "",
                   "Execute a previously saved user macro");
      execMacroMenuIndex = _menu_find_loaded_menu_caption(macroMenuHandle,
                                                          "Execute Saved Macro",
                                                          execMacroMenuHandle);
   }

   // find user recorded macros
   _str user_macros[];
   index := name_match("", /*find_first*/1, COMMAND_TYPE);
   while (index) {
      // add user macros to the list
      if (index_callable(index)) {
         typeless flags = "";
         parse name_info(index) with ',' flags;
         if (isinteger(flags) && (flags & VSARG2_MACRO)) {
            user_macros :+= name_name(index);
         }
      }
      // next please
      index = name_match("", /*find_first*/0, COMMAND_TYPE);
   }
   if (user_macros._length() == 0) {
      return;
   }

   // add each one to the submenu
   submenuIndex := 0;
   foreach (auto macro_name in user_macros) {
      // already there?  if not, add it to the menu
      macroNameMenuIndex := _menu_find_loaded_menu_caption(execMacroMenuHandle, macro_name);
      if (macroNameMenuIndex < 0) {
         //say(__FUNCTION__ :+ ": Adding macro: " :+ macro_name);
         _menu_insert(execMacroMenuHandle,
                      submenuIndex,
                      MF_ENABLED,
                      macro_name,
                      macro_name,
                      /*categories*/ "",
                      /*help_commend*/ "",
                      /*help_message*/ "Execute ":+macro_name);
      }
      submenuIndex++;
      continue;
   }
}

To get this to work properly with user macros that had keyboard shortcuts, I needed to fix this function:
Code: [Select]
int _menu_find_loaded_menu_caption(int menu_handle,_str caption,int &submenu_handle=0)
{
   int i, Nofitems=_menu_info(menu_handle,'c');
   for (i=0;i<Nofitems;++i) {
      _str item_text;
      mf_flags := 0;
      _menu_get_state(menu_handle,i,mf_flags,'p',item_text,submenu_handle);
      item_text=stranslate(item_text,'','&');
      parse item_text with item_text "\t" .;  // <--- HERE
      if (strieq(item_text,caption)) {
         return(i);
      }
   }
   return(-1);
}
« Last Edit: October 03, 2025, 08:21:52 PM by Dennis »

Clark

  • SlickEdit Team Member
  • Senior Community Member
  • *
  • Posts: 7088
  • Hero Points: 537
Re: Execute Save Macro submenu
« Reply #1 on: October 05, 2025, 01:28:31 AM »
This looks like good addition. Thanks!