What this is about
I have started using the Trigger macro by name
action much more lately, now that I have worked out a convenient system that shows only the macros that I want to see in the list presented by the prompt.
By a "system" I mean a "hack that works for me" rather than something that you will necessarily want to use in its current form. Perhaps this will help spark your own ideas, or feedback of more educational value.
I detail the path I took, so there are opportunities to respond with either "oh, I didn't know about that" or "why the heck didn't you just..?", depending on the level of your experience with Keyboard Maestro. Also it illustrates either how I have overlooked something obvious or else how smart groups have what was, to me, one surprising limitation.
This is a long post, sorry… You can, if you like, jump to the conclusion, or read something else.
Related topics might include Trigger Macro by Name issue.
What used to put me off using "macro by name"
To quickly trigger macros that I use very often within certain contexts, I have, for a long time, used conflict palettes. For example, within an macro group that is active for the Finder only, there could be macros for "MF Move to folder Foo", "MB Move to folder Bar" and so on. Select the files, press M then B and they have been moved.
That's a very quick and convenient system, but sometimes I want to have to confirm an action first by hitting Return, or I want to have freer matching of the text I enter. The obvious solution is to use a macro based on trigger macro by name
, but I was put off using it because, by default, it listed too many macros. If you don't care about such things, you have the right priorities in life, and should stop reading now.
Standard ways of limiting which macros are listed
Setting the search range to "Active macros" helps, but that will still include lots of macros that one never wants to trigger in this way—for example, subroutines and macros that are to be triggered by hotkeys.
However, the search range can be limited further by specifying the macros that are to be included, by either specifying each one (no thanks) or by specifying a group, including smart groups. So, we just need to set up a suitable smart group, and point trigger macro by name
at that.
Good… but how should the smart group be set up?
The challenge of setting up a suitable smart group
Remember that my aim was to be able to choose which macros should be presented by trigger by macro name
. Those are idiosyncratic choices. That is to say, rather than trying to codify why I might want one macro in the list and not another, it is far simpler just to somehow mark the macros that are to be included, and have the smart group match on that mark. Therefore the smart group should simply match some text that I have added somewhere in the relevant macros.
So what sort of text would be suitable, and where should it be added?
A long string such as "include in macro list" is likely to be unique, whereas something shorter might be contained in many macros that should not be included in the list, so let's start from there. Set up a smart group to match on the arbitrarily chosen string "include in macro list".
Putting "include in macro list" in the name of the desired macros would of course look unacceptably distracting in the KM Editor, let alone the list of macros that is to appear in! So we would need to put that string elsewhere in the relevant macros.
I wanted to be able to add (and remove) the text string easily and quickly, I wanted them to be easy to see in KM's editor, and I did not want them to be a visual distraction in the presented list of macros.
That ruled out putting the string in, for example in the notes for any action (the nuisance of having to click on the cog wheel, select "notes"… and afterwards not being able to see the note without checking on it) so I tried using a comment
action. The text to be matched would be a string such as "include in macro list" and the comment could be saved as a "favourite" (or "favorite" of course), so that it could be added to any macro fairly quickly.
That could have been the end of the tale, but for me, this solution felt clunky in practice and it added a bit of visual clutter to the macro. I wanted a system that would be very quick and convenient to use and which would be unobtrusive.
So… what if I just added a full stop (period) after the names of macros that I wanted to appear in the list? Macro names don't normally end in a full stop. A simple, unobtrusive "." could be my way of marking the wanted macros.
How then, would I get the smart group to match a macro name containing a full stop? It would be even better to match a full stop that appears only at the end of the name (in case, say, I ever import a macro that uses periods elsewhere in its name) but let's start with the simpler case.
Set the smart group to match "name: ." and... oh dear, there are far too many matches.
What does "has a name" mean?
The Search Strings page in the Wiki tells us that "name: " matches "any macro that has a name matching the specified string". It appears that "has a name matching" does not simply mean "has the match in its name" but rather "contains a matching name". Consequently our smart group contains all the macros that use an action titled "pause for 0.5 seconds", just for a start!
So let's try to match a period that appears at the end of a name.
What does "matches" mean here?
Actions are as unlikely as macros to end in a full stop, so we would not have to worry about excluding them. Since we are looking at matching here, we can perhaps try a regular expression? The regular expression to match a period at the end of a string is \.$
, so let's try that.
name: \.$
No matches.
Hmm. name: "\.$
"
Nope.
How about name: (\.$)
Not today.
So either I am doing something wrong or it turns out that "matching" in this context does not imply that regex "matching" is possible when setting up a smart group.
Looking for a replacement for the full stop, and settling on another full stop
Instead of using a full stop to mark macros for collection in the smart group, perhaps another unobtrusive character could be used instead. How about using an invisible character? They are unobtrusive!
There are certainly many of them, but such a character would be invisible not just in the list prompt, but in the Editor, and that would surely cause confusion at some point. Also, the more mundane space characters might be treated as being the same as the conventional, ubiquitous space character, and the weirder invisible characters might cause unexpected difficulties.
How about using the smallest character you can find? That would be visible in the Editor, just about, and might not be too distracting in the list. Well it turns out that the smallest characters appear in Semitic languages which are written in right-to-left order. Adding right-to-left characters to left-to-right strings is easy enough to do in a Mac app, but trying to edit the resulting string can be a little confusing for the text cursor, for a start (for an example of a Mac app which seems confused about how to handle bi-directional text, Exhibit A is, unsurprisingly, Apple's Music.app).
What about other kinds of full stop, then? Do they exist? They do! And I settled on using a fullwidth full stop, which looks like this: .
, a small version of the familiar full stop but with a space after it.
The conclusion, FFS
My smart group is now set to look for name: .
and my "Run macro by name" macro consists of just a trigger macro by name
action set to "active macros" only in that smart group.
And here are some example of some macros appearing in a prompt by virtue of ending in "."
That's pretty, and unwanted macros do not appear, but was it worth spending time on?
Yes, because I learned some things (not by any means all shown here) along the way.
Was posting this worthwhile?
Probably not, but it's done now. Next question.
How would I enter that Fullwidth Full Stop, in the unlikely event that I might want to?
I use a text expander to type the Fullwidth Full Stop character, and you will understand why the typed trigger is ;ffs
.