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.
/**
* 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:
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);
}