Trying to invoke a KM macro as a macOS service, bur there's a problem before I even can start that

There is a topic on this forum called "How to trigger a macro from the Services menu?" but it's 3 years old and its advice doesn't seem to work anymore (perhaps because macOS/Automator has changed) so I need to repeat this question.

I'm trying to create a macOS service to call a KM macro (perhaps using Applescript to invoke it) so that I can process text inside other macOS applications. Before I even get to KM I have a problem. A simple example is to use Automator to create a "service" with one action called "Run Shell Script" which calls "sort" which takes the selected text as input, sorts it, and then replaces the output with the sorted data.

Despite a variety of tactics and variations I can't get the following one line Automator action to work:

Even though this action has been saved and compiled, it does not actually "replace selected text". In the case of the sort command, it actually displays no output when I click on the Results button near the bottom of the photo. So if I replace "sort" with "ls", run it, and click on Results, I can get this:

You can see in the Results pane above that the ls command produces output, but when I invoke it from the Services pane of the Notes app, or any other app, the results are NOT inserted into the selected text.

So there's two problems I can't resolve. 1) Automator is not passing input to stdin; 2) Automator is not replacing selected text.

I'm afraid I don't know what's going on with Automator, but as a workaround, I was able to get an Automator-created macOS service working that sorts text using sort via KM. Basically, this Automator-created service:

5

runs this macro via AppleScript:

5

And in my limited testing, it worked as expected. I know it's not as direct as running a shell script directly in Automator, but in practice it seems to work identically, so hopefully this can be of some use.

I thank you for trying to help (and for showing me a fascinating new usage for the Execute Shell Script action that I had never seen before!) However if you look you do not have the checkbox “Output replaces selected text” checked so I don’t think your script could possibly work as I expect. What I expect it to do is sort the lines of text and then replace the selected text with the sorted text. That doesn’t happen (for me), either with your example code or if I fix it by checking the box that you missed. Is it clear what I want? I want to be able to select some text in an application like Notes, then click on Notes / Services / sort and the text should be sorted. Is that what happens when you run your code? If so, there must be something wrong with my macOS, and I’d like to know how it could work for you if you don’t have the checkbox checked.

Glad I was able to show you a new way to use the Execute Shell Script action. Yes, this script works for me exactly as you describe: select text in Notes/BBEdit/wherever, run the service, and the selected text is sorted and replaced. I know I don't have that checkbox checked; the trick is that I have KM paste the text, rather than returning it to Automator:

Untitled

Yes I did have paste results selected as you highlighted, it still didn’t work for me. I guess I’m stuck.

If that's the case, then yes, I'm afraid I don't know what might be going wrong. On the off chance it helps, here's the service and macro I made that I've confirmed works for me; if this version works for you too, hopefully that will help you figure out where the issue may be:

Sort via service.zip (80.5 KB)

I installed both your automator and KMM attachments, then I installed your automator action, and I verified all the options were the same, and still it doesn’t work. The automator action still shows an empty “Results” window. So if Automator doesn’t get the text, neither will KM.

I did notice you used the words “with parameter input” which I hadn’t used, and that was the only difference I could see. You have been very good at trying to help, thanks.

You're welcome. Sorry I haven't been able to help solve your problem yet. I have one last idea: are you running this action within Automator, or actually as a service? Because as written, this script won't work within Automator; it's designed to work strictly as a macOS service, and thus can't be tested adequately within Automator itself. I'm guessing you may have dismissed this error at some point in the past, but this is what I get when I try to run it in Automator:

5

If what you've been doing is running the service exclusively within Automator, this seems like it might explain why nothing has been working for you. If you haven't already, save it as a service in your ~/Library/Services folder and try running it while selecting text in an app, not within Automator.

Select Text

5

Run Service

Sorted

5

Yes indeed I had always created a “service” in Automator, and always got the same warning as you. Indeed your sort.workflow which I imported from you is located in the (hidden) ~/Library/Services folder on my computer (my previous attempts aren’t in there) but it still doesn’t work. And I did properly compile and save your workflow before testing it.

I see. Well then, I’m afraid I’m well and truly out of ideas as to what could be happening. Since we’ve come this far though, I might as well ask: is there any particular reason this task has to be done through a service? If the end goal is to process text inside other apps, why not just make a macro that copies the text, processes it, pastes it, and optionally deletes the two most recent clipboards?

Fair question. Largely, I just wanted to learn to create services. Smallly, it seemed like a good solution. I suppose I can do it your way.

P.S. I’ve never used a word with three consecutive letters before that. Reminds me of the first poem I read and enjoyed as a kid: “A one-l lama, he’s a priest. A two-l llama, he’s a beast. But I will bet a silk pajama there isn’t any three-l lllama.”

As a confessed app addict who’s screwed up the MacOS many times by loading and deleting dozens of apps and extensions to try them out, there’s nothing like a clean installation of the OS to get mysterious glitchiness out.

2cents

Yeah, I can certainly sympathize with the urge to try something new, but if the end goal is to be able to process text , and copying it straight into KM works while the service method, for whatever reason, doesn’t, I just don’t see the point in continuing to bang your head against the wall when there’s a perfectly viable solution right in front of you.

That said, I still can’t imagine why in the world something that should be straightforward to set up just refused to work right for you. Hopefully whatever it is that was getting in the way doesn’t cause you any other grief until the issue is resolved.

I am thrilled to hear someone else’s two cents. In this case, I won’t reinstall the OS because it’s a fairly new iMac and I haven’t tinkered with anything to do with services on this iMac yet. But there’s a chance someone else may see this thread and post their solution, so I’m good with that.

@Sleepy, I think this would help you. For example, to select word “Hello” and replace it with “Hello World”, you pass data as stdin in a Run Shell Script Automator action, select Output replaces selected text and paste this code. Variable stdin value is the text you selected.

stdin=$(cat)
echo "$stdin World"

Interesting. Okay, I had to google that because I had never seen $() before. From what I've read, it's the same thing as backquotes to execute a command. I must be old-school becauseit used to be backquotes. So I think this is assigning the standard input to a variable. And then the second command modified the variable (just by adding another word to it) and then the automator action seems to be replacing the original selected test. Okay. it seems to work! Here's an example that is clearer to me because "stdin" was confusing me as I thought it was a reserved name:

In this example I gave the variable a more typical variable name, and I did a more powerful action for demonstration purposes, which is to insert line numbers before each line.

Wow, that's cool. This is good, but my original question was whether I could get a KM macro to be called to do the processing. I'm still not sure about that. I'm trying to modify your idea to make it work with a KM macro, here's my best attempt:

The problem is this doesn't work because I can't figure out how to get a KM macro to accept input from STDIN. If I could then maybe this would work. It's possible I'm a complete moron, but I can't see how to get a KM macro to work in a Run Applescript action in Automator and accept the STDIN. Please tell me I'm a moron and show me how to do that.

Your AppleScript needs to include the input parameter, as I believe that's where the output from STDIN in the preceding shell script action is contained:

tell application "Keyboard Maestro Engine"
do script "TestSort" with parameter input
end tell

And the corresponding KM macro needs to use the %TriggerValue% token accordingly, like I showed you before (though you may not want to have it paste the results if you want to return the text to Automator):

04 PM

By adding "with parameter input" to the Run AppleScript action and by creating the TestSort macro thusly:

I get this error: (when selecting 5 lines of text.)

I know the routine TestSort macro I wrote isn't "sorting", but it is rather rev'ving, however that's simply for illustration purposes, because sorting a list of sequential numbers probably won't do much.

We are getting close. Any improvements?

The issue you're running into is that input contains an AppleScript list, which KM can't interpret as plain text as-is. Try changing the AppleScript in the Run AppleScript action to this:

on run {input}
	
set text item delimiters to linefeed
set input to input as text

tell application "Keyboard Maestro Engine"
	do script "TestSort" with parameter input
end tell

end run

When I do that, I get this result with rev on the same sample data as you:

fed 1
ihg 2
luj 3
dcb 4
gfe 5

Your words make some sense, and I'm very glad you get the correct/intended output, but when I copied your AppleScript into my AppleScript action I now get nothing at all. Running the macro does absolutely nothing. Here's a screenshot:

Yes there is an end run statement at the bottom of the Run Applescript action.

When I select text now, nothing is replaced. Prior to this change, I was getting text replaced, but the results only matched the first Automator action, as if the second one didn't run. Now neither is running.

Can you see any difference between your actions and mine? I can't.