Getting a handle on keyboard shortcuts... starting with Keyboard Maestro

Like I suspect many (most?) folks here, I have created a variety of keyboard shortcuts between system keyboard shortcuts (like ⌘P to create a PDF from the print dialog as David has described), Alfred, and Keyboard Maestro. I’m now delving into Better Touch Tool, so here come even more.

I have found that I tend to forget the vast majority of what I have set up, retaining in memory only a few that I use fairly frequently. Since I trigger most of my Alfred workflows via keywords and not hot keys, there are a lot that I just don’t use that often.

I’m trying to get a handle on what I have and clear out the cruft.

Most of my hot keys are based on using ⇧⌃I⌥⌘ which I have tied to my caps lock key (eg the “meta” key as first described by Brett Terpstra - at least in my reading), initially using Karabiner but now with BTT as I start to experiment with it. At least this makes it relatively easy for me to remember the gist of trigging my own hot keys and separating them from other system and application designated key sequences.

What I have been doing in KM is moving a large number of my hot key triggers to ⇧⌃I⌥⌘A (meta-A). This is a very easy sequence to hit with my left hand on the keyboard, and then I get the conflict palette which allows me to winnow down to the macro I want, also as described by David (a very very helpful tip, btw). Some of my macro groups are only active in certain apps, so when I hit this hot key the conflict palette will vary depending on the focussed app. This has been working very well for me. There are some KM macros that fire from hot key sequences not using the meta key at all, for a variety of reasons, but these are infrequent now.

In order to get a handle on my assigned hot keys (especially as I start to play with BTT and want to create some hot keys for windows management after watching David’s video on this), I want to have a way to quickly itemize the hot keys already in use.

I have started with KM, and have the python code below which outputs a Markdown-formatted table listing all KM macros that have a hot key trigger assigned. The first column has the macro group name, followed in parenthesis by a hot key that triggers a macro palette if assigned. The second column is the macro name. The third column is the hotkey assigned to that macro (this column is never blank as the output only includes macros with a hotkey trigger). It looks like this, for a macro group I created that does window manipulation:

In this case, the macro group will display in a palette with one hotkey, but each macro can also be activated with its own hotkey.

Note that a macro or group name that ends with a * means that macro or macro group is disabled. This of course relies on my not creating any macros or macro groups with names that themselves end with a *.

Also, it is worth noting that you can have a macro group that activates with a hot key to display a palette, with the macros in that group not active unless the palette is displayed OR active when the palette is not displayed. I have not yet figured out how to pull that out of the data I have from KM, so there are a few kinks in the system, but it does get me pretty much where I want to be with figuring this stuff out.

BTW: this macro group is about to be disabled and the individual hot keys removed from its macros, in favor of moving window control to BTT to experiment with it. (Downside - all of my KM macros sync between desktop and laptop, but sync is experimental in BTT…) I will be paring down the number of individual window placements as well. I have a huge variety of them in KM (there are 35 macros in the group) but I use, from the keyboard, only a few. I can still access them all in the palette if I find I need to reenable the group, which is fine. I have them all on a special layout on my StreamDeck and I pretty much using them only on my desktop with the StreamDeck anyway, so it should work out…

I have not yet tackled getting the system defined hot keys (probably going to need to find some pre-built utility that pulls out this data or figure out how to code that myself) or from Alfred (probably going to need to parse Alfreds config file, but maybe this is accessible from AppleScript?). If you know how, please let me know.

Ok, enough musings for one posting. I anyone has ideas / thoughts / interest, would like to learn from you.

Here is the code I use to parse KM’s data in case anyone has interest. It’s highly specialized for this one task.

#!/usr/bin/env python3
import sys
sys.path.insert(1, '/Users/<me>/Python')
import pythonapplescript as PAS
import plistlib

# Get all Keyboard Maestro macros
res = PAS.run_applescript(
	'tell application "Keyboard Maestro Engine" to getmacros with asstring'
if res[1] != '':
	sys.stdout.write("Could not get KM macros")
p = plistlib.loads(res[0].encode())

items = []

|Group|Macro|Keyboard Trigger|

for group in p:
	group_enabled = '' if group['enabled'] else '*'
	group_name = group['name']
	group_triggers = []
	results = []
	for macro in group['macros']:
		macro_enabled = '' if macro['enabled'] else '*'
		macro_name = macro['name']
		triggers = []
			for t in macro['triggers']:
				if t['type'] == 'Hot Key Trigger':
			if macro_name == group_name + ' [Macro Group]':
				group_triggers = triggers
				triggers = []
			if triggers:
				results.append( {'group_name': group_name, 
								'macro_name': macro_name,
								'macro_enabled': macro_enabled,
								'macro_triggers': ' '.join(triggers)
		except Exception:
	group_triggers = ' (' + ' '.join(group_triggers) + ')' if group_triggers else ''
	for r in results:
		output = f'| {r["group_name"]}{group_enabled}{group_triggers} | '
		output += f'{r["macro_name"]}{r["macro_enabled"]} | {r["macro_triggers"]} |'
		output += '\n'

This is superb, thank you so much for sharing the process and the code.