Skip to Content

A Modular Hotkey System

For my StrangeLoop workshop I had to do a lot of powerpoint work. To streamline this, I made over 20 AutoHotKey shortcuts to run various ribbon commands. To avoid polluting my keyboard I built them all into a general-purpose system. All shortcuts started by clicking the thumb mouse button and then quickly pressing 1-2 keys in sequence.

#IfWinActive ahk_exe POWERPNT.EXE
pp_func()
{
    pp_cmd := Map("a2", {cmd: "{alt}adu.2", info: "Set animation time to .2 seconds"}

    , "fh", {cmd: "{alt}hgoh", info: "Flip horizontal"} ; etc etc
    )


pp_input := "?"
pp_info := ""
for pkey, pval in pp_cmd {
    pp_input .=  "," . pkey
    pp_info .= Format("{1:-20}{2:-1}`n",pkey,pval.info)
}

ih := InputHook("L2 C T1",, pp_input)
ih.Start()
if (ih.Wait() == "Match") {
    if (ih.Match == "?") {
        MsgBox(pp_info)
    }
    else {
            Send(pp_cmd[ih.Match].cmd)
        }
    }
}

; Mouse thumb button, you can change this to something else
XButton1::pp_func()
#IfWinActive

Pressing ? will show all of the commands along with descriptions.

How it Works

The trick here is the InputHook, which accepts a sequence of presses and stores it into a variable. We dynamically construct the matching Input list beforehand— pressing any matching sequence causes ih.Wait() to return “Match”, which is how we know we’ve got something useful. Then we extract the keypresses associated with the command and send them to PowerPoint, which triggers the appropriate ribbon command. That works because {alt}x is equivalent to alt+x. Keypresses after that are not modified.

The L2 T1 param to Input says to accept at most two keystrokes and to timeout after 1 second.

Notes

  • I wrote {alt}abc for clarity; you can also write it !abc. See here for more information on the special characters.
  • AutoHotKey dictionaries are case-insensitive, so adding the key aB will clobber the earlier key Ab. I have a very convoluted workaround for my file launchers, you should probably just Not Do That. AUTOHOTKEY V2 FIXES THIS
  • We need to pull out the command from the array before we can Send it because you can’t do interpolated array lookups in a command. THIS TOO
  • The closing brace needs to be on the same line as a command. AHK handles newlines weird. I LOVE V2