MenuHammer icon indicating copy to clipboard operation
MenuHammer copied to clipboard

calling commands by name

Open dmgerman opened this issue 1 year ago • 0 comments

Hi Darin,

first of all, thank you again for the spoon. I use it every day. For some time I have wanted to call commands by name (e.g. emacs) but hammerspoon does not allow that.

So I wrote the following code that scans the menus and creates a list of commands, that then you can call by name.

This is not a suggestion that you add this to the spoon. I just think you might find it useful.

 menuCommands = {}
 
 function menu_extract_action(action, menuName, indent)
   command = {}
   if not indent then indent = 0 end
   indst = string.rep("  ", indent)
   name =   string.gsub(action["desc"], "^.+↩ ", "")
   command["desc"] = name
   command["category"] = action["category"]
   command["actType"] = action["commands"][1][1]
   command["action"] = action["commands"][1][2]
   command["inMenu"] = menuName
   table.insert(menuCommands, command)
   -- ↩
 --  print(string.format("%s>>>>>Printing and action table [menu %s]", indst, menuName))
 --  print(string.format("%sDesc [%s] Category [%s]", indst, action["desc"],action["category"]))
 end
 
 
 function menu_scan_for_actions(menu, indent)
   if not indent then indent = 0 end
   indst = string.rep("  ", indent)
   for i,v in pairs(menu) do
     st = ""
     if type(v) == "string" then st = v end
 --    if menable then
 --       print(string.format("%s[%s] [%s] [%s]", indst, i,type(v),st))
 --    end
     if (type(v) == "table") and
        v["category"] and
        v["desc"] and
        v["category"] ~= "navigation" and
        v["category"] ~= "exit" and
        v["category"] ~= "back" and
        v["desc"] ~= "" then
        menu_extract_action(v, v["menu"]["name"], indent)
 --       menable = true
     end
     if (type(v) == "table") and
       (i ~=  "menu") and
       (i ~=  "menuManager") then
          menu_scan_for_actions(v, indent+1)
 --         menable = false
     end
   end
 end
 
 
 local function list_commands()
   if #menuCommands == 0 then
     menu_scan_for_actions(menuHammerMenuList)
   end
    local choices = {}
    for i,v in ipairs(menuCommands) do
      table.insert(choices, {text = string.format("%s -- %s", v["desc"], v["inMenu"]), idx=i})
    end
    return choices
 end
 
 
 local lastCommand  = ""
 
 local commandChooser = hs.chooser.new(
    function(choice)
       if not choice then hs.alert.show("Nothing chosen"); return end
       local idx = choice["idx"]
 
       print("calling...")
       print(idx)
 
       local name = choice["text"]
       print(name)
 
       print(menuCommands[idx])
 
       local actType = menuCommands[idx]["actType"]
 
       hs.alert.show("Executing " .. name)
       if actType == "function" then
         local action = menuCommands[idx]["action"]
         action()
       end
       -- reorder table to keep this one at top
       local save = menuCommands[idx]
       table.remove(menuCommands,idx)
       table.insert(menuCommands, 1, save)
       lastCommand = name
 end)
 
 
 
 function doCommand ()
    local commandChoices = list_commands()
    commandChooser:choices(commandChoices)
    commandChooser:placeholderText(lastCommand)
    commandChooser:show()
 end
 
 hs.hotkey.bind(dmg_prefix_keys, "RETURN", function () doCommand(); end)

dmgerman avatar Feb 14 '24 21:02 dmgerman